Skip to main content
Version: 8.x

Routes

Most routes within Gotenberg are designed to accept multipart/form-data requests and generate one or more PDF files. This guide will assist you in understanding their usage.

Convert with Chromium

The next routes leverage the capabilities of the Chromium browser to effectively transform a diverse range of HTML documents into PDFs.

Checkout the Chromium module configuration to tailor the Chromium behavior to your needs.

URL into PDF route

This multipart/form-data route converts a web page into PDF.

POST /forms/chromium/convert/url

It accepts the following specific form field:

KeyDescription
urlURL of the page you want to convert into PDF.required
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
-o my.pdf
Content-Disposition: attachement; filename={output-filename.pdf}
Content-Type: {content-type}
Content-Length: {content-length}
Gotenberg-Trace: {trace}
Body: {output-file}
  • See the Request Tracing section for more information about the Gotenberg-Trace header.
  • See the Output Filename section for more information about the Gotenberg-Output-Filename header.

HTML file into PDF route

This multipart/form-data route converts an HTML file into PDF.

POST /forms/chromium/convert/html

It accepts the following specific form file:

KeyDescription
index.htmlThe HTML file to convert into PDF.required

For instance:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My PDF</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@/path/to/index.html \
-o my.pdf
Content-Disposition: attachement; filename={output-filename.pdf}
Content-Type: {content-type}
Content-Length: {content-length}
Gotenberg-Trace: {trace}
Body: {output-file}
  • See the Request Tracing section for more information about the Gotenberg-Trace header.
  • See the Output Filename section for more information about the Gotenberg-Output-Filename header.

You may also send additional files, like images, fonts, stylesheets, and so on.

The only requirement is that their paths in the index.html file are on the root level.

For instance, this will work:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My PDF</title>
</head>
<body>
<h1>Hello world!</h1>
<img src="img.png" />
</body>
</html>

But this won't:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My PDF</title>
</head>
<body>
<h1>Hello world!</h1>
<img src="/foo/img.png" />
</body>
</html>
curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@/path/to/index.html \
--form files=@/path/to/img.png \
-o my.pdf
info

Remote paths for images, fonts (e.g., Google Fonts), etc., work too.

warning

Beware of the <base> HTML element, as it may break path resolution for any relative href.

Markdown file(s) into PDF route

This multipart/form-data route converts Markdown file(s) into PDF.

POST /forms/chromium/convert/markdown

It accepts the following specific form files:

KeyDescription
index.htmlThe HTML file that wraps the markdown content.required
*.mdAt least one markdown file.required

It works like the HTML route but with access to a Go template function toHTML. This function converts a markdown file's content into HTML.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My PDF</title>
</head>
<body>
{{ toHTML "file.md" }}
</body>
</html>
curl \
--request POST http://localhost:3000/forms/chromium/convert/markdown \
--form files=@/path/to/index.html \
--form files=@/path/to/file.md \
-o my.pdf
Content-Disposition: attachement; filename={output-filename.pdf}
Content-Type: {content-type}
Content-Length: {content-length}
Gotenberg-Trace: {trace}
Body: {output-file}
  • See the Request Tracing section for more information about the Gotenberg-Trace header.
  • See the Output Filename section for more information about the Gotenberg-Output-Filename header.

Page Properties

Each route accepts the following form fields:

KeyDescriptionDefault
singlePageDefine whether to print the entire content in one single page.false
paperWidthSpecify paper width using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified.8.5
paperHeightSpecify paper height using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified.11
marginTopSpecify top margin width using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified.0.39
marginBottomSpecify bottom margin using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified.0.39
marginLeftSpecify left margin using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified.0.39
marginRightSpecify right margin using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified.0.39
preferCssPageSizeDefine whether to prefer page size as defined by CSS.false
printBackgroundPrint the background graphics.false
omitBackgroundHide the default white background and allow generating PDFs with transparency.false
landscapeSet the paper orientation to landscape.false
scaleThe scale of the page rendering.1.0
nativePageRangesPage ranges to print, e.g., '1-5, 8, 11-13' - empty means all pages.All pages
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form paperWidth=8.27 \
--form paperHeight=11.7 \
--form marginTop=1 \
--form marginBottom=1 \
--form marginLeft=1 \
--form marginRight=1 \
--form preferCssPageSize=false \
--form printBackground=true \
--form omitBackground=true \
--form landscape=true \
--form scale=2.0 \
--form nativePageRanges=1-5 \
-o my.pdf
info

