PDFPipe

Archiving and long-term storage / PDF/A-1b

What PDF/A-1b requires, and how far this API gets you

The oldest and strictest archiving profile: a PDF 1.4 file with everything it needs to render sealed inside it, and nothing in it that a future reader might not understand.

Where this API stands

This API does part of what the standard asks for, and the paragraph below is the whole of it rather than a summary of it. The `pdf_a` option targets exactly this and gets part of the way. What it does is write an XMP packet declaring pdfaid:part 1 and pdfaid:conformance B and set it as the document catalogue's metadata entry. It changes nothing else, and the API says so in the response: every render with the option on comes back carrying the warning that the marking is best-effort and that full conformance requires tagged structure and an embedded ICC profile. So the file claims to be PDF/A-1b and a validator will check that claim against the actual bytes. What decides whether it passes is your source: a document whose CSS uses rgba(), opacity or box-shadow contains transparency, and PDF/A-1 forbids transparency outright, so that one styling habit fails the file before colour is even considered.

What the standard requires

The requirements as a checker enforces them, rather than as a procurement document paraphrases them. A file satisfies all of these or it satisfies none of them.

  • Every font used anywhere in the document is embedded, including the fourteen standard faces that older readers would otherwise substitute from the system.
  • No encryption of any kind. A password-protected file is not PDF/A and no validator will accept one.
  • Colour is either device independent or given meaning by an output intent carrying an embedded ICC profile, so a device colour value means the same thing in thirty years as it does now.
  • No transparency at all, which in practice means no opacity below 1, no rgba() colour, no box shadow and no blend mode anywhere in the source.
  • An XMP packet in the document catalogue declaring pdfaid:part 1 and pdfaid:conformance B, with any values it repeats from the document information dictionary agreeing exactly.
  • No JavaScript, no launch actions, no embedded files, no optional content groups and no references to external streams.

Who asks for this

Public sector procurement, court filing systems, and internal records retention policies written by somebody who read the ISO number and stopped. It is usually specified as a submission format: the portal rejects the upload rather than a person reviewing it, so there is no arguing about substantial compliance. The requirement almost never arrives with a conformance level attached, which is its own problem and the reason the conformance levels page exists.

What it looks like in a file

The concrete form of the thing being described, so you can recognise it in a document you have been handed rather than only in a specification.

xml
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/">
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description rdf:about=""
        xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/">
      <pdfaid:part>1</pdfaid:part>
      <pdfaid:conformance>B</pdfaid:conformance>
    </rdf:Description>
  </rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>

<!-- This is the whole of what options.pdf_a adds: the packet above, registered
     as a metadata stream and set as the catalogue's /Metadata entry. The fonts,
     the colour and the absence of transparency are still your side of the line. -->

What to do about it

Two honest paths. If you control the markup, remove the transparency (solid colours instead of rgba, borders instead of shadows), embed your fonts through @font-face with real files rather than naming a system family, and then decide whether the missing output intent is something your validator actually enforces, because most do. If you need a file that passes cleanly, render first and convert second: Ghostscript with -dPDFA=1 and a PDFA_def.ps that names an ICC profile will rewrite the colour and attach the output intent, and callas pdfToolbox or Acrobat's preflight will do the same with a report. Convert after rendering, never instead of it.

How to check a file rather than assume

veraPDF is the reference implementation and it is free. Run it with the flavour you claim and it reports each failed check against the clause of the specification it came from, so you get an actionable list rather than a yes or no. Do not treat a file as conformant because a reader opened it without complaining: readers are permissive by design, and the identification metadata is a claim, not a certificate.

The mistake people make here

Believing the metadata. Setting pdfaid:part and pdfaid:conformance makes a file say it is PDF/A-1b, and a file that says so and is not is worse than a plain PDF, because it will be accepted by anything that trusts the claim and rejected by the one system that checks. The API's own warning says this in as many words. Read the warning array in the response rather than ignoring it.

Frequently asked

Does this API produce PDF/A-1b?

Partly, and the page says how far. The `pdf_a` option targets exactly this and gets part of the way. What it does is write an XMP packet declaring pdfaid:part 1 and pdfaid:conformance B and set it as the document catalogue's metadata entry. It changes nothing else, and the API says so in the response: every render with the option on comes back carrying the warning that the marking is best-effort and that full conformance requires tagged structure and an embedded ICC profile. So the file claims to be PDF/A-1b and a validator will check that claim against the actual bytes. What decides whether it passes is your source: a document whose CSS uses rgba(), opacity or box-shadow contains transparency, and PDF/A-1 forbids transparency outright, so that one styling habit fails the file before colour is even considered.

Can I turn on the pdf_a option and be done?

No. The option writes an XMP packet declaring PDF/A-1b into the document catalogue, and the render response comes back carrying a warning that says in as many words that this is best-effort and that full conformance requires tagged structure and an embedded ICC profile. It is a claim written into the file, not a certificate earned by it, and a validator checks the claim against the bytes. Read the warning array in the response rather than taking the absence of an error as a pass.

Should I convert before rendering or after?

After, always. A conformance converter rewrites colour, embeds profiles, sets boxes and stamps metadata on a finished PDF. Trying to satisfy a conformance target from the source side means guessing at what the converter would have done, and the guesses that go wrong are expensive: flattening transparency you did not need to flatten changes what the page looks like.

Standards this one is confused with

The neighbours that matter are the ones people mistake for this, not the ones that sort next to it.

Conformance is decided after a file exists. Render the document, then check it, then convert only what the checker actually flags.