| id | routes |
|---|---|
| title | Routes |
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
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.
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.
This multipart/form-data route converts a web page into PDF.
POST /forms/chromium/convert/url
It accepts the following specific form field:
| Key | Description | |
|---|---|---|
| url | URL of the page you want to convert into PDF. | required |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
-o my.pdf<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '403 Forbidden', value: '403', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
Gotenberg also returns a 400 Bad Request if it encounters any of the following network errors while attempting to load the main page:
net::ERR_CONNECTION_CLOSEDnet::ERR_CONNECTION_RESETnet::ERR_CONNECTION_REFUSEDnet::ERR_CONNECTION_ABORTEDnet::ERR_CONNECTION_FAILEDnet::ERR_NAME_NOT_RESOLVEDnet::ERR_INTERNET_DISCONNECTEDnet::ERR_ADDRESS_UNREACHABLEnet::ERR_BLOCKED_BY_CLIENTnet::ERR_BLOCKED_BY_RESPONSEnet::ERR_FILE_NOT_FOUNDnet::ERR_HTTP2_PROTOCOL_ERROR
This error happens when the given URL is not authorized.
See the Chromium module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: '{url}' does not match the authorized URLs
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
This multipart/form-data route converts an HTML file into PDF.
POST /forms/chromium/convert/html
It accepts the following specific form file:
| Key | Description | |
|---|---|---|
| index.html | The 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><Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@/path/to/index.html \
-o my.pdf<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
Gotenberg also returns a 400 Bad Request if it encounters any of the following network errors while attempting to load the main page:
net::ERR_CONNECTION_CLOSEDnet::ERR_CONNECTION_RESETnet::ERR_CONNECTION_REFUSEDnet::ERR_CONNECTION_ABORTEDnet::ERR_CONNECTION_FAILEDnet::ERR_NAME_NOT_RESOLVEDnet::ERR_INTERNET_DISCONNECTEDnet::ERR_ADDRESS_UNREACHABLEnet::ERR_BLOCKED_BY_CLIENTnet::ERR_BLOCKED_BY_RESPONSEnet::ERR_FILE_NOT_FOUNDnet::ERR_HTTP2_PROTOCOL_ERROR
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
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><Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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.
:::
This multipart/form-data route converts Markdown file(s) into PDF.
POST /forms/chromium/convert/markdown
It accepts the following specific form files:
| Key | Description | |
|---|---|---|
| index.html | The HTML file that wraps the markdown content. | required |
| *.md | At 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 (with MathJaX support).
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My PDF</title>
</head>
<body>
{{ toHTML "file.md" }}
</body>
</html><Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
Gotenberg also returns a 400 Bad Request if it encounters any of the following network errors while attempting to load the main page:
net::ERR_CONNECTION_CLOSEDnet::ERR_CONNECTION_RESETnet::ERR_CONNECTION_REFUSEDnet::ERR_CONNECTION_ABORTEDnet::ERR_CONNECTION_FAILEDnet::ERR_NAME_NOT_RESOLVEDnet::ERR_INTERNET_DISCONNECTEDnet::ERR_ADDRESS_UNREACHABLEnet::ERR_BLOCKED_BY_CLIENTnet::ERR_BLOCKED_BY_RESPONSEnet::ERR_FILE_NOT_FOUNDnet::ERR_HTTP2_PROTOCOL_ERROR
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
Each route accepts the following form fields:
| Key | Description | Default |
|---|---|---|
| singlePage | Define whether to print the entire content in one single page. | false |
| paperWidth | Specify paper width using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified. | 8.5 |
| paperHeight | Specify paper height using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified. | 11 |
| marginTop | Specify top margin width using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified. | 0.39 |
| marginBottom | Specify bottom margin using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified. | 0.39 |
| marginLeft | Specify left margin using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified. | 0.39 |
| marginRight | Specify right margin using units like 72pt, 96px, 1in, 25.4mm, 2.54cm, or 6pc. Default unit is inches if unspecified. | 0.39 |
| preferCssPageSize | Define whether to prefer page size as defined by CSS. | false |
| generateDocumentOutline | Define whether the document outline should be embedded into the PDF. | false |
| generateTaggedPdf | Define whether to generate tagged (accessible) PDF. | false |
| printBackground | Print the background graphics. | false |
| omitBackground | Hide the default white background and allow generating PDFs with transparency. | false |
| landscape | Set the paper orientation to landscape. | false |
| scale | The scale of the page rendering. | 1.0 |
| nativePageRanges | Page ranges to print, e.g., '1-5, 8, 11-13' - empty means all pages. | All pages |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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 14Tabloid- 11 x 17Ledger- 17 x 11A0- 33.1 x 46.8A1- 23.4 x 33.1A2- 16.54 x 23.4A3- 11.7 x 16.54A4- 8.27 x 11.7A5- 5.83 x 8.27A6- 4.13 x 5.83
:::
:::info
The rules regarding the printBackground and omitBackground form fields are the following:
- If
printBackgroundis set to false, no background is printed. - If
printBackgroundis set to true:- If the HTML document has a background, that background is used.
- If not:
- If
omitBackgroundis set to true, the default background is transparent. - If not, the default white background is used.
- If
:::
Each route accepts the following form files:
| Key | Description | Default |
|---|---|---|
| header.html | HTML file containing the header. | None |
| footer.html | HTML file containing the footer. | None |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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.pdfEach 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
It is recommended to use a large font-size to ensure that the content displays correctly.
:::
:::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.htmlCSS properties override the ones fromheader.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-colorandcolorCSS properties require an additional-webkit-print-color-adjust: exactCSS property in order to work.- Assets are not loaded (i.e., CSS files, scripts, fonts, etc.).
- Background form fields do not apply.
:::
:::danger
Remove external assets from your header and footer; they can slow rendering or cause the request to fail.
:::
Each route accepts the following form fields:
| Key | Description | Default |
|---|---|---|
| waitDelay | Duration (e.g, '5s') to wait when loading an HTML document before converting it into PDF. | None |
| waitForExpression | The JavaScript expression to wait before converting an HTML document into PDF until it returns true. | None |
| waitForSelector | Selector (e.g. '#id') to query before converting an HTML document into PDF until it matches a node. | 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.
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form waitDelay=5s \
-o my.pdfwaitForExpression
A more reliable option than the previous form field:
// Somewhere in the HTML document.
var globalVar = 'notReady'
await promises()
window.globalVar = 'ready'<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form 'waitForExpression=window.globalVar === '\''ready'\''' \
-o my.pdfwaitForSelector
Instead of waiting on an expression, you can wait until a node matching a selector query becomes visible on the page:
// Somewhere in the HTML document
await promises()
const newText = document.createElement("p")
newText.id = "special-id"
document.insertBefore(newText, null)<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form 'waitForSelector=#special-id' \
-o my.pdfEach route accepts the following form field:
| Key | Description | Default |
|---|---|---|
| emulatedMediaType | The media type to emulate, either "screen" or "print" - empty means "print". |
Some websites have dedicated CSS rules for print. Using "screen" allows you to force the "standard" CSS rules.
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form emulatedMediaType=screen \
-o my.pdfEach route accepts the following form field:
| Key | Description | Default |
|---|---|---|
| cookies | Cookies 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:
| Key | Description | Default |
|---|---|---|
| name | Cookie name. | required |
| value | Cookie value. | required |
| domain | Cookie domain. | required |
| path | Cookie path. | None |
| secure | Set the cookie to secure if true. | None |
| httpOnly | Set the cookie as HTTP-only if true. | None |
| sameSite | Accepted values are "Strict", "Lax" or "None". | None (empty) |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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.pdfEach route accepts the following form fields:
| Key | Description | Default |
|---|---|---|
| userAgent | Override the default User-Agent HTTP header. |
None |
| extraHttpHeaders | Extra HTTP headers to send by Chromium (JSON format). | None |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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.
:::
Each route accepts the following form field:
| Key | Description | Default |
|---|---|---|
| failOnHttpStatusCodes | Return a 409 Conflict response if the HTTP status code from the main page is not acceptable. | [499,599] |
| failOnResourceHttpStatusCodes | Return a 409 Conflict response if the HTTP status code from at least one resource is not acceptable. | None |
An X99 entry means every HTTP status codes between X00 and X99 (e.g., 499 means every HTTP status codes between 400 and 499).
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://httpstat.us/400 \
--form 'failOnHttpStatusCodes=[499]'<Tabs defaultValue="409" values={[ { label: '409 Conflict', value: '409', }, ] }>
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body:
Invalid HTTP status code from the main page: 400: Bad Request
Gotenberg returns a 400 Bad Request if it encounters any of the following network errors while attempting to load the main page:
net::ERR_CONNECTION_CLOSEDnet::ERR_CONNECTION_RESETnet::ERR_CONNECTION_REFUSEDnet::ERR_CONNECTION_ABORTEDnet::ERR_CONNECTION_FAILEDnet::ERR_NAME_NOT_RESOLVEDnet::ERR_INTERNET_DISCONNECTEDnet::ERR_ADDRESS_UNREACHABLEnet::ERR_BLOCKED_BY_CLIENTnet::ERR_BLOCKED_BY_RESPONSEnet::ERR_FILE_NOT_FOUNDnet::ERR_HTTP2_PROTOCOL_ERROR
If you want a similar behavior for resources too, you may use the following form field:
| Key | Description | Default |
|---|---|---|
| failOnResourceLoadingFailed | Return a 409 Conflict response if Chromium fails to load at least one resource. | false |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@/path/to/index.html \
--form failOnResourceLoadingFailed=true<Tabs defaultValue="409" values={[ { label: '409 Conflict', value: '409', }, ] }>
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body:
Chromium failed to load resources: resource Stylesheet: net::ERR_FILE_NOT_FOUND; resource Image: net::ERR_CONNECTION_REFUSED
:::info
It's currently not possible to have more details about the exact resource that is failing.
:::
Each route accepts the following form field:
| Key | Description | Default |
|---|---|---|
| failOnConsoleExceptions | Return 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.
:::
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@/path/to/index.html \
--form failOnConsoleExceptions=true<Tabs defaultValue="409" values={[ { label: '409 Conflict', value: '409', }, ] }>
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:
Each route accepts the following form field:
| Key | Description | Default |
|---|---|---|
| skipNetworkIdleEvent | Do 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.
:::warning
Prior to Gotenberg 8.11.0, false was the default value.
:::
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@/path/to/index.html \
--form skipNetworkIdleEvent=false \
-o my.pdfEach route accepts the following form fields:
| Key | Description | Default |
|---|---|---|
| splitMode | Either intervals or pages. | None |
| splitSpan | Either the intervals or the page ranges to extract, depending on the selected mode. | None |
| splitUnify | Specify whether to put extracted pages into a single file or as many files as there are page ranges. Only works with pages mode. | false |
:::caution
Gotenberg currently does not validate the splitSpan value if splitMode is pages, as it depends on the selected
engine for the split feature:
See also the PDF Engines module configuration for more details.
:::
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form splitMode=intervals \
--form splitSpan=1 \
-o my.zip<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--form url=https://my.url \
--form splitMode=pages \
--form splitSpan=1-2 \
--form splitUnify=true \
-o my.pdfEach route accepts the following form fields:
| Key | Description | Default |
|---|---|---|
| pdfa | Convert the resulting PDF into the given PDF/A format. | None |
| pdfua | Enable PDF for Universal Access for optimal accessibility. | false |
:::info
As of Gotenberg 8.21.0, using the generateTaggedPdf form field may yield better results if you're prioritizing
accessibility over strict (and sometimes hacky) PDF/UA compliance.
:::
At present, the following PDF/A formats are available:
PDF/A-1bPDF/A-2bPDF/A-3b
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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.pdfEach route accepts the following form field:
| Key | Description | Default |
|---|---|---|
| metadata | The 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.
:::
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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.pdfEach route accepts the following form field:
| Key | Description | Default |
|---|---|---|
| flatten | Flatten the resulting PDF. | false |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert \
--form url=https://my.url \
--form flatten=true \
-o my.pdfEach route accepts the following specific form fields:
| Key | Description | Default |
|---|---|---|
| userPassword | Password for opening the resulting PDF(s). | None |
| ownerPassword | Password for full access on the resulting PDF(s). | None |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert \
--form url=https://my.url \
--form userPassword=my_user_password \
--form ownerPassword=my_owner_password \
-o my.pdf<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
This feature enables the creation of PDFs compatible with standards like ZUGFeRD / Factur-X, which require embedding XML invoices and other files within the PDF.
Each route accepts the following form field to attach files to the generated PDF:
| Key | Description | Default |
|---|---|---|
| embeds | Files to embed in the generated PDF (repeatable). | None |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/html \
--form files=@index.html \
--form embeds=@invoice.xml \
--form embeds=@logo.png \
-o my.pdf:::info
You can embed multiple files by repeating the embeds form field. All embedded files will be attached to the generated PDF and can be extracted using PDF readers that support file attachments.
:::
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:
| Key | Description | Default |
|---|---|---|
| width | The device screen width in pixels. | 800 |
| height | The device screen height in pixels. | 600 |
| clip | Define whether to clip the screenshot according to the device dimensions. | false |
| format | The image compression format, either "png", "jpeg" or "webp". | png |
| quality | The compression quality from range 0 to 100 (jpeg only). | 100 |
| omitBackground | Hide the default white background and allow generating screenshots with transparency. | false |
| optimizeForSpeed | Define whether to optimize image encoding for speed, not for resulting size. | false |
The following features are also available:
- Wait Before Rendering
- Emulated Media Type
- Cookies
- Custom HTTP headers
- Invalid HTTP Status Codes
- Console Exceptions
- Performance Mode
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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:::info
If your screenshots' content is repeated and clipped, consider setting the skipNetworkIdleEvent form field to false.
See issue #1065.
:::
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.
:::
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
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
-o my.pdf<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form files=@/path/to/file.xlsx \
-o my.zip<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
The route also accepts the following form fields:
| Key | Description | Default |
|---|---|---|
| password | Set the password for opening the source file. | None |
| landscape | Set the paper orientation to landscape. | false |
| nativePageRanges | Page ranges to print, e.g., '1-4' - empty means all pages. | All pages |
| updateIndexes | Specify whether to update the indexes before conversion, keeping in mind that doing so might result in missing links in the final PDF. | true |
| exportFormFields | Specify whether form fields are exported as widgets or only their fixed print representation is exported. | true |
| allowDuplicateFieldNames | Specify whether multiple form fields exported are allowed to have the same field name. | false |
| exportBookmarks | Specify if bookmarks are exported to PDF. | true |
| exportBookmarksToPdfDestination | Specify that the bookmarks contained in the source LibreOffice file should be exported to the PDF file as Named Destination. | false |
| exportPlaceholders | Export the placeholders fields visual markings only. The exported placeholder is ineffective. | false |
| exportNotes | Specify if notes are exported to PDF. | false |
| exportNotesPages | Specify if notes pages are exported to PDF. Notes pages are available in Impress documents only. | false |
| exportOnlyNotesPages | Specify, if the form field exportNotesPages is set to true, if only notes pages are exported to PDF. | false |
| exportNotesInMargin | Specify if notes in margin are exported to PDF. | false |
| convertOooTargetToPdfTarget | Specify 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 |
| exportLinksRelativeFsys | Specify that the file system related hyperlinks (file:// protocol) present in the document will be exported as relative to the source document location. | false |
| exportHiddenSlides | Export, for LibreOffice Impress, slides that are not included in slide shows. | false |
| skipEmptyPages | Specify that automatically inserted empty pages are suppressed. This option is active only if storing Writer documents. | false |
| addOriginalDocumentAsStream | Specify that a stream is inserted to the PDF file which contains the original document for archiving purposes. | false |
| singlePageSheets | Ignore 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.
:::
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.xlsx \
--form singlePageSheets=true \
-o my.pdfThe route accepts the following form fields:
| Key | Description | Default |
|---|---|---|
| losslessImageCompression | Specify if images are exported to PDF using a lossless compression format like PNG or compressed using the JPEG format. | false |
| quality | Specify the quality of the JPG export. A higher value produces a higher-quality image and a larger file. Between 1 and 100. | 90 |
| reduceImageResolution | Specify if the resolution of each image is reduced to the resolution specified by the form field maxImageResolution. | false |
| maxImageResolution | If 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 |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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.pdfThe route also accepts the following form fields:
| Key | Description | Default |
|---|---|---|
| merge | Merge alphanumerically the resulting PDFs. | false |
:::info
Alphanumerically means numbers first, then letters in alphabetical order.
:::
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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.pdfThe route accepts the following form fields:
| Key | Description | Default |
|---|---|---|
| splitMode | Either intervals or pages. | None |
| splitSpan | Either the intervals or the page ranges to extract, depending on the selected mode. | None |
| splitUnify | Specify whether to put extracted pages into a single file or as many files as there are page ranges. Only works with pages mode. | false |
:::caution
Gotenberg currently does not validate the splitSpan value if splitMode is pages, as it depends on the selected
engine for the split feature:
See also the PDF Engines module configuration for more details.
:::
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form splitMode=intervals \
--form splitSpan=1 \
-o my.zip<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form splitMode=pages \
--form splitSpan=1-2 \
--form splitUnify=true \
-o my.pdfThe route also accepts the following form fields:
| Key | Description | Default |
|---|---|---|
| pdfa | Convert the resulting PDF into the given PDF/A format. | None |
| pdfua | Enable PDF for Universal Access for optimal accessibility. | false |
At present, the following PDF/A formats are available:
PDF/A-1bPDF/A-2bPDF/A-3b
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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.pdfThe route accepts the following form field:
| Key | Description | Default |
|---|---|---|
| metadata | The 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.
:::
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form 'metadata={"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"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.pdfThe route accepts the following form field:
| Key | Description | Default |
|---|---|---|
| flatten | Flatten the resulting PDF. | false |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form flatten=true \
-o my.pdfThe route accepts the following specific form fields:
| Key | Description | Default |
|---|---|---|
| userPassword | Password for opening the resulting PDF(s). | None |
| ownerPassword | Password for full access on the resulting PDF(s). | None |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form userPassword=my_user_password \
--form ownerPassword=my_owner_password \
-o my.pdf<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
This feature enables the creation of PDFs compatible with standards like ZUGFeRD / Factur-X, which require embedding XML invoices and other files within the PDF.
The route accepts the following form field to attach files to the generated PDF:
| Key | Description | Default |
|---|---|---|
| embeds | Files to embed in the generated PDF (repeatable). | None |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form files=@/path/to/file.docx \
--form embeds=@invoice.xml \
--form embeds=@logo.png \
-o my.pdf:::info
You can embed multiple files by repeating the embeds form field. All embedded files will be attached to the generated PDF and can be extracted using PDF readers that support file attachments.
:::
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:
| Key | Description | Default |
|---|---|---|
| At least one PDF file. | required | |
| pdfa | Convert the resulting PDF into the given PDF/A format. | None<span style={{color: 'red'}}>* |
| pdfua | Enable PDF for Universal Access for optimal accessibility. | false<span style={{color: 'red'}}>* |
<span style={{color: 'red'}}>*Note that at least one of the form field must be provided.
At present, the following PDF/A formats are available:
PDF/A-1bPDF/A-2bPDF/A-3b
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
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:
| Key | Description | Default |
|---|---|---|
| At least one PDF file. | required |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/pdfengines/metadata/read \
--form files=@/path/to/file1.pdf \
--form files=@/path/to/file2.pdf<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
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-Traceheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
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:
| Key | Description | Default |
|---|---|---|
| At least one PDF file. | required | |
| metadata | The 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.
:::
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/pdfengines/metadata/write \
--form files=@/path/to/file.pdf \
--form 'metadata={"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"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<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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","CreateDate":"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<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
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
| Key | Description | Default |
|---|---|---|
| PDF files. | required | |
| pdfa | Convert the resulting PDF into the given PDF/A format. | None |
| pdfua | Enable PDF for Universal Access for optimal accessibility. | false |
| metadata | The metadata to write (JSON format). | None |
| flatten | Flatten the resulting PDF. | false |
| userPassword | Password for opening the resulting PDF(s). | None |
| ownerPassword | Password for full access on the resulting PDF(s). | None |
| embeds | Files to embed in the generated PDF (repeatable). | None |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
This multipart/form-data route splits PDF files.
POST /forms/pdfengines/split
| Key | Description | Default |
|---|---|---|
| At least one PDF file. | required | |
| splitMode | Either intervals or pages. | required |
| splitSpan | Either the intervals or the page ranges to extract, depending on the selected mode. | required |
| splitUnify | Specify whether to put extracted pages into a single file or as many files as there are page ranges. Only works with pages mode. | false |
| pdfa | Convert the resulting PDF(s) into the given PDF/A format. | None |
| pdfua | Enable PDF for Universal Access for optimal accessibility. | false |
| metadata | The metadata to write (JSON format). | None |
| flatten | Flatten the resulting PDF(s). | false |
| userPassword | Password for opening the resulting PDF(s). | None |
| ownerPassword | Password for full access on the resulting PDF(s). | None |
| embeds | Files to embed in the generated PDF (repeatable). | None |
:::caution
Gotenberg currently does not validate the splitSpan value if splitMode is pages, as it depends on the selected
engine for the split feature:
See also the PDF Engines module configuration for more details.
:::
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/pdfengines/split \
--form files=@/path/to/pdf.pdf \
--form splitMode=intervals \
--form splitSpan=1 \
-o my.zip<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/pdfengines/split \
--form files=@/path/to/pdf.pdf \
--form splitMode=pages \
--form splitSpan=1-2 \
--form splitUnify=true \
-o my.pdf<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
This multipart/form-data route flatten PDF files.
POST /forms/pdfengines/flatten
| Key | Description | Default |
|---|---|---|
| At least one PDF file. | required |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/pdfengines/flatten \
--form files=@/path/to/pdf.pdf \
-o my.pdf<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
This multipart/form-data route accepts one or more PDF files and adds password protection to them.
POST /forms/pdfengines/encrypt
It accepts the following specific form fields:
| Key | Description | |
|---|---|---|
| files | At least one PDF file. | required |
| userPassword | Password for opening the resulting PDF(s). | required |
| ownerPassword | Password for full access on the resulting PDF(s). | None |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/pdfengines/encrypt \
--form files=@my.pdf \
--form userPassword=my_user_password \
--form ownerPassword=my_owner_password \
-o my.pdf<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
This feature enables the creation of PDFs compatible with standards like ZUGFeRD / Factur-X, which require embedding XML invoices and other files within the PDF.
This multipart/form-data route accepts one or more PDF files and embeds files into them.
POST /forms/pdfengines/embed
It accepts the following specific form fields:
| Key | Description | |
|---|---|---|
| files | PDF files to embed files into. | required |
| embeds | Files to embed in the PDF (repeatable). | required |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
```bash {3-5}
curl \
--request POST http://localhost:3000/forms/pdfengines/embed \
--form files=@invoice.pdf \
--form embeds=@data.xml \
--form embeds=@metadata.json \
-o my.pdf
```
<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '400 Bad Request', value: '400', }, { label: '503 Service Unavailable', value: '503', }, ] }>
Content-Disposition: attachment; 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-Traceheader. - See the Output Filename section for more information about the
Gotenberg-Output-Filenameheader.
This errors happens if one ore more form fields are invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
If a request doesn't complete within a specified duration, the API will respond with a 503 Service Unavailable status.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Service Unavailable
GET /health
HEAD /health
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl --request GET http://localhost:3000/healthcurl --request HEAD http://localhost:3000/health<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, { label: '503 Service Unavailable', value: '503', }, ] }>
{
"status": "up",
"details": {
"chromium": {
"status": "up",
"timestamp": "2021-07-01T08:05:14.603364Z"
},
"libreoffice": {
"status": "up",
"timestamp": "2021-07-01T08:05:14.603364Z"
}
}
}{
"status": "down",
"details": {
"chromium": {
"status": "up",
"timestamp": "2021-07-01T08:05:14.603364Z"
},
"libreoffice": {
"status": "down",
"timestamp": "2021-07-01T08:05:14.603364Z",
"error": "LibreOffice is unhealthy"
}
}
}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.
:::
This route exposes the metrics from other modules using the Prometheus format.
GET /prometheus/metrics
Currently, the metrics include:
| Metric | Description |
|---|---|
| {namespace}_chromium_requests_queue_size | Current number of Chromium conversion requests waiting to be treated. |
| {namespace}_chromium_restarts_count | Current number of Chromium restarts. |
| {namespace}_libreoffice_requests_queue_size | Current number of LibreOffice conversion requests waiting to be treated. |
| {namespace}_libreoffice_restarts_count | Current number of LibreOffice restarts. |
See the Prometheus module configuration for more information.
GET /version
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl --request GET http://localhost:3000/version<Tabs defaultValue="200" values={[ { label: '200 OK', value: '200', }, ] }>
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body:
8.25.1
:::info
Custom variants of Gotenberg may not print a strict semver version.
For instance, the live demo prints 8.25.1-live-demo-snapshot.
:::
GET /debug
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl --request GET http://localhost:3000/debugSee for instance https://demo.gotenberg.dev/debug.
:::info
This route is only available if the flag --api-enable-debug-route is set to true.
:::
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.
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/chromium/convert/url \
--header 'Gotenberg-Trace: debug' \
--form url=https://my.url \
-o my.pdfThe 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.
:::
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.
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
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.
:::
All multipart/form-data endpoints accept the following form field:
| Key | Description | Default |
|---|---|---|
| downloadFrom | URLs 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:
| Key | Description | Default |
|---|---|---|
| url | URL of the file. It MUST return a Content-Disposition header with a filename parameter. |
required |
| extraHttpHeaders | The extra HTTP headers to send to the URL (JSON format). | None |
| embedded | Whether this file should be embedded in the PDF (see Embed Files). | false |
<Tabs defaultValue="curl" values={[ { label: 'cURL', value: 'curl', }, ] }>
curl \
--request POST http://localhost:3000/forms/libreoffice/convert \
--form 'downloadFrom=[{"url":"http://url/to/file.com","extraHttpHeaders":{"X-Header": "value"}}]' \
-o my.pdf<Tabs defaultValue="requests" values={[ { label: 'Requests', value: 'requests', }, { label: '400 Bad Request', value: '400', }, { label: '403 Forbidden', value: '403', }, ] }>
GET http://url/to/file.com
Gotenberg-Trace: {trace}
User-Agent: Gotenberg
X-Header: value
This errors happens if at least one entry is invalid.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: {error}
This error happens if at least one of the given URLs is not authorized.
See the API module configuration for more details.
Content-Type: text/plain; charset=UTF-8
Gotenberg-Trace: {trace}
Body: Forbidden
:::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.
:::