Make a PDF conform
Repairs a PDF until it conforms to PDF/A, PDF/UA or Factur-X, or to PDF/A and PDF/UA together, and reports what it couldn't fix.
Remediate a PDF
curl \
--request POST http://localhost:3000/forms/pdf/remediate \
--form files=@report.pdf \
--form profile=PDF/A-2b \
-o report.pdf
HTTP/1.1 200 OK
Content-Type: application/pdf
Gotenberg-Remediation-Residual: 0
Gotenberg-Remediation-Rolled-Back: 0
Two headers report how it went:
Gotenberg-Remediation-Residualcounts the violations left.0means the PDF conforms.Gotenberg-Remediation-Rolled-Backcounts the fixes Gotenberg undid because they lost pages, text or images.aggressive: trueallows more fixes that may change how the pages look, for better compliance, under the same rollback. It deletes every embedded file on PDF/A-1, which forbids them, and the ones that aren't PDF/A themselves on PDF/A-2 and PDF/A-4, which forbid those.
Gotenberg answers 200 even when violations remain: check Gotenberg-Remediation-Residual, and list what's left with /forms/pdf/validate. With several PDFs, the headers sum their counts.
Pick a PDF/A level
profile takes PDF/A-1a, PDF/A-1b, PDF/A-2a, PDF/A-2b, PDF/A-2u, PDF/A-3a, PDF/A-3b, PDF/A-3u, PDF/A-4, PDF/A-4e or PDF/A-4f.
- The letter sets how much the PDF keeps:
bits look,uits text as Unicode too,aits structure too, through tags. - The number sets the base: PDF/A-1 builds on PDF 1.4, PDF/A-2 adds transparency and layers, PDF/A-3 accepts embedded files of any type, and PDF/A-4 builds on PDF 2.0.
PDF/A-4f needs an embedded file: attach one first, or the residual stays above 0.
Pick the level your archive or portal asks for. Without one, PDF/A-4 is the latest version.
Make it PDF/UA
PDF/UA-1 and PDF/UA-2 make the PDF accessible, and tag it if it isn't:
curl \
--request POST http://localhost:3000/forms/pdf/remediate \
--form files=@report.pdf \
--form profile=PDF/UA-1 \
--form language=en-US \
-o report.pdf
HTTP/1.1 200 OK
Content-Type: application/pdf
Gotenberg-Remediation-Residual: 0
Gotenberg-Remediation-Rolled-Back: 0
languagesets the document's language,enby default. Screen readers pick their voice from it.figureAltTextgives a description to the figures that lack one. Better, write thealttext in your HTML.
Make it PDF/A and PDF/UA
A PDF can be archival and accessible at once. Give profile a PDF/A profile and a PDF/UA one, as a JSON array or as the field repeated:
curl \
--request POST http://localhost:3000/forms/pdf/remediate \
--form files=@report.pdf \
--form 'profile=[
"PDF/A-2b",
"PDF/UA-1"
]' \
--form language=en-US \
-o report.pdf
HTTP/1.1 200 OK
Content-Type: application/pdf
Gotenberg-Remediation-Residual: 0
Gotenberg-Remediation-Rolled-Back: 0
In a list of stages, the array goes in the stage: {"op": "remediate", "profile": ["PDF/A-2b", "PDF/UA-1"]}. The residual counts the violations of both profiles, so 0 means the PDF conforms to each.
The PDF version sets the pairs. PDF/A-1, PDF/A-2, PDF/A-3 and Factur-X pair with PDF/UA-1, and PDF/A-4 with PDF/UA-2. Any other pair answers 400 and lists these.
Make it a Factur-X
Factur-X embeds the invoice's XML and makes the PDF a PDF/A-3 e-invoice, the format Germany also publishes as ZUGFeRD:
curl \
--request POST http://localhost:3000/forms/pdf/remediate \
--form files=@report.pdf \
--form files=@invoice.xml \
--form profile=Factur-X \
--form xml=invoice.xml \
--form 'level=EN 16931' \
-o invoice.pdf
The XML is a Cross Industry Invoice (CII), the syntax Factur-X uses. It declares its level, and level names the same one: another level, or an XML that isn't a CII invoice, answers 400 before anything changes. An XRECHNUNG invoice also passes as BASIC, EN 16931 or EXTENDED. EN 16931 carries everything the European standard for e-invoices requires; MINIMUM and BASIC WL carry less, so check what your recipient accepts.
Stage 'remediate' failed on 'report.pdf': factur-x conformance level does not match the invoice XML: level "MINIMUM" given, but the invoice XML declares "EN 16931" (guideline ID "urn:cen.eu:en16931:2017")
The residual counts the fatal violations the invoice leaves, the ones /forms/pdf/validate reports: 0 means the invoice validates.
Without xml, the stage repairs a Factur-X invoice the PDF already carries. The e-invoice recipe makes one from HTML.
Remediate last
A list takes one remediate, so a pair goes in one stage. It comes after the stages that change the content: only encrypt, optimize, sign, timestamp and render may follow it. A PDF/A or Factur-X can't be encrypted.
In a list of stages
The stage also runs in a list on /forms/pdf/pipe, and on the PDFs a Chromium or LibreOffice conversion makes, in its stages field:
curl \
--request POST http://localhost:3000/forms/pdf/pipe \
--form files=@report.pdf \
--form 'stages=[
{ "op": "remediate", "profile": "PDF/A-4" }
]' \
-o report.pdf
HTTP/1.1 200 OK
Content-Type: application/pdf
Gotenberg-Remediation-Residual: 0
Gotenberg-Remediation-Rolled-Back: 0