If the singlePage form field is set to true, it automatically overrides the values from the paperHeight and nativePageRanges form fields.

info

Examples of paper size (width x height):

  • Letter - 8.5 x 11 (default)
  • Legal - 8.5 x 14
  • Tabloid - 11 x 17
  • Ledger - 17 x 11
  • A0 - 33.1 x 46.8
  • A1 - 23.4 x 33.1
  • A2 - 16.54 x 23.4
  • A3 - 11.7 x 16.54
  • A4 - 8.27 x 11.7
  • A5 - 5.83 x 8.27
  • A6 - 4.13 x 5.83
info

The rules regarding the printBackground and omitBackground form fields are the following:

  • If printBackground is set to false, no background is printed.
  • If printBackground is set to true:
    • If the HTML document has a background, that background is used.
    • If not:
      • If omitBackground is set to true, the default background is transparent.
      • If not, the default white background is used.

Each route accepts the following form files:

KeyDescriptionDefault
header.htmlHTML file containing the header.None
footer.htmlHTML file containing the footer.None
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form files=@/path/to/header.html \
--form files=@/path/to/footer.html \
-o my.pdf

Each of them has to be a complete HTML document:

<html>
<head>
<style>
body {
font-size: 12px;
margin: auto 20px;
}
</style>
</head>
<body>
<p><span class="pageNumber"></span> of <span class="totalPages"></span></p>
</body>
</html>
info

The following classes allow you to inject printing values:

  • date - formatted print date.
  • title - document title.
  • url - document location.
  • pageNumber - current page number.
  • totalPages - total pages in the document.
caution

There are some limitations:

  • No JavaScript.
  • The CSS properties are independent of the ones from the HTML document.
  • footer.html CSS properties override the ones from header.html.
  • Only fonts installed in the Docker image are loaded - see the fonts configuration section.
  • Images only work using a base64 encoded source - i.e., data:image/png;base64, iVBORw0K....
  • background-color and color CSS properties require an additional -webkit-print-color-adjust: exact CSS property in order to work.
  • Assets are not loaded (i.e., CSS files, scripts, fonts, etc.).
  • Background form fields do not apply.

Wait Before Rendering

Each route accepts the following form fields:

KeyDescriptionDefault
waitDelayDuration (e.g, '5s') to wait when loading an HTML document before converting it into PDF.None
waitForExpressionThe JavaScript expression to wait before converting an HTML document into PDF until it returns true.None
info

These form fields do not work if JavaScript is disabled via --chromium-disable-javascript.

See the Chromium module configuration for more details.

waitDelay

When the page relies on JavaScript for rendering, and you don't have access to the page's code, you may want to wait a certain amount of time to make sure Chromium has fully rendered the page you're trying to generate.

curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form waitDelay=5s \
-o my.pdf

waitForExpression

A more reliable option than the previous form field:

// Somewhere in the HTML document.
var globalVar = 'notReady'
await promises()
window.globalVar = 'ready'
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form 'waitForExpression=window.globalVar === '\''ready'\''' \
-o my.pdf

Emulated Media Type

Each route accepts the following form field:

KeyDescriptionDefault
emulatedMediaTypeThe media type to emulate, either "screen" or "print" - empty means "print".print

Some websites have dedicated CSS rules for print. Using "screen" allows you to force the "standard" CSS rules.

curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form emulatedMediaType=screen \
-o my.pdf

