# Standards and warnings

Ask for an archival or an accessible PDF, and read which standards the file meets and why one was left out.

Page: https://legivel.com/docs/standards

By default the PDF is the smallest PDF 2.0 file and claims no standard. You state what the file is for, in `features`. The converter writes every standard the document can meet, and the answer tells which standards the file meets and why one was left out. A render does not fail for a standard unless you send `standards: "strict"`.

POST /v1/render

```json
{ "markdown": "---\ntitle: Annual report\n---\n# Annual report", "language": "en-GB",
  "features": { "archive": true, "accessible": true } }
```

## Intents

All intents are off by default. The MCP server takes the same keys, and `archive`, `accessible` and `mathml` also work in the document's front matter.

| Feature | Effect |
| --- | --- |
| `archive: true` | Archive rules: no Info dictionary, an output intent, every font and file embedded. The PDF claims PDF/A-4, or PDF/A-4f when it carries attached files. |
| `accessible: true` | Tags, the title in the metadata and the document language. The PDF claims PDF/UA-2 when the document names its language. |
| `mathml: true` | One MathML file for each formula. This turns tagging on, because the files are attached to the formula tags. accessible adds the files by itself when the document has formulas, because PDF/UA-2 requires MathML for formulas. |
| `embed_source: true` | The Markdown source as an attached file. |
| `standards: "strict"` | For archive pipelines: refuse the render with 422 when the PDF cannot meet a requested standard. The default is "best_effort". |

You do not name PDF/A-4 or PDF/A-4f: the converter selects the level from the content. PDF/A-1, PDF/A-2, PDF/A-3 and PDF/A-4e are not available.

## What each request claims

| Request | Written | Standards claimed |
| --- | --- | --- |
| nothing | PDF 2.0, untagged | none |
| archive | PDF 2.0, archive rules | PDF/A-4 |
| archive + mathml or embed_source | the same, with the attached files listed | PDF/A-4f |
| accessible, language set | PDF 2.0, tagged | PDF/UA-2 |
| accessible, no language | PDF 2.0, tagged | none (warning language_missing) |
| archive + accessible, language set | tagged, archive rules | PDF/A-4 (or 4f) and PDF/UA-2 |
| mathml alone | tagged, MathML files | none (warning tagging_enabled) |
| accessible, document with formulas | tagged, MathML files | PDF/UA-2 (warning mathml_enabled); with archive, PDF/A-4f |
| accessible + mathml: false, formulas | tagged, no MathML files | none (warning mathml_required) |

## How the answer reports it

- `X-Legivel-Standards`: the standards the file meets, such as `PDF/A-4f, PDF/UA-2`. Absent when the file claims none.
- `X-Legivel-Warnings`: the warning codes, such as `language_missing, alt_text_missing`. Absent when there is none. The codes are stable.
- The `json` delivery and the `upload` receipt carry `standards` and `warnings`. Each warning has a `code`, a `message` and, where the converter counts, `detail.count`.
- The MCP result names the standards and gives each warning as a sentence.

The file itself names only the standards it meets.

## Warnings

| Code | When | Standards kept | What to do |
| --- | --- | --- | --- |
| `language_missing` | accessible without a document language. The file is tagged; no language is guessed. | PDF/A; not PDF/UA-2 | Send language, or set language in the front matter. |
| `title_missing` | accessible, and the PDF has no title. Every PDF gets one: without a front matter title it takes the file name, else legivel.com document and the render time. | PDF/A; not PDF/UA-2 | Set title in the front matter. |
| `mathml_required` | accessible with mathml: false and formulas in the document. | PDF/A; not PDF/UA-2 | Remove mathml: false. |
| `glyph_missing` | archive or accessible, and no font can draw a character. | none | Remove these characters or replace them. |
| `unicode_invalid` | archive or accessible, and text maps to U+0000, U+FEFF or U+FFFE. Control characters and a leading byte order mark are removed before this check. | none | Remove these characters. |
| `private_use_text` | accessible, and the text has characters from the Unicode Private Use Area, which have no standard meaning. | PDF/A; not PDF/UA-2 | Replace them with standard Unicode characters. |
| `alt_text_missing` | accessible, and an image has no alternative text. The image is marked as decoration. | all | Give each image that carries content an alternative text. |
| `tagging_enabled` | mathml without accessible. Tagging is turned on. | all | Nothing to do. |
| `mathml_enabled` | accessible, and the document has formulas. The MathML files are added. | all; archive becomes 4f | Nothing to do. |
| `plan_raster` | archive, accessible or mathml on the watermarked download, which is a picture of each page. | none | Download the full PDF. |
| `engine_unsupported` | archive, accessible or mathml, and this converter version does not write standards yet. | none | Try again after the next release. |

## Strict mode

With `standards: "strict"`, each warning that leaves a requested standard out refuses the render with 422 and the same code: `language_missing`, `title_missing`, `mathml_required`, `glyph_missing`, `unicode_invalid`, `private_use_text`, `plan_raster` and `engine_unsupported`. The error body lists every warning of the render in `warnings`, and the document is returned to your period. See [Errors and quota](https://legivel.com/docs/errors).
