HTTP API

Generate reports

HTTP API to merge the data in your template

Generate a report

/render/{templateId-or-versionId}

Renders a document by merging a template with the JSON data you provide: reference it by Template ID to always render the latest deployed version, by Version ID to pin an exact one, or skip uploading entirely and provide the template inline as base64 in the request body. By default the response is a JSON object with a renderId; add ?download=true to get the rendered file directly in this same call.

curl  --location --request POST 'https://api.carbone.io/render/{templateId-or-versionId}' \
      --header 'carbone-version: 5' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Bearer API_TOKEN' \
      --data-raw '{ "data": { "firstname": "John", "lastname": "Wick" }, "convertTo": "pdf" }'

Request header

{
  // REQUIRED - Pass your API token here (string)
  "authorization"       : "Bearer API_TOKEN",

  // REQUIRED - Content type (string)
  "content-type"        : "application/json",

  // REQUIRED - Pin the Carbone API major version to avoid breaking changes (string)
  "carbone-version"     : "5",

  // OPTIONAL - Webhook for asynchronous rendering, called by Carbone when the report is generated. More info (string)
  "carbone-webhook-url" : "https://your-url",

  // OPTIONAL - Webhook custom headers, where X is any header name. Ex: carbone-webhook-header-authorization, carbone-webhook-header-x-api-key. More info (string)
  "carbone-webhook-header-X" : "headers value",

  // OPTIONAL (v5.9.0+) - Custom authorization header for egress traffic. More info (string, max 512 chars)
  "carbone-egress-header-authorization" : "my-secret"
}

Request body

{
  // OPTIONAL - Data merged into the template with tags {d.}. Omit "data" to skip templating and only convert the file (tags left unchanged). Pass {} to run templating with an empty data-set (tags resolve to empty) (array|object)
  "data"         : {},

  // OPTIONAL - Output file format. More info (string|object)
  "convertTo"    : "pdf",

  // OPTIONAL - PDF converter engine, only relevant when "convertTo" is "pdf". "L" = LibreOffice (default), the best balance between performance and document compatibility. "O" = OnlyOffice, ideal for office documents (DOCX, XLSX, PPTX). "C" = Chromium, high-fidelity HTML-to-PDF conversion, perfect for web-based templates. "I" = Carbone ICE, the fastest DOCX to PDF conversion, done by Carbone itself. More info (string)
  "converter": "L",

  // OPTIONAL - Render without a pre-uploaded template ID by providing the template here as a base64 string. When used, put the keyword "template" in the URL instead of the ID (POST /render/template). More info (string)
  "template": "BASE64_ENCODED_TEMPLATE_CONTENT",

  // OPTIONAL - Convert document dates to a timezone. More info (string)
  "timezone"     : "Europe/Paris",

  // OPTIONAL - Locale of the generated document. More info (string)
  "lang"         : "en-us",

  // OPTIONAL - Extra data object that can be merged into the template with tags {c.} (object)
  "complement"   : {},

  // OPTIONAL - Predefined alias (string)
  "variableStr"  : "{#def = d.id}",

  // OPTIONAL - Static or dynamic file name returned in the `content-disposition` header (the output extension is appended automatically). More info (string)
  "reportName"   : "{d.date}",

  // OPTIONAL - List of enumerations to use with the convEnum formatter (object)
  "enum"         : {
    "ORDER_STATUS" : ["open", "close"],
    "SPEED" : {
      "10" : "slow",
      "20" : "fast"
    }
  },

  // OPTIONAL - Localization dictionary to use with Carbone tags {t( )}. More info (object)
  "translations" : {
    "fr-ca" : {"one":"un" },
    "es"    : {"one":"uno"}
  },

  // OPTIONAL - Currency source coming from your JSON data. More info (string)
  "currencySource" : "EUR",

  // OPTIONAL - Target currency for the generated document. More info (string)
  "currencyTarget" : "USD",

  // OPTIONAL - Exchange rates used for currency conversion. More info (object)
  "currencyRates"  : {
    "EUR" : 1,
    "USD" : 1.1403
  },

  // OPTIONAL - Force the report to recompute pagination and table of contents. Requires "convertTo" to be defined (boolean)
  "hardRefresh": false,

  // OPTIONAL - Generate multiple reports with one template and multiple JSON objects. More info (string)
  "batchSplitBy" : "d.items",

  // OPTIONAL - From v5+, the output format for batch processing. More info (string)
  "batchOutput" : "zip",

  // OPTIONAL - Customize each file name inside a ZIP batch export, Carbone tags accepted. More info (string)
  "batchReportName" : "report-{d.id}",

  // OPTIONAL - Pre-release feature level for this render. Overrides the server default. More info (number)
  "preReleaseFeatureIn" : 5000000
}