Cookies

Each route accepts the following form field:

KeyDescriptionDefault
cookiesCookies to store in the Chromium cookie jar (JSON format).None
info

Cookies are set to automatically expire after a specified duration, determined by the request time limit. Additionally, you have the option to clear cookies after each conversion.

For further details, refer to the API module configuration and the Chromium module configuration sections.

This form field is a JSON-formatted array with items accepting the following keys:

KeyDescriptionDefault
nameCookie name.required
valueCookie value.required
domainCookie domain.required
pathCookie path.None
secureSet the cookie to secure if true.None
httpOnlySet the cookie as HTTP-only if true.None
sameSiteAccepted values are "Strict", "Lax" or "None".None (empty)
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form 'cookies=[{"name":"yummy_cookie","value":"choco","domain":"theyummycookie.com"}]' \
-o my.pdf

Custom HTTP Headers

Each route accepts the following form fields:

KeyDescriptionDefault
userAgentOverride the default User-Agent HTTP header.None
extraHttpHeadersExtra HTTP headers to send by Chromium (JSON format).None
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form 'userAgent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)"' \
--form-string 'extraHttpHeaders={"X-Header":"value","X-Scoped-Header":"value;scope=https?:\\/\\/([a-zA-Z0-9-]+\\.)*domain\\.com\\/.*"}' \
-o my.pdf
info

You can add an optional scope token to a header value to restrict its application using a regular expression.

For example, "X-Scoped-Header":"value;scope=https?:\\/\\/([a-zA-Z0-9-]+\\.)*domain\\.com\\/.*" will apply the X-Scoped-Header only to requests directed at domain.com and its subdomains.

Note that the scope token is only processed by Gotenberg and is never sent with the header value.

Invalid HTTP Status Codes

Each route accepts the following form field:

KeyDescriptionDefault
failOnHttpStatusCodesReturn a 409 Conflict response if the HTTP status code from the main page is not acceptable.[499,599]

An X99 entry means every HTTP status codes between X00 and X99 (e.g., 499 means every HTTP status codes between 400 and 499).

curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://httpstat.us/400 \
--form 'failOnHttpStatusCodes=[499]'
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body:

Invalid HTTP status code from the main page: 400: Bad Request

Console Exceptions

Each route accepts the following form field:

KeyDescriptionDefault
failOnConsoleExceptionsReturn a 409 Conflict response if there are exceptions in the Chromium console.false
info

This form field does not work if JavaScript is disabled via --chromium-disable-javascript.

See the Chromium module configuration for more details.

curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@/path/to/index.html \
--form failOnConsoleExceptions=true
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body:

Chromium console exceptions:

exception "Uncaught" (17:10): Error: Exception 1
at file:///tmp/db09d2c8-31e3-4058-9923-c2705350f2b3/index.html:18:11;
exception "Uncaught" (20:10): Error: Exception 2
at file:///tmp/db09d2c8-31e3-4058-9923-c2705350f2b3/index.html:21:11:

Performance Mode

Each route accepts the following form field:

KeyDescriptionDefault
skipNetworkIdleEventDo not wait for Chromium network to be idle.true

By default, Gotenberg does not wait for the network idle event, significantly speeding up the conversion process. Although Chromium triggers this event heuristically, it is often — if not always — fired too late for page rendering.

warning

Prior to Gotenberg 8.11.0, false was the default value.

curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@/path/to/index.html \
--form skipNetworkIdleEvent=false \
-o my.pdf

PDF/A & PDF/UA

Each route accepts the following form fields:

KeyDescriptionDefault
pdfaConvert the resulting PDF into the given PDF/A format.None
pdfuaEnable PDF for Universal Access for optimal accessibility.false

At present, the following PDF/A formats are available:

  • PDF/A-1b
  • PDF/A-2b
  • PDF/A-3b
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form pdfa=PDF/A-1b \
--form pdfua=true \
-o my.pdf

Metadata

