PDF/A Conversion and Validation
PDF/A (ISO 19005) is the archival profile of PDF: a file that carries everything needed to
render it, forever, with no dependence on fonts installed somewhere, scripts that run
somewhere, or color defined by somebody's device. Two endpoints implement the whole
discipline: POST /lmkit/v1/pdf-to-pdfa converts a document by repairing it toward
conformance, and POST /lmkit/v1/document-validation audits any PDF against the standard's
rule catalog and reports evidence, not opinion. This page is the complete treatment of both;
the surrounding PDF workshop lives in The PDF Toolbox.
1What the standard actually demands#
Everything PDF/A requires follows from one idea: the file must be self-contained and deterministic. Concretely, a conforming document has every font embedded, device color anchored by an ICC output intent, XMP metadata identifying its own conformance level, and none of the machinery whose behavior depends on the outside world: no encryption, no JavaScript or launch actions, no XFA forms, no references to external content, no LZW-compressed streams, and (in the strictest level) no transparency. A "PDF/A" file that violates any of this is an ordinary PDF wearing a claim, which is why validation exists as its own endpoint.
2Choosing a conformance level#
| Level | Base | Allows | Choose it when |
|---|---|---|---|
PdfA1b |
PDF 1.4 | The strictest set: no transparency, no layers, no JPEG2000 | A regulation or counterparty names PDF/A-1 explicitly |
PdfA2b |
PDF 1.7 | Transparency, layers, JPEG2000 | The default, and the right answer for most archives: modern documents convert without flattening away their appearance |
PdfA3b |
PDF 1.7 | Everything in 2b, plus arbitrary embedded attachments | Hybrid records where a machine-readable payload rides inside the human-readable document, the pattern electronic-invoicing standards build on |
All three are level B ("basic": visual reproducibility). When nothing external forces a
choice, use the default PdfA2b.
3Converting: the request#
| Field | Default | Meaning |
|---|---|---|
input, input_format |
base64 | The source PDF, as base64 or a file id. |
level |
PdfA2b |
The targeted conformance level. |
fallback |
Rasterize |
What happens to content that no repair can make conforming (section 5). |
password |
none | Opens an encrypted source. The output is always unencrypted; PDF/A prohibits encryption. |
raster_dpi |
200 | Rendering resolution for fallback pages (72 to 600). |
raster_jpeg_quality |
92 | JPEG quality for fallback page images (1 to 100). |
include_text_layer |
true | Overlays the source text invisibly on fallback pages, so they stay searchable. |
4What conversion does: repair first, always#
The converter is built on a repair-first contract: every possible fix is applied before any fallback is considered, and the response itemizes both what was found and what was done.
features_detected names the conformance-relevant traits of the SOURCE:
| Value | The source contained |
|---|---|
Encrypted |
Encryption (removed; PDF/A prohibits it) |
UnembeddedFont |
Fonts referenced but not embedded |
DeviceCmyk |
Device-dependent CMYK color with no anchoring intent |
Lzw |
LZW-compressed streams (forbidden) |
Jpx |
JPEG2000 imagery (constrained; forbidden entirely in A-1) |
Transparency |
Transparency groups (forbidden in A-1) |
EmbeddedFiles |
File attachments (forbidden below A-3) |
Javascript, Xfa |
Script actions, XFA forms (forbidden) |
AnnotationWithoutAppearance |
Annotations missing the appearance streams PDF/A requires |
fixes_applied names the repairs, and the catalog is deep because real documents are:
scripts, launch actions, and XFA are stripped (DocumentJavascript, OpenAction,
DocumentAdditionalActions, PageAdditionalActions, OutlineActions, Xfa); annotations
gain generated appearance streams or lose forbidden flags and actions (AnnotationFlags,
AnnotationActions, AnnotationsRemoved, NeedAppearances); fonts are embedded with their
declared metrics reconciled against the actual glyph programs (FontsEmbedded), and text
that maps to no real glyph is cleaned up without shifting layout (NotdefTextStripped);
LZW streams are re-encoded (LzwReencoded); device CMYK gains an embedded ICC profile and
inconsistent colorant definitions are unified (DefaultCmykInstalled, ColorantsUnified);
nonconforming JPEG2000 codestreams are re-encoded (JpxRecoded); attachments are removed or,
for A-3, given the relationship metadata the level requires (EmbeddedFiles,
AttachmentRelationship); and the document's structure, graphics state, image dictionaries,
and version metadata are normalized (ExtGState, ImageKeys, CatalogVersion, MiscKeys).
On top of the repairs, the converter synthesizes what conformance requires: XMP metadata
with the PDF/A identification (mirrored from the document's existing properties) and an sRGB
output intent.
Two consequences worth stating: the output is always unencrypted, and a digital signature cannot survive conversion, because rewriting the file invalidates the signed digest; convert first, sign after.
5The raster fallback: guaranteed conformance, page by page#
Some content cannot be repaired into conformance (a font program too broken to embed, an
exotic construct with no conforming equivalent). The fallback field decides what happens
to it, and only after every repair has been tried:
Rasterize(default): only the residual pages are rebuilt from their own rendered image, atraster_dpi, with an invisible text layer carrying the source text so search and extraction keep working. The rest of the document keeps its original, repaired content. This is the maximum-success strategy: the output always conforms.ReportOnly: the original content is kept and the remaining problems are listed inunresolved_violations;conformsis false. Choose it when fidelity of the original content streams outranks the conformance guarantee.Fail: the conversion is rejected instead. Choose it when a rasterized page is not an acceptable archival artifact and a human should see the document instead.
When the fallback fires, used_raster_fallback is true and raster_triggers names the
violations that forced it, so the decision is inspectable afterward.
6The response is a work report with its own audit#
| Field | Meaning |
|---|---|
file_id |
The converted document, stored server-side, ready to chain or download. |
level, page_count |
What was targeted, and the output's size. |
conforms |
Whether the output meets the target. False only under ReportOnly with violations remaining. |
features_detected, fixes_applied |
The source's traits and the repairs applied (section 4). |
used_raster_fallback, raster_triggers |
Whether and why any page was rebuilt from its render. |
encryption_removed |
Whether the source was encrypted. |
unresolved_violations |
What remains, under ReportOnly only. |
validation |
A full, independent validation report over the produced bytes (section 7). |
That last field is the load-bearing one: the converter does not grade its own work. The
stored output is re-parsed and evaluated against the same rule catalog the standalone
validator runs, so validation.verdict is a checked fact, and the conversion response is
already the evidence pair an archival gate wants: what was done, and proof it worked.
7Validating: the independent auditor#
POST /lmkit/v1/document-validation evaluates ANY PDF, from any source, against the PDF/A
rule catalog. The request is the document plus two knobs: profile (pdfa today; the field
is the extensible axis for future document standards) and flavor, which defaults to
auto: the level is read from the document's own declared identification, and a document
declaring nothing is validated as 2b. A password opens protected sources, but an encrypted
document still fails encryption.present: openable is not conforming.
The report is built to be stored and cited:
verdict:compliant,non_compliant, orundetermined. Undetermined means the document could not be judged (unreadable bytes, a missing password, a declared level outside coverage) and must never be read as a failure.flavor_declaredvsflavor_validated: the claim versus what was actually checked. A declaration is a claim, not a fact; this pair is what catches the ordinary PDF wearing a PDF/A label.rules_evaluatedandrules_failed: the pass's own coverage, stated, so a stored verdict remains honest about what it meant when a future validator evaluates more.findings: one entry per failed rule, each with a STABLE identifier and a human-readable statement of the requirement. Identifiers never change once shipped, so monitoring, deduplication, and trend dashboards can key on them. The catalog spans the full width of the standard:fonts.*(embedding, encodings, glyph coverage, width consistency),color.*(device color, ICC validity, output intents, colorants),metadata.*(XMP presence, well-formedness, PDF/A identification),encryption.*,compression.*,transparency.*,action.*andannotation.*,files.*,structure.*andlimits.*(syntax and implementation limits),graphics.*,images.*,xobjects.*,form.*,optional-content.*, andprepress.*.validatorandreport_schema: the versioned identity of the engine and the report shape, so evidence stored today stays attributable and parseable years from now.
8The archival workflows#
- The archival gate: convert, then store three things together: the artifact, the conversion report, and the validation report. The document pipeline chains them by file id in two calls, and the conversion's embedded audit means the second call is already included.
- Inbound acceptance: when a counterparty delivers "PDF/A", validate before accepting.
flavor_declaredversusflavor_validatedplus the findings list turns a dispute about conformance into a rule-by-rule document. - Regression checks: any transformation that touches an archival file (a merge, a redaction, a stamp) can un-conform it; re-validate after, and the stable rule ids tell you exactly what the operation broke.
- The periodic audit: archives outlive the software that built them. Re-validating the
store on a schedule, with verdicts keyed by
validatorversion, is cheap insurance against the day a regulator asks. - Scan to archive: OCR overlay for searchability, convert to PDF/A, and the validation report closes the loop; the whole digitization pipeline is one chain of calls. As the terminal stage of IDP, this is what "deliver" means for records that must outlive their systems.
- From an agent, over MCP: the same pair ships as tools (
pdf_to_pdfaandpdf_validate_pdfa, both in the default set) plus a ready-made command, "Archive a document as PDF/A", that converts and then proves the output independently. Connecting a client is The MCP Server.
9Stated plainly#
- Conversion is repair-first across the standard's whole surface (fonts, color, compression, scripts, annotations, metadata), and the response itemizes every finding and fix.
- The raster fallback trades per-page content streams for a conformance guarantee, page by page, searchable, and only where repair was impossible; two other policies exist when that trade is wrong for you.
- Every conversion ships with an independent validation of its own output, and the standalone validator audits anyone's conformance claim with stable rule ids, declared versus validated levels, and a report built for storage.