Request Query Parameters

Parameter Type Required Description
download Boolean No true: returns the generated document directly as a file stream (the Content-Type reflects the output format). The file is not stored on Carbone servers and no renderId is issued, so there is no need to call GET /render/{renderId} (more info).
false: returns a JSON object with a renderId; use GET /render/{renderId} to download the file in a second call (see Download Reports).

Response

On success, by default a JSON response with content-type application/json containing the renderId is returned, which is a unique identifier for the generated document. If the query parameter download=true is used, the response body will be the file itself, and the content type will reflect the type of the generated document.

Status Code Body
200 { "success" : true, "data": { "renderId": "" } }
or File Stream, if the query parameter download=true is used.
400 { "success" : false, "error" : ""Content-Type" header is not "application/json""}
400 { "success" : false, "error" : "Invalid templateId"}
401 { "success" : false, "error" : "Unauthorized, please provide a correct API key on the "Authorization" header"}
404 { "success" : false, "error" : "Template not found"}
413 { "success" : false, "error" : "Content too large, the JSON size limit is X MB"}
422 { "success" : false, "error" : "Missing "data" property in body"}
Note: From carbone-version: 5, data is optional: omitting it converts the file without templating (tags left unchanged). This error applies to carbone-version: 4 only.
500 { "success" : false, "error" : "Error while rendering template"}
500 { "success" : false, "error" : "Error while setting up the webhook"}

Providing a template

Every render call needs a template. There are two ways to provide one:

Upload it first (template ID): Upload your template once with POST /template, which returns a templateId (and a versionId per version). Reference that ID in the render URL: POST /render/{templateId-or-versionId}. Best when the same template is reused across many renders. See Upload a template.

Provide it inline (base64): Skip the upload and send the template directly in the request body as a base64-encoded string in the template field, using the keyword template in the URL instead of an ID: POST /render/template. The template is not stored on Carbone's servers, so a single API call is enough. Best for one-off or dynamically generated templates.

Direct download

The POST /render/{templateId-or-versionId} endpoint accepts a ?download=true query parameter to download the rendered report directly.

When this option is used, the file is not stored on our servers. A single API call is enough to download the file. There is no need to call GET /render/{renderId}.

When download=true, the response shape depends on the outcome:

  Content-Disposition: 'attachment; filename="report.pdf"'
  Content-Type: 'application/pdf'

Output filename

With Carbone, even the generated report filename is a template!

Define the reportName option in the request body to set a custom filename. It accepts a static string or Carbone tags for dynamic filenames, for example:

{
  "data": { "company": "Acme", "date": "2026-06-29" },
  "reportName": "{d.company}-{d.date}"
}

Carbone appends the output file extension automatically (based on the generated format), so do not include it in reportName. The resulting filename is returned in the content-disposition header when the report is downloaded, for example Acme-2026-06-29.pdf.

Output file type

By default, if convertTo is undefined, the output file type is the same as the input template file type.

The table below lists all accepted convertTo values according to the input template file type.

And some output file types can have additional options. See the dedicated documentation