Each route accepts the following form field:

KeyDescriptionDefault
metadataThe metadata to write (JSON format).None
info

Not all metadata are writable. Consider taking a look at https://exiftool.org/TagNames/XMP.html#pdf for an (exhaustive?) list of available metadata.

caution

Writing metadata may compromise PDF/A compliance.

curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form 'metadata={"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreationDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"}' \
-o my.pdf

Screenshots route

You can capture screenshots using the following three routes, which function similarly to their PDF equivalents:

POST /forms/chromium/screenshot/url
POST /forms/chromium/screenshot/html
POST /forms/chromium/screenshot/markdown

These routes accept the following form fields:

KeyDescriptionDefault
widthThe device screen width in pixels.800
heightThe device screen height in pixels.600
clipDefine whether to clip the screenshot according to the device dimensions.false
formatThe image compression format, either "png", "jpeg" or "webp".png
qualityThe compression quality from range 0 to 100 (jpeg only).100
omitBackgroundHide the default white background and allow generating screenshots with transparency.false
optimizeForSpeedDefine whether to optimize image encoding for speed, not for resulting size.false

The following features are also available:

curl \
--request POST http://localhost:3000/forms/chromium/screenshot/html \
--form files=@/path/to/index.html \
--form format=jpeg \
--form quality=100 \
--form optimizeForSpeed=true \
-o my.jpeg

Convert with LibreOffice

The next route leverage the capabilities of LibreOffice to effectively transform a diverse range of Office documents (Word, Excel, PowerPoint, etc.) into PDFs.

Checkout the LibreOffice module configuration to tailor the LibreOffice behavior to your needs.

tip

This route mainly targets Office documents, but you can also use it to manipulate PDFs, for instance by compressing images.

Office documents into PDFs route

This multipart/form-data route convert one or more Office documents into PDF.

POST /forms/libreoffice/convert

Currently, the following extensions are supported:

.123 .602 .abw .bib .bmp .cdr .cgm .cmx .csv .cwk .dbf .dif .doc .docm .docx .dot .dotm .dotx .dxf .emf .eps .epub .fodg .fodp .fods .fodt .fopd .gif .htm .html .hwp .jpeg .jpg .key .ltx .lwp .mcw .met .mml .mw .numbers .odd .odg .odm .odp .ods .odt .otg .oth .otp .ots .ott .pages .pbm .pcd .pct .pcx .pdb .pdf .pgm .png .pot .potm .potx .ppm .pps .ppt .pptm .pptx .psd .psw .pub .pwp .pxl .ras .rtf .sda .sdc .sdd .sdp .sdw .sgl .slk .smf .stc .std .sti .stw .svg .svm .swf .sxc .sxd .sxg .sxi .sxm .sxw .tga .tif .tiff .txt .uof .uop .uos .uot .vdx .vor .vsd .vsdm .vsdx .wb2 .wk1 .wks .wmf .wpd .wpg .wps .xbm .xhtml .xls .xlsb .xlsm .xlsx .xlt .xltm .xltx .xlw .xml .xpm .zabw

curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
-o my.pdf
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form files=@/path/to/file.xlsx \
-o my.zip
Content-Disposition: attachement; filename={output-filename.ext}
Content-Type: {content-type}
Content-Length: {content-length}
Gotenberg-Trace: {trace}
Body: {output-file}
  • See the Request Tracing section for more information about the Gotenberg-Trace header.
  • See the Output Filename section for more information about the Gotenberg-Output-Filename header.

Page Properties

The route also accepts the following form fields:

