Gotenberg Documentation

website·Indexed 35 days ago

https://gotenberg.dev/docs

A Docker-based API for converting documents to PDF and manipulating PDF files. It provides modules for Headless Chromium and LibreOffice to convert HTML, Markdown, and various document formats to PDF, as well as tools to merge, split, rotate, watermark, encrypt, and optimize PDFs.

Tokens
49.9K
Snippets
271
Records
344
Agent score
71%

What's inside Gotenberg

  1. Overview of Gotenberg PDF API

    Gotenberg is a Docker-based API that converts documents to PDF and provides PDF manipulation capabilities. It handles the underlying dependencies for Chromium, LibreOffice, and fonts, allowing users to send files via multipart/form-data to receive a PDF. Supported operations include conversion, merging, splitting, encrypting, watermarking, metadata management, and Factur-X / ZUGFeRD e-invoicing.
  2. Understand Chromium module behavior and scaling

    The Chromium module converts HTML documents to PDF. It operates in a stateful mode where a single browser manages conversions, supporting up to 6 parallel operations. Under heavy load, requests are queued; if the queue reaches maximum capacity, requests are terminated prematurely. To maintain performance during high traffic, it is recommended to increase the number of Gotenberg instances rather than relying on a single instance's queue.
  3. Understand Gotenberg's outbound HTTP request posture

    Gotenberg makes outbound HTTP calls in four primary areas: Chromium navigations/sub-resources, Webhook callbacks, downloadFrom fetches, and LibreOffice fetches for document references. By default, Gotenberg is permissive, assuming it runs within a trusted network behind an API gateway. All outbound requests pass through a pipeline consisting of allow/deny regex filters, IP-class checks, and a DNS-rebind pinning proxy.
  4. Merge multiple PDF files into a single PDF

    Use the /forms/pdfengines/merge endpoint to combine multiple PDF files. Files are merged in alphanumeric order (numbers first, then alphabetical). Since version 8.37.0, files sharing the same filename are all preserved and merged in the order they were uploaded.
    curl \
    --request POST http://localhost:3000/forms/pdfengines/merge \
    --form files=@/path/to/1_pdf.pdf \
    --form files=@/path/to/2_pdf.pdf \
    --form files=@/path/to/3_pdf.pdf \
    -o my.pdf
  5. Generate accessible or archival PDFs (PDF/A, PDF/UA)

    Gotenberg provides two ways to handle accessibility and archival standards:

    1. Native Chromium Accessibility: Use generateTaggedPdf=true to embed a logical structure tree (headings, paragraphs). This is faster and preferred for screen readers.
    2. Post-Processing (LibreOffice): Use pdfa (PDF/A-1b, PDF/A-2b, PDF/A-3b) or pdfua=true. This is a slower second pass.

    Caveats:

    • PDF/A and encryption are mutually exclusive (returns 400 Bad Request).
    • PDF/A-1b and PDF/A-2b do not support file attachments; use PDF/A-3b for both.
    • LibreOffice may rasterize table cells with background colors, impacting accessibility.
    # Native Chromium Accessibility
    curl \
    --request POST http://localhost:3000/forms/chromium/convert/html \
    --form files=@/path/to/index.html \
    --form generateTaggedPdf=true \
    -o my.pdf
    
    # Post-Processing PDF/A and PDF/UA
    curl \
    --request POST http://localhost:3000/forms/chromium/convert/html \
    --form files=@/path/to/index.html \
    --form pdfa=PDF/A-1b \
    --form pdfua=true \
    -o my.pdf
  6. Embed external files as PDF attachments

    Attach files directly inside the PDF container using the embeds form files. To satisfy PDF/A-3 or Factur-X requirements, use embedsMetadata to specify the mimeType and relationship (e.g., Source, Data, Alternative, Supplement) for each file, keyed by the filename.

    This feature requires a supported PDF engine (QPDF is the default).

    curl \
    --request POST http://localhost:3000/forms/chromium/convert/url \
    --form url=https://my.url \
    --form embeds=@factur-x.xml \
    --form embeds=@logo.png \
    --form embedsMetadata='{"factur-x.xml":{"mimeType":"text/xml","relationship":"Alternative"},"logo.png":{"mimeType":"image/png","relationship":"Supplement"}}' \
    -o my.pdf
  7. Handle fonts and linked content in LibreOffice

    Important constraints for high-fidelity rendering:

    • Fonts: LibreOffice uses installed fonts for layout. Missing fonts cause shifted pagination. Install required fonts in your Docker image via a custom Dockerfile.
    • Linked Content: Since v8.34.0, LibreOffice drops linked content (e.g., file:// paths or external URLs) for security. The conversion will succeed (200 OK), but the linked content will be absent. Use embedded images instead of linked images.
    • Macros: Macros in files (e.g., .docm, .xlsm) are disabled by default; macro-generated content will not execute.
  8. Add watermarks to PDF files

    Use the /forms/pdfengines/watermark endpoint to add a watermark behind the content of each page of one or more PDF files. You can use a simple text label, a tiled image, or a full-page PDF as the watermark source. If multiple input files are provided, Gotenberg returns a ZIP archive of the watermarked PDFs.
    curl \
    --request POST http://localhost:3000/forms/pdfengines/watermark \
    --form files=@/path/to/file.pdf \
    --form watermarkSource=text \
    --form watermarkExpression=CONFIDENTIAL \
    --form 'watermarkOptions={"opacity":0.25,"rotation":45}' \
    -o my.pdf
  9. Embed external files into a Markdown-to-PDF conversion

    Attach external files (such as XML invoices or images) directly inside the PDF container. This is commonly used for e-invoicing standards like ZUGFeRD or Factur-X. You can provide per-attachment metadata using embedsMetadata to specify the MIME type and the relationship of the file to the document.
    curl \
    --request POST http://localhost:3000/forms/chromium/convert/markdown \
    --form files=@/path/to/index.html \
    --form files=@/path/to/file.md \
    --form embeds=@factur-x.xml \
    --form embeds=@logo.png \
    --form embedsMetadata='{"factur-x.xml":{"mimeType":"text/xml","relationship":"Alternative"},"logo.png":{"mimeType":"image/png","relationship":"Supplement"}}' \
    -o my.pdf
  10. Fix LibreOffice layout and font shifts

    Layout shifts in LibreOffice usually occur when the container lacks the fonts used in the document, causing LibreOffice to use substitutes.

    • Install Fonts: Use a custom Dockerfile to install required fonts.
    • Microsoft Core Fonts: After version 8.30.0, the font stack was simplified. If documents using Arial, Times New Roman, or Calibri show layout differences, install ttf-mscorefonts-installer.
    • Clipped Form Fields: If form field text is clipped due to font mismatches, set exportFormFields=false to flatten the fields.
  11. Encrypt and restrict a PDF during HTML conversion

    Set passwords and permissions to control PDF access.

    • userPassword: Required to open the PDF.
    • ownerPassword: Grants full access and lifts restrictions. If empty, it defaults to the user password.
    • Permission flags: allowPrinting, allowCopying, allowModifying, allowAnnotating, allowFillingForms, and allowAssembling (all default to true).

    Constraints:

    • Permission restrictions require either a userPassword or ownerPassword (otherwise returns 400 Bad Request).
    • Encryption strength and permission enforcement depend on the active PDF engine (QPDF, pdfcpu, or PDFtk).
    curl \
    --request POST http://localhost:3000/forms/chromium/convert/html \
    --form files=@/path/to/index.html \
    --form userPassword=my_user_password \
    --form ownerPassword=my_owner_password \
    --form allowCopying=false \
    -o my.pdf
  12. Encrypt merged PDFs with passwords and permissions

    Set user and owner passwords to control access and permissions. The user password is required to open the file. The owner password lifts restrictions. Since version 8.34.0, providing only an owner password creates an owner-only PDF (opens without password, but permissions apply).
    curl \
    --request POST http://localhost:3000/forms/pdfengines/merge \
    --form files=@/path/to/1_pdf.pdf \
    --form files=@/path/to/2_pdf.pdf \
    --form userPassword=my_user_password \
    --form ownerPassword=my_owner_password \
    --form allowCopying=false \
    -o my.pdf