Template Type convertTo
document pdf, docx, odt, bib, doc, doc6, doc95, docbook, docx7, fodt, html, latex, ooxml, ott, psw, rtf, stw, sxw, text, txt, uot, xhtml, jpg, jpeg, png, epub, md, svg, webp, pages
spreadsheet pdf, xlsx, ods, csv, dbf, dif, fods, html, ooxml, ots, pxl, slk, stc, sxc, uos, xhtml, xls, xls5, xls95, xlt, xlt5, xlt95, numbers, parquet
presentation pdf, pptx, odp, bmp, emf, eps, fodp, gif, html, jpg, met, odg, pbm, pct, pgm, png, ppm, pwp, ras, sti, svg, svm, swf, sxi, tiff, uop, wmf, xhtml, otp, potm, pot, pps, ppt, webp
web pdf, etext, html10, html, txt, text10, text
graphics bmp, emf, eps, fodg, gif, html, jpg, met, odd, otg, pbm, pct, pdf, pgm, png, ppm, ras, std, svg, svm, swf, sxd, tiff, wmf, xhtml, webp, pub, cdr

Notes:

Multi-timezone

Some date formatters like formatD or formatI adapt the inserted date in the template according to the timezone.

List of accepted timezone (Column TZ identifier) : https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

Multi-language

Many text, date, and number formatters like formatN, formatD, formatI adapt their output in the template according to the locale.

Also, the lang parameter is used to select the corresponding translations when the Carbone tag {t()} is used for multi-lingual reports.

List of supported locales: https://github.com/carboneio/carbone/blob/master/formatters/_locale.js

You can support multiple languages in your report by using translations formatters.

Multi-currency

You can create templates that adapt their currency depending on the locale.

The formatC formatter converts amounts from a source currency to a target currency using the exchange rates you provide:

Learn more

Pre-release features

Sets the pre-release feature level for this render only. Only features and fixes introduced up to the given tag are applied. Higher tags stay disabled. This overrides the global configuration default, and can itself be overridden by the tag in the template.

Use it to opt into upcoming features early, or to keep Carbone v5 behaving like v4 during a migration.

See Pre-release features and Force Carbone v5 to behave like v4.

Converters

Document conversion (for example DOCX to PDF) is handled by a dedicated converter engine. From v5, the converter option in the request body selects which engine Carbone uses.

Choosing a converter

converter Engine Recommended for Notes
L LibreOffice (default) DOCX/XLSX/PPTX, ODT/ODS/ODP/ODG and MD to PDF Best balance between performance and document compatibility. Supports all PDF options.
O OnlyOffice DOCX/XLSX/PPTX to PDF Alternative for office documents. Only Security and Watermark options are supported (see limitations).
C Chromium HTML to PDF/JPG/PNG/WEBP High-fidelity HTML-to-PDF conversion, perfect for web-based templates. Only Security and Watermark options are supported (see limitations).
I Carbone ICE DOCX to PDF Instant Converter Engine. The fastest and the most faithful way to turn a DOCX into a PDF: Carbone draws the PDF itself, no office suite involved, and the output is matched pixel-for-pixel to the PDF saved from Word. Only Watermark options are supported (see limitations).

OnlyOffice limitations

Chromium limitations

ICE limitations

Carbone ICE is a new engine, released in v5.14.0. This first release covers the DOCX to PDF path, and the list below is what it does not handle yet. Most of it is on the roadmap.

Formats

PDF options

Document features not yet supported

The following are ignored when they appear in the template, the rest of the document still converts (the list may not be exhaustive):

Fonts

PDF options

Options can be passed for PDF conversion. In this case, convertTo has to be an object with formatName set to pdf and formatOptions with options.

{
  "convertTo" : {
    "formatName"    : "pdf",
    "formatOptions" : {
      "EncryptFile"          : true,
      "DocumentOpenPassword" : "QWERTY1234",
      "Watermark"            : "Watermark Carbone.io"
    }
  }
}

The following options can be passed to formatOptions:

Option name Type Default Description
General
SelectPdfVersion integer 0 Specifies the PDF version to emit.
0 : PDF 1.6 Standard.
1 : PDF/A-1 (ISO 19005-1:2005).
2 : PDF/A-2 (ISO 19005-2:2011).
3 : PDF/A-3 (ISO 19005-3:2012).
4 : PDF/A-4 (ISO 19005-4).
15 : PDF 1.5 Standard.
16 : PDF 1.6 Standard.
17 : PDF 1.7 Standard.
20 : PDF 2.0 Standard.
ConvertOOoTargetToPDFTarget boolean false Renames .od[tpgs] links to .pdf in exported PDF, leaving source untouched.
ExportFormFields boolean true Specifies whether form fields are exported as widgets or only as fixed print representation.
ExportLinksRelativeFsys boolean false Exports file system hyperlinks as relative to source document.
ExportNotes boolean true Specifies if notes are exported to PDF.
ExportNotesPages boolean false Specifies if notes pages are exported to PDF (Impress only).
FormsType integer 0 Format for PDF form submission:
0: FDF
1: PDF
2: HTML
3: XML
IsAddStream boolean false Adds stream containing original document for archiving (PDF Import only).
IsSkipEmptyPages boolean false Suppresses auto-inserted empty pages (Writer only).
UseTransitionEffects boolean true Exports slide transitions to PDF (Impress only).
Security
DocumentOpenPassword string Password to open PDF file (with "EncryptFile" enabled).
EncryptFile boolean false Encrypts the PDF file with AES-256; the "DocumentOpenPassword" is required to open it. The document properties (Title, Author, Subject, and the other Info strings) are encrypted as well, so they cannot be read without the password.
PermissionPassword string Password for restricted permissions if "RestrictPermissions" enabled.
RestrictPermissions boolean false Enables restricted permissions in the PDF document. Must be used with "PermissionPassword".
Changes integer 4 What changes are allowed in the PDF.
0: None
1: Insert/delete/rotate pages
2: Fill forms
3: Comment/fill forms
4: Any except page extraction.
Requires "RestrictPermissions": true and "PermissionPassword".
EnableCopyingOfContent boolean true Allows copying content to other documents.
Requires "RestrictPermissions": true and "PermissionPassword".
EnableTextAccessForAccessibilityTools boolean true Allows extraction for accessibility tools.
Requires "RestrictPermissions": true and "PermissionPassword".
Printing integer 2 Allowed printing:
0: None
1: Low resolution (150 DPI)
2: Max resolution.
Requires "RestrictPermissions": true and "PermissionPassword".
Compression & Quality
MaxImageResolution integer 300 Reduce images to this DPI if "ReduceImageResolution" is true. Possible: 75, 150, 300, 600, 1200
Quality integer 90 JPG export quality (1-100). Lower = higher compression/larger file; higher = better quality/smaller file.
ReduceImageResolution boolean false Reduces image resolution to "MaxImageResolution".
UseLosslessCompression boolean true Use PNG (lossless) or JPEG for graphics.
Watermark
Watermark string Draws text watermark on every page.
Watermarks array Array of up to 4 watermark objects (see Watermark options).
Accessibility
UseTaggedPDF boolean false Creates PDF with special tags (Tagged PDF).
PDFUACompliance boolean false Enables PDF/UA Universal Accessibility standard (ISO 14289).
AllowDuplicateFieldNames boolean false Allows export of multiple form fields with same name (OOo 3.3+).
View/Appearance
CenterWindow boolean false Opens PDF centered on screen.
DisplayPDFDocumentTitle boolean true Shows document title in viewer window.
ExportBookmarks boolean true Exports bookmarks to PDF.
ExportBookmarksToPDFDestination boolean false Exports bookmarks as named destinations.
FirstPageOnLeft boolean false Used with "PageLayout": odd first page appears left.
HideViewerMenubar boolean false Hides PDF viewer menubar.
HideViewerToolbar boolean false Hides PDF viewer toolbar.
HideViewerWindowControls boolean false Hides PDF viewer window controls.
InitialPage integer 1 Page number on which PDF opens.
InitialView integer 0 Display mode on open:
0: none
1: outline pane
2: thumbnail pane.
Magnification integer 0 Open action:
0: default
1: fit page
2: fit width
3: fit width of bounding box
4: Zoom set by "Zoom".
OpenBookmarkLevels integer -1 Number of bookmark levels opened on startup (-1 = all).
OpenInFullScreenMode boolean false Opens PDF in full screen.
PageLayout integer 0 Page layout:
0: reader default
1: single
2: one column
3: two columns (see "FirstPageOnLeft").
PageRange string Range of pages to include. Example : "1-5"
PDFViewSelection integer 0 PDF viewing:
0: all links as URI
1: PDF reader only (not for PDF/A-1)
2: Internet browser with plugin (see "ExportBookmarksToPDFDestination").
ResizeWindowToInitialPage boolean false Resizes viewer to first page at open.
Zoom integer 100 Zoom percent if "Magnification" is 4.
The availability of PDF export options varies by converter.
Option Category LibreOffice Chrome OnlyOffice Carbone ICE
All PDF Options
Security Options
Watermark Option