KeyDescriptionDefault
passwordSet the password for opening the source file.None
landscapeSet the paper orientation to landscape.false
nativePageRangesPage ranges to print, e.g., '1-4' - empty means all pages.All pages
exportFormFieldsSpecify whether form fields are exported as widgets or only their fixed print representation is exported.true
allowDuplicateFieldNamesSpecify whether multiple form fields exported are allowed to have the same field name.false
exportBookmarksSpecify if bookmarks are exported to PDF.true
exportBookmarksToPdfDestinationSpecify that the bookmarks contained in the source LibreOffice file should be exported to the PDF file as Named Destination.false
exportPlaceholdersExport the placeholders fields visual markings only. The exported placeholder is ineffective.false
exportNotesSpecify if notes are exported to PDF.false
exportNotesPagesSpecify if notes pages are exported to PDF. Notes pages are available in Impress documents only.false
exportOnlyNotesPagesSpecify, if the form field exportNotesPages is set to true, if only notes pages are exported to PDF.false
exportNotesInMarginSpecify if notes in margin are exported to PDF.false
convertOooTargetToPdfTargetSpecify that the target documents with .od[tpgs] extension, will have that extension changed to .pdf when the link is exported to PDF. The source document remains untouched.false
exportLinksRelativeFsysSpecify that the file system related hyperlinks (file:// protocol) present in the document will be exported as relative to the source document location.false
exportHiddenSlidesExport, for LibreOffice Impress, slides that are not included in slide shows.false
skipEmptyPagesSpecify that automatically inserted empty pages are suppressed. This option is active only if storing Writer documents.false
addOriginalDocumentAsStreamSpecify that a stream is inserted to the PDF file which contains the original document for archiving purposes.false
singlePageSheetsIgnore each sheet’s paper size, print ranges and shown/hidden status and puts every sheet (even hidden sheets) on exactly one page.false
info

If multiple files are provided, the page ranges will be applied independently to each file.

curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form landscape=true \
--form nativePageRanges=1-5 \
--form exportFormFields=false \
-o my.pdf
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.xlsx \
--form singlePageSheets=true \
-o my.pdf

Compress

The route accepts the following form fields:

KeyDescriptionDefault
losslessImageCompressionSpecify if images are exported to PDF using a lossless compression format like PNG or compressed using the JPEG format.false
qualitySpecify the quality of the JPG export. A higher value produces a higher-quality image and a larger file. Between 1 and 100.90
reduceImageResolutionSpecify if the resolution of each image is reduced to the resolution specified by the form field maxImageResolution.false
maxImageResolutionIf the form field reduceImageResolution is set to true, tell if all images will be reduced to the given value in DPI. Possible values are: 75, 150, 300, 600 and 1200.300
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form losslessImageCompression=false \
--form quality=50 \
--form reduceImageResolution=true \
--form maxImageResolution=75 \
-o my.pdf

Merge

The route also accepts the following form fields:

KeyDescriptionDefault
mergeMerge alphanumerically the resulting PDFs.false
info

Alphanumerically means numbers first, then letters in alphabetical order.

curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form files=@/path/to/file.xlsx \
--form merge=true \
-o my.pdf

PDF/A & PDF/UA

The route also accepts the following form fields:

KeyDescriptionDefault
pdfaConvert the resulting PDF into the given PDF/A format.None
pdfuaEnable PDF for Universal Access for optimal accessibility.false

At present, the following PDF/A formats are available:

  • PDF/A-1b
  • PDF/A-2b
  • PDF/A-3b
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form pdfa=PDF/A-1b \
--form pdfua=true \
-o my.pdf

Metadata

The route accepts the following form field:

KeyDescriptionDefault
metadataThe metadata to write (JSON format).None
info

Not all metadata are writable. Consider taking a look at https://exiftool.org/TagNames/XMP.html#pdf for an (exhaustive?) list of available metadata.

caution

Writing metadata may compromise PDF/A compliance.

curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form 'metadata={"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreationDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"}' \
-o my.pdf

Convert into PDF/A & PDF/UA route

This multipart/form-data route transforms one or more PDF files into the requested PDF/A format and/or PDF/UA.

POST /forms/pdfengines/convert

It accepts the following form files and form fields:

KeyDescriptionDefault
*.pdfAt least one PDF file.required
pdfaConvert the resulting PDF into the given PDF/A format.None*
pdfuaEnable PDF for Universal Access for optimal accessibility.false*

*Note that at least one of the form field must be provided.

At present, the following PDF/A formats are available:

  • PDF/A-1b
  • PDF/A-2b
  • PDF/A-3b
curl \
--request POST http://localhost:3000/forms/pdfengines/convert \
--form files=@/path/to/pdf.pdf \
--form pdfa=PDF/A-1b \
--form pdfua=true \
-o my.pdf
curl \
--request POST http://localhost:3000/forms/pdfengines/convert \
--form files=@/path/to/pdf1.pdf \
--form files=@/path/to/pdf2.pdf \
--form files=@/path/to/pdf3.pdf \
--form files=@/path/to/pdf4.pdf \
--form pdfa=PDF/A-1b \
--form pdfua=true \
-o my.zip
Content-Disposition: attachement; filename={output-filename.ext}
Content-Type: {content-type}
Content-Length: {content-length}
Gotenberg-Trace: {trace}
Body: {output-file}
  • See the Request Tracing section for more information about the Gotenberg-Trace header.
  • See the Output Filename section for more information about the Gotenberg-Output-Filename header.

Read PDF metadata route

This multipart/form-data route returns the metadata of one or more PDF files.

POST /forms/pdfengines/metadata/read

It accepts the following form files:

KeyDescriptionDefault
*.pdfAt least one PDF file.required
curl \
--request POST http://localhost:3000/forms/pdfengines/metadata/read \
--form files=@/path/to/file1.pdf \
--form files=@/path/to/file2.pdf
Content-Type: application/json; charset=UTF-8
Content-Length: {content-length}
Gotenberg-Trace: {trace}
Body:
{
"file1.pdf": {
"CreateDate": "2024:03:05 09:15:32Z",
"Creator": "Writer",
"TaggedPDF": "Yes",
"XMPToolkit": "Image::ExifTool 12.57"
// ...
},
"file2.pdf": {
"CreateDate": "2024:03:05 09:15:32Z",
"Creator": "Writer",
"TaggedPDF": "Yes",
"XMPToolkit": "Image::ExifTool 12.57"
// ...
}
}
  • See the Request Tracing section for more information about the Gotenberg-Trace header.

Write PDF metadata route

This multipart/form-data route accepts one or more PDF files and writes/overrides their metadata.

POST /forms/pdfengines/metadata/write

It accepts the following form files and form field:

KeyDescriptionDefault
*.pdfAt least one PDF file.required
metadataThe metadata to write (JSON format).required
info

Not all metadata are writable. Consider taking a look at https://exiftool.org/TagNames/XMP.html#pdf for an (exhaustive?) list of available metadata.

caution

Writing metadata may compromise PDF/A compliance.

curl \
--request POST http://localhost:3000/forms/pdfengines/metadata/write \
--form files=@/path/to/file.pdf \
--form 'metadata={"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreationDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"}' \
-o my.pdf
curl \
--request POST http://localhost:3000/forms/pdfengines/metadata/write \
--form files=@/path/to/file1.pdf \
--form files=@/path/to/file2.pdf \
--form 'metadata={"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreationDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"}' \
-o my.zip
Content-Disposition: attachement; filename={output-filename.ext}
Content-Type: {content-type}
Content-Length: {content-length}
Gotenberg-Trace: {trace}
Body: {output-file}
  • See the Request Tracing section for more information about the Gotenberg-Trace header.
  • See the Output Filename section for more information about the Gotenberg-Output-Filename header.

Merge PDFs route

This multipart/form-data route accepts PDF files and merges them alphanumerically.

info

Alphanumerically means numbers first, then letters in alphabetical order.

POST /forms/pdfengines/merge
KeyDescriptionDefault
*.pdfPDF files.required
pdfaConvert the resulting PDF into the given PDF/A format.None
pdfuaEnable PDF for Universal Access for optimal accessibility.false
metadataThe metadata to write (JSON format).None
curl \
--request POST http://localhost:3000/forms/pdfengines/merge \
--form files=@/path/to/pdf1.pdf \
--form files=@/path/to/pdf2.pdf \
--form files=@/path/to/pdf3.pdf \
--form files=@/path/to/pdf4.pdf \
-o my.pdf
Content-Disposition: attachement; filename={output-filename.pdf}
Content-Type: {content-type}
Content-Length: {content-length}
Gotenberg-Trace: {trace}
Body: {output-file}
  • See the Request Tracing section for more information about the Gotenberg-Trace header.
  • See the Output Filename section for more information about the Gotenberg-Output-Filename header.

Health Check route

GET /health
HEAD /health
curl --request GET http://localhost:3000/health
curl --request HEAD http://localhost:3000/health
{
"status": "up",
"details": {
"chromium": {
"status": "up",
"timestamp": "2021-07-01T08:05:14.603364Z"
},
"libreoffice": {
"status": "up",
"timestamp": "2021-07-01T08:05:14.603364Z"
}
}
}

The details entry gathers the health checks from modules:

  • The Chromium module checks if the Chromium browser is healthy.
  • The LibreOffice module checks if the LibreOffice instance is healthy.
info

The body will be empty with the HEAD method.

Metrics route

This route exposes the metrics from other modules using the Prometheus format.

GET /prometheus/metrics

Currently, the metrics include:

MetricDescription
{namespace}_chromium_requests_queue_sizeCurrent number of Chromium conversion requests waiting to be treated.
{namespace}_chromium_restarts_countCurrent number of Chromium restarts.
{namespace}_libreoffice_requests_queue_sizeCurrent number of LibreOffice conversion requests waiting to be treated.
{namespace}_libreoffice_restarts_countCurrent number of LibreOffice restarts.

See the Prometheus module configuration for more information.

Version route

GET /version
curl --request GET http://localhost:3000/version
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body:

8.12.0
info

Custom variants of Gotenberg may not print a strict semver version.

For instance, the live demo prints 8.12.0-live-demo-snapshot.

Request Tracing

A trace, or request ID, serves to identify a specific request in the logs.

By default, the API assigns a unique UUID trace to every request. However, you also have the option to specify the trace for each request using the Gotenberg-Trace header.

curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--header 'Gotenberg-Trace: debug' \
--form url=https://my.url \
-o my.pdf

The API also incorporates a Gotenberg-Trace header into each response. If you're utilizing the webhook feature, this header will also be added to each request made to your callbacks.

info

The --api-trace-header flag allows you to configure the header key. See the API module configuration for more details.

Output Filename

By default, for multipart/form-data endpoints, the API generates a response with a UUID filename. However, you have the option to specify the filename for each request using the Gotenberg-Output-Filename header.

curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--header 'Gotenberg-Output-Filename: my_filename' \
--form url=https://my.url \
-O -J
info

The API automatically appends the file extension, so there's no need for you to set it manually.

Download From

All multipart/form-data endpoints accept the following form field:

KeyDescriptionDefault
downloadFromURLs to download files from (JSON format).None
info

This form field does not work if this feature is disabled via --api-disable-download-from.

For further details, refer to the API module configuration.

This form field is a JSON-formatted array with items accepting the following keys:

KeyDescriptionDefault
urlURL of the file. It MUST return a Content-Disposition header with a filename parameter.required
extraHttpHeadersThe extra HTTP headers to send to the URL (JSON format).None
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form 'downloadFrom=[{"url":"http://url/to/file.com","extraHttpHeaders":{"X-Header": "value"}}]' \
-o my.pdf
GET http://url/to/file.com
Gotenberg-Trace: {trace}
User-Agent: Gotenberg
X-Header: value
warning

Currently, a bug is preventing Gotenberg to parse an empty mediatype. If you're using AWS S3, make sure to set the Content-Disposition header with the attachment value in the S3 metadata.