DEV Community

Cover image for PDF/A Has Eight Conformance Levels: What 1b, 2b, and 3b Actually Mean for What You're Archiving
PDF4me
PDF4me

Posted on

PDF/A Has Eight Conformance Levels: What 1b, 2b, and 3b Actually Mean for What You're Archiving

Ask a developer to "convert this to PDF/A" and watch them pick the first option in the dropdown. Most of the time that's PDF/A-1b, and most of the time it works. But PDF4me's Create PDF/A endpoint doesn't expose one archival format. It exposes eight, grouped into three families that answer three different questions: does it look right, can a screen reader use it, and can it carry other files inside it? Picking the wrong one doesn't usually throw an error. It just means the document you archived for thirty years doesn't do what compliance actually needed it to do.

Three families, not eight random options

The eight compliance levels aren't eight unrelated formats. They're three conformance families (1, 2, 3) crossed with three conformance tiers (b, u, a), and understanding the tier is what actually matters day to day.

The "b" family: PDF/A-1b, PDF/A-2b, PDF/A-3b. This is basic conformance: reliable reproduction of the document's visual appearance, nothing more. If a human opens the file in twenty years, it looks exactly like it does today. That's the whole promise, and for most archival workflows it's the only promise you need.

The "a" family: PDF/A-1a, PDF/A-2a, PDF/A-3a. Accessible conformance. Everything in the "b" tier, plus document structure, tagged text spans, tagged images, and language specification, the metadata a screen reader needs to actually parse the document instead of just displaying it. If the archived file has to meet accessibility requirements, "b" conformance doesn't cover you.

The "u" family: PDF/A-2u, PDF/A-3u. Basic conformance with every text string mapped to Unicode. There's no PDF/A-1u; Unicode mapping was introduced with the Part 2 standard. Pick "u" when the archive needs reliable text extraction and cross-platform character support (multilingual invoices, non-Latin scripts) but doesn't need full accessibility tagging.

That's the framework the Create PDF/A REST API exposes through one required compliance parameter, accepting values like PdfA1b, PdfA2u, or PdfA3a. Same logic, same eight values, whether you're calling the endpoint directly or driving it from an integration platform.

Calling it directly: a minimal example

The REST endpoint is a single POST against https://api.pdf4me.com/api/v2/PdfA, authenticated with your API key in the Authorization header. The request body is small: base64 file content, a filename, the compliance level, and the two upgrade/downgrade flags covered below.

import base64
import requests

with open("source.pdf", "rb") as f:
    doc_content = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "docContent": doc_content,
    "docName": "output.pdf",
    "compliance": "PdfA2b",
    "allowUpgrade": True,
    "allowDowngrade": True
}

headers = {
    "Content-Type": "application/json",
    "Authorization": "YOUR_API_KEY"
}

response = requests.post(
    "https://api.pdf4me.com/api/v2/PdfA",
    json=payload,
    headers=headers
)

with open("archived.pdf", "wb") as out:
    out.write(response.content)
Enter fullscreen mode Exit fullscreen mode

Swap compliance for any of the eight values (PdfA1a, PdfA1b, PdfA2a, PdfA2b, PdfA2u, PdfA3a, PdfA3b, PdfA3u) and the rest of the call stays identical. Field names, the endpoint path, and the base URL are all confirmed on the Create PDF/A reference page and the Connect to the PDF4me V2 API guide; get your own key from the Getting Started with the PDF4me API Portal page before running this. Want to try a request before writing any code at all? The Create PDF/A API Tester runs the same call from the browser and shows the raw response, including the 202-plus-polling flow triggered by setting IsAsync to true.

What 1, 2, and 3 actually change

The number isn't a version bump. Each part of the standard unlocks something the previous part couldn't do.

PDF/A-1 targets PDF up to version 1.4. It's the oldest, strictest, most universally-supported part of the standard, and it's still the right default when the only requirement is "this has to open correctly forever."

PDF/A-2 builds on PDF 1.7 and adds transparency support, image compression, embedded fonts, and provisions for digital signatures. It also allows embedding other PDF/A files, useful for archiving a set of related documents inside one container. For most modern archival pipelines, PDF/A-2b is the practical default: it accepts contemporary PDF features without the strict limitations of Part 1.