For the most advanced PDF controls, use the LibreOffice converter.
If you are using Chrome or OnlyOffice, only "Security" and "Watermark" options are supported.
If you are using Carbone ICE, only "Watermark" options are supported.

JPG/PNG options

It is possible to export jpg or png images with options (list below).

Export Types Option name Type Default Description
jpg / png PixelWidth Number Document width Image width as pixels
jpg / png PixelHeight Number Document height Image height as pixels
jpg / png ColorMode Number 0 0 Colors, 1 Greyscale
jpg Quality Number 100 From 1 (low quality, high compression, low size) to 100 (high quality, low compression, high size)
png Compression Number 0 From 0 (compression disabled) to 9 (high compression, low size)
png Interlaced Number 0 0 not interlaced, 1 interlaced (higher size)
png Translucent Number 0 0 no transparent background, 1 transparent background

Here is an example of exporting a JPG image with options:

{
  "convertTo": {
    "formatName" : "jpg",
    "formatOptions": {
      "Quality"   : 50,
      "ColorMode" : 1
    }
  }
}

CSV options

During CSV conversion, the following elements can be changed: separator, delimiter and the character set. convertTo has to be an object with formatName set to csv and formatOptions with options. characterSet can be one of these options : https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_Options

{
  convertTo : {
    formatName    : 'csv',
    formatOptions : {
      fieldSeparator : '+',
      textDelimiter  : '"',
      characterSet   : '76' // utf-8
    }
  }
}

Watermark options

Carbone supports adding one or multiple text watermarks to every page of a generated PDF. Watermarks are defined inside the formatOptions object when convertTo is set to pdf.

Two fields are available:

{
  "convertTo": {
    "formatName": "pdf",
    "formatOptions": {
      // Legacy: single centered watermark (backward compatible)
      "Watermark": "CONFIDENTIAL",
      // New in v5.3.0: array of watermark objects
      "Watermarks": [
        {
          "text": "Confidential - Page {#PAGE_NUMBER} / {#PAGE_TOTAL}",
          "anchor": "topLeft",
          "offsetX": 10,
          "offsetY": 10,
          "rotation": -45,
          "color": "#000000",
          "size": 64,
          "opacity": 0.21,
          "font": "Helvetica",
          "fromPage": 1,
          "toPage": 10
        }
      ]
    }
  }
}

Watermark object properties

The following properties apply to each watermark object defined inside the Watermarks array. They are not available on the legacy Watermark string field.

All properties except text are optional.

