Skip to content

Render a report by name

The Reports API is the simplest way to get a document: send a template’s name and your data, and the response is the finished PDF or XLSX file. To render one specific template version or your own HTML, use the Renders API.

  • An API key with render:create, render:read and template:read.
  • A published template, such as one called Invoice; see Build a template.
  • curl or a client library, set up as in the quickstart.

Send the template’s name and your data. The response is the file:

Terminal window
curl "$PDF_URL/v1/reports/render" \
-H "x-api-key: $API_KEY" \
-H "content-type: application/json" \
--fail-with-body -o invoice.pdf \
-d '{
"format": "pdf",
"template": { "name": "Invoice" },
"data": {
"invoice": { "number": "INV-2041" },
"customer": { "name": "Marta Tamm" }
}
}'

data holds the fields your template uses. The template’s current published version is always used, so clicking Publish in Studio changes your next document without a code change.

template takes exactly one of these:

template Matches
{ "name": "Invoice" } Templates with that name, ignoring case.
{ "id": "..." } The template with that ID.
{ "shortid": "..." } Templates with that shortid. Only imported templates have one.
  • Only templates that render the requested format count. If several match, a published one wins, then the most recently updated.
  • Two templates in different folders can share a name; a request by that name then gets the one edited last. Give templates distinct names, or render by id.
  • No match, or a match that was never published, answers 404 NOT_FOUND.

locale is a language tag such as de-CH. It picks the template’s translation file, a spreadsheet’s number and date formats, and the language recorded in the PDF. Without it, en-US is used, not the locale in the template’s page.json. See Translations.

Success is 200 with the file as the body: application/pdf, the image’s type for an image, or application/vnd.openxmlformats-officedocument.spreadsheetml.sheet for XLSX. Any other status returns a JSON error whose message says what to fix (curl’s --fail-with-body saves it in place of the file; the clients throw it). The error format is in the HTTP API.

Status Code When What to do
400 BAD_REQUEST A field is wrong or unknown, or pdf or test is sent with "format": "xlsx". Fix the request as message says.
404 NOT_FOUND No published template with that name, ID or shortid renders this format. Check the name, the format, and that the template is published.
422 RENDER_FAILED The PDF render failed or was cancelled. error.renderId names it. Read the render to see why. Do not retry unchanged.
429 RATE_LIMITED The workspace is at its render allowances, or is preparing too many reports at once. Send it again later, after Retry-After when it is sent.
504 RENDER_TIMEOUT The PDF was still rendering when the Reports API wait ran out. error.renderId names it. Follow it with GET /v1/renders/{renderId}; do not start another.

Keep your HTTP client’s timeout above the Reports API wait. The clients’ defaults already are.

A PDF is an ordinary render: it counts against your render allowances, appears in the render list and sends webhooks. An XLSX file creates no render and sends no webhooks, but is still refused while the workspace is at its allowances.

Add "test": true (Test = true in .NET, test=True in Python) for a free test PDF with a diagonal “TEST” watermark on every page. It doesn’t count against your render allowances; see test renders. PDF and images only.

To retry a PDF request safely, send an Idempotency-Key header (idempotencyKey in the .NET and TypeScript clients, idempotency_key in Python). A repeat with the same key returns the first render instead of making a second one; see idempotency keys. It has no effect on XLSX.

pdf overrides the template’s page and PDF settings for this request only. Leave a field out to keep the template’s value.

Terminal window
curl "$PDF_URL/v1/reports/render" \
-H "x-api-key: $API_KEY" \
-H "content-type: application/json" \
--fail-with-body -o invoice.pdf \
-d '{
"format": "pdf",
"template": { "name": "Invoice" },
"data": { "invoice": { "number": "INV-2041" } },
"pdf": {
"orientation": "landscape",
"margins": { "topMm": 10, "bottomMm": 10 }
}
}'

