The API

Templates

Templates are reusable documents you build once in the visual editor and fire off as many times as you want through the API, sending only the data. It is the recommended path for any recurring document: invoices, contracts, receipts, certificates, posts.

The lifecycle of a template

1. Create

Build the layout in the visual editor and add {{...}} variables where the data goes.

2. Save

Saving in the editor immediately gives the template a stable slug — the identifier the API uses.

3. Use

Call /v1/render with the slug in template and your data in data.

1. Create in the editor

In the Renderly visual editor you design the document like in a design app: text blocks, images, tables, QR codes and charts. Where the content should change with each issuance, you place a variable in the format {{caminho.do.valor}}. This model is saved as a DocumentModel — a structured representation of the document, not just HTML.

Why a model and not just HTML
Because it is structured, the model can resolve tables that iterate over arrays, generate QR codes from the data and draw charts — things raw HTML cannot do on its own. When the model is compatible, it still renders through the native engine (deterministic, no browser).

2. Save and the slug

As soon as you save it in the editor, the template gets a slug — a short, stable string (e.g. fatura, recibo, post-instagram). The slug is what you pass in the template field of the API, and it works right away — no separate publish step. It is scoped to your organization: two different customers can each have a fatura template with no conflict.

ConceptWhat it isWhere it appears
slugStable, readable identifier of the templateIn the body: "template": "fatura"
DocumentModelStructured representation of the documentGenerated by the editor, compiled on the server
variávelInjection point {{...}}In the layout, filled by data

3. Use via the API

With the template saved, the call is minimal: the slug and the data. There is no need to resend the layout each time.

curl — render an invoice via template
curl -X POST https://api.renderly.dev/v1/render \
  -H "Authorization: Bearer rndr_live_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "invoice",
    "data": {
      "customer": "Acme Inc",
      "issued_at": "2026-06-15",
      "items": [
        { "description": "Pro plan (monthly)", "qty": 1, "amount": "$99.00" },
        { "description": "Extra user",          "qty": 3, "amount": "$45.00" }
      ],
      "total": "$234.00"
    }
  }' --output invoice.pdf
node
const res = await fetch("https://api.renderly.dev/v1/render", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.RENDERLY_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    template: "invoice",           // slug of the published template
    data: invoice,                 // your data; fills {{...}} and tables
    format: "pdf",
  }),
})

Minimal example

Simple templates need only the scalars their variables reference:

application/json
{
  "template": "receipt",
  "data": { "amount": "$50.00", "payer": "John" }
}
Nonexistent template → 404
If the slug does not exist in your organization, the API responds 404 template_not_found. If it exists but has no content, it is 422 template_empty. Check the slug in the Dashboard.

Variables in the template

Variables follow the same syntax everywhere in Renderly. In the template path, beyond scalar substitution, they feed tables (via a data-source field), QR codes and charts.

SyntaxEffect
{{cliente}}Inserts the value, with HTML escaping (safe).
{{{cliente}}}Inserts the raw value, without escaping (for trusted HTML).
{{cliente.nome}}Accesses a nested path inside data.
{{status|pendente}}Uses “pending” as a fallback if the value is missing.

Tables iterate over an array from data (via a source field, the dataField), and each row references the columns of that item. The full reference for syntax, tables, QR and charts is in Data & variables.

Template or raw HTML?

Use template when…Use html when…
The document repeats (invoices, receipts)It is a one-off layout or a prototype
There are data-driven tables, QR or chartsYou already generate the HTML elsewhere
You want to version the layout outside your codeYou want full control of the markup on that call
You want the native engine when possibleYou need arbitrary CSS/JS rendered by Chromium

Versioning and best practices

PracticeWhy
Short, stable slugThe slug becomes a contract with your code — avoid renaming it.
Fallbacks on optional variablesAvoids holes in the document when a value is missing.
Validate the data on your sideThe API trusts the shape you send to the template.
Test with real data before relying on itTables and charts only reveal problems with real volume.
Next
Data & variables
{{x}}, {{{x}}}, fallback, tables via dataField, QR and charts.