Property Type Default Description
text string Required. The watermark label. Between 1 and 2000 characters. Supports {#PAGE_NUMBER} and {#PAGE_TOTAL} variables for dynamic page numbering.
anchor string center Position on the page. Accepted values: topLeft, top, topRight, left, center, right, bottomLeft, bottom, bottomRight.
offsetX number 0 Horizontal offset in points (pt) from the anchor. In PDFs, the origin is bottom-left, so positive values move right.
offsetY number 0 Vertical offset in points (pt) from the anchor. Positive values move up.
rotation number 45 for center, 0 for others Rotation angle in degrees, between -360 and 360. For non-center anchors, only 0, 90, or -90 are allowed.
color string #000000 Watermark text color in #RGB or #RRGGBB format (e.g. #ff0000, #f00).
size number Auto for center, 12 for others Font size in points (pt), between 1 and 2000.
opacity number 0.1 for center, 1 for others Opacity between 0 (invisible) and 1 (fully opaque).
font string Helvetica Font family. Accepted values: Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique, Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique, Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic.
fromPage integer 1 First page (1-based) on which the watermark is applied.
toPage integer Last page Last page (1-based) on which the watermark is applied. Defaults to all remaining pages.

Dynamic page numbering

Use {#PAGE_NUMBER} and {#PAGE_TOTAL} in the text field to insert the current page number and total page count into the watermark.

{
  "text": "Draft - Page {#PAGE_NUMBER} of {#PAGE_TOTAL}"
}

Asynchronous jobs

For large reports or long-running renders, we recommend using the asynchronous rendering system. This method offers a longer rendering timeout of 5 minutes, surpassing the 60-second limit of the synchronous API.

Carbone will notify your application/service at a custom URL as soon as the document is generated.

How to use this system?

  1. Prepare your server to accept POST requests at a webhook endpoint. For experimentation, https://webhook.site/ is a convenient option.
  2. Send a request to POST /render/{templateId-or-versionId} with the HTTP header carbone-webhook-url: https://my-custom-webhook/my-custom-url
  3. (From version 4.23.0) If your webhook url needs authentication or a specific header, you can configure it by adding the header carbone-webhook-header-X. Ex : carbone-webhook-header-authorization: my-secret
  4. Upon report completion, Carbone will invoke your webhook endpoint, sending a JSON object that includes the renderId. The response object is the same as the response from the synchronous method.

Carbone automatically retries (one retry) to call your webhook for the following errors:

Egress authentication

(From version 5.9.0) When Carbone makes outbound calls during a render, to your webhook, to a dynamic image URL, or to a file fetched by appendFile, you can set the authorization header on all of them with the carbone-egress-header-authorization request header.

For example, sending carbone-egress-header-authorization: my-secret makes Carbone add authorization: my-secret to every egress request (webhook, dynamic image, appendFile, and so on).

Batch processing

Since version 4.20.0, Carbone generates several reports in a single POST /render call, from one template and an array of data: one report per object. The reports come back in a ZIP archive, or concatenated into a single PDF. This is the way to produce personalised documents in bulk, such as invoices for a list of customers or letters for a list of recipients.

Requirements

Batch processing runs when all of the following are true:

Request example

{
  "data"         : {
    "letters" : [
      { "id" : 1, "name" : "Guillaume" },
      { "id" : 2, "name" : "David"     },
      { "id" : 3, "name" : "Steeve"    }
    ]
  },
  // Each report is converted to PDF, and the archive holds the three of them
  "convertTo"        : "pdf",
  "batchSplitBy"     : "d.letters",
  "batchOutput"      : "zip",
  "batchReportName"  : "letter-{d.id}"
}

Options

Option Description
batchSplitBy Required. How the data is split into reports. "d" when data is itself an array of objects, or "d.myArray" to select a direct child array of data.
batchOutput From v5, the output file type. "zip" (default) returns an archive of all the reports, "pdf" returns a concatenation of the generated PDFs, and requires convertTo to be "pdf".
batchReportName Name of each file inside the ZIP, Carbone tags accepted. Ignored when batchOutput is "pdf", since the reports are merged into a single document. See the naming rules below.

Writing the template

Each report receives one object of the array. There are two ways to write the tags, and Carbone chooses between them by looking at the first {d. tag of the template. Both examples below use the request of the previous section, splitting d.letters into three reports.

1. Direct child access. The tags address the object directly, as if data were that single object. This is the way to write a new template, and the one the request above uses.

{d.id} {d.name}

With "batchReportName" : "letter-{d.id}", the archive holds letter-1.pdf containing 1 Guillaume, letter-2.pdf containing 2 David, and letter-3.pdf containing 3 Steeve.

2. Array access. The tags keep the full path of the array, loop included, and Carbone hands each report an array holding its own single object, so the loop renders one row. Use it to reuse, unchanged, a template already designed to list the whole array. The i+1 line closes the loop, as in any Carbone template.

{d.letters[i].id}    {d.letters[i].name}
{d.letters[i+1].id}

The report data keeps this shape, so the file name follows it too: "batchReportName" : "letter-{d.letters[0].id}" gives the same three files, where letter-{d.id} would render an empty name.

The two approaches cannot be mixed, and mixing them raises no error: in a template starting with {d.name}, a {d.letters[i].id} loop placed after it renders empty.

File names inside the ZIP

batchReportName names each file of the archive and accepts Carbone tags, so every report carries its own name. It is resolved with the data of its own report, so its tags follow the approach used by the template, as shown above.