What pdf can change:

  • Paper: pageSize (A3, A4, A5, Letter, Legal or a size in millimetres), orientation, margins (sides you leave out keep their value) and preferCssPageSize. See Build a template.
  • Pages: pageRanges keeps only some pages, such as 1-5, 8, 11-; page numbers still count the whole document. operations replaces the template’s pages from other templates and PDF files, and [] adds none; see Combine templates.
  • See-through content: opaqueFills draws CSS opacity and translucent colours at full strength.
  • Watermark: watermark draws text such as DRAFT across every page; see Add a watermark.
  • PDF standards and security: metadata, pdfa, pdfua, attachments, encryption and signature. metadata, encryption and signature apply over the template’s values one field at a time. See PDF standards and security.

Values in pdf are used as written: only the template’s own values fill {{path}} placeholders. Every field and its limits are in the API reference.

pdf.watermark draws text such as DRAFT, COPY or PAID across every page, in front of the content. Only text is required.

Terminal window
curl "$PDF_URL/v1/reports/render" \
-H "x-api-key: $API_KEY" \
-H "content-type: application/json" \
--fail-with-body -o invoice.pdf \
-d '{
"format": "pdf",
"template": { "name": "Invoice" },
"data": { "invoice": { "number": "INV-2041" } },
"pdf": { "watermark": { "text": "COPY" } }
}'

Its colour, opacity, angle and size can be changed too; the fields and their defaults are under Watermarks. Like every pdf option, it is for PDFs and images only: an Excel request with pdf answers 400 BAD_REQUEST.

Set "format" to "png", "jpeg" or "webp" to get one page of a PDF template as an image. image picks the page and the width:

Terminal window
curl "$PDF_URL/v1/reports/render" \
-H "x-api-key: $API_KEY" \
-H "content-type: application/json" \
--fail-with-body -o invoice.png \
-d '{
"format": "png",
"template": { "name": "Invoice" },
"data": { "invoice": { "number": "INV-2041" } },
"image": { "page": 1, "width": 400 }
}'

The response is the image, as image/png, image/jpeg or image/webp. The image fields, the size of a social card and the limits are under Render an image. pdf options, such as a watermark, and test work as for a PDF; encryption, signature, attachments, pdfa and pdfua answer 400 BAD_REQUEST. An image is an ordinary render and counts as one document.

Set "format": "xlsx" (ReportFormat.Xlsx in the .NET and TypeScript clients, ReportFormat.XLSX in Python). The response is the .xlsx file. Which templates render which format:

Template Renders
Spreadsheet template (sheets.json) XLSX or PDF
Workbook template (uses an .xlsx workspace file) XLSX only
HTML or component template PDF only

A template that renders PDF also renders images. Asking for a format the template does not render answers 404 NOT_FOUND. pdf options and test are for PDFs and images only.

GET /v1/reports lists every template in the workspace, sorted by name, with the formats it renders.

Terminal window
curl "$PDF_URL/v1/reports" -H "x-api-key: $API_KEY" --fail-with-body
{
"items": [
{
"id": "0f5b7c1e-6a43-4f7e-9d1b-1c2a3b4c5d6e",
"name": "Invoice",
"formats": ["pdf"],
"published": true,
"folderPath": "Invoices"
}
]
}

Use id or name in template. published says whether the template has a published version; only published templates render. formats comes from the published version, or from the draft if it was never published. Imported templates also have a shortid.

GET /v1/reports/data-schema returns the data a published template expects, as JSON Schema, so you can generate types or check your data. Pass format and one of name, id or shortid; the template is chosen the same way as for a render.

Terminal window
curl -G "$PDF_URL/v1/reports/data-schema" \
-H "x-api-key: $API_KEY" \
--fail-with-body \
--data-urlencode "format=pdf" \
--data-urlencode "name=Invoice"

How the schema is built:

  • Spreadsheet templates: from the sections and columns. Each section’s data is a required array; each column is an optional value typed by its format.
  • Other templates: from the sample data published with the version. A property is required only when every sample object has it. Without sample data the schema is {}.

Renders are not checked against the schema, and values a template script adds do not appear in it.

Send one request per document; they can run in parallel. A request answered with 429 RATE_LIMITED can be sent again later, and the clients do this for you (3 times by default).

The Reports API has no batches. To create many PDFs with one request, use a batch in the Renders API. Each batch item names a template version or sends its own document, not a template name.