PDF/A-3 keeps everything Part 2 does and adds one capability neither Part 1 nor Part 2 has: embedding arbitrary external files (XML, CSV, CAD drawings, Word documents) inside the archival PDF itself. This isn't a minor feature. It's the entire mechanism behind hybrid e-invoicing formats like ZUGFeRD and Factur-X, where a human-readable PDF and a machine-readable XML have to travel as one file. If your workflow needs to bundle source data inside the archive, PDF/A-1 and PDF/A-2 simply can't do it. Only the PDF/A-3 family can.

So the practical decision tree looks like this: need embedded files? You're in PDF/A-3, no other option qualifies. Need screen-reader accessibility? Take the "a" tier of whichever part you land on. Otherwise, PDF/A-2b covers nearly everything else, with PDF/A-1b as the fallback when maximum compatibility with older PDF readers matters more than modern features.

Two parameters that keep the workflow from breaking

Requesting a specific compliance level assumes the source PDF can actually meet it, and not every source file can. That's what allowUpgrade and allowDowngrade are for, and every platform surfaces them slightly differently.

allowDowngrade is the one that matters most in production. If the source PDF can't satisfy the requested level (transparency effects that block PDF/A-1b, for instance), the API falls back to a compatible lower level instead of failing the request outright. On bulk archival runs, that's the difference between one bad document halting a batch job and the batch job finishing with a note instead. allowUpgrade does the reverse: it lets PDF4me promote the output to a higher compliance level when the source document already qualifies.

Both are visible as Advanced Options in the Create PDF/A node in n8n, as explicit Yes/No fields in the Create PDF/A module in Make (Make's own guidance calls Allow Downgrade = Yes "success insurance" on bulk runs), and as boolean parameters in the Create PDF/A action in Power Automate. Zapier's Create PDF/A action exposes the same eight compliance options through its own dropdown, mapped from a file field that accepts either an uploaded file or a URL.

The same logic, five different surfaces

What's worth noticing across all five surfaces (REST, Make, Power Automate, Zapier, n8n) is that the compliance framework doesn't change shape depending on where you call it from. Every platform exposes the same eight values, grouped the same three ways, with the same two flexibility parameters attached. What changes is only how the source file gets in and the output gets out: n8n accepts binary data, Base64, or a URL and returns the archival PDF as a binary output property; Make maps File Name and Document from a prior module and hands back a buffer you route into Dropbox, Google Drive, or SharePoint; Power Automate wires directly into a Microsoft 365 flow; Zapier returns a URL to the converted file rather than raw binary, fitting its trigger-based automation model.

That consistency is worth relying on. A team standardizing on PDF/A-2b for its default archive doesn't need a different mental model for the developer who calls the REST endpoint directly versus the ops person who builds the same conversion into a Zapier workflow. It's the same compliance value either way, just wrapped in a different platform's fields.

Converting isn't the same as verifying

Creating a PDF/A file and confirming it actually conforms are two different operations, and treating "the conversion succeeded" as proof of compliance is a mistake worth naming explicitly. PDF4me separates the two on purpose: Validate PDF/A in Make, Validate PDF/A in Power Automate, and Validate PDFA in Zapier each check ISO 19005 conformance against a file and return the specific conformance level detected, not just a pass or fail flag. For an archive gate sitting between "document generated" and "document stored," that's the module that actually belongs in the pipeline: convert with Create PDF/A, confirm with Validate PDF/A, then store. Skipping the validation step means finding out a document doesn't actually conform the day someone needs to open it, which for an archival system is usually the worst possible day to find out.

Picking a level without guessing

If there's one habit worth taking from all of this, it's to stop treating "PDF/A" as a single checkbox. Before calling Create PDF/A, ask three questions in order: does this need to embed another file inside it (only PDF/A-3 can), does it need to meet accessibility requirements (only the "a" tier can), and does it need guaranteed cross-platform text extraction beyond that (the "u" tier, or "a" if accessibility applies too). If the answer to all three is no, PDF/A-2b is almost always the right default, PDF/A-1b if you need the widest possible reader compatibility. Set allowDowngrade on anything running at scale, and put a Validate PDF/A check between the conversion and the archive so "converted" and "compliant" don't quietly become the same claim.

Website: pdf4me.com
Documentation: docs.pdf4me.com
Developer portal: dev.pdf4me.com

Top comments (0)