PDFPipe

What you send / POST /v1/templates, then template_id

Store an HTML template and render it with data

Upload the markup once, then render it by id with a data object, so the template lives on the server rather than in every caller.

What it is for

For documents whose layout changes on a different schedule from the code that produces them. An invoice template that finance wants to change should not require a deploy, and a caller that only sends data does not have to hold a large HTML string in memory or in its request body.

The request

Sent to POST /v1/templates, then template_id. Everything else on this page is what happens around it.

bash
# Once: store the template.
curl -X POST https://api.pdfpipe.xyz/v1/templates \
  -H "Authorization: Bearer $PDFPIPE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "invoice", "html": "<h1>{{customer.name}}</h1>" }'

# Then: render it with data.
curl -X POST https://api.pdfpipe.xyz/v1/pdf \
  -H "Authorization: Bearer $PDFPIPE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl_...",
    "data": { "customer": { "name": "Calder Interiors Ltd" } }
  }' \
  --output invoice.pdf

The actual limits

Read from the implementation rather than remembered, so these are the numbers the API enforces rather than the ones a roadmap intends.

  • Placeholders are double braces for a value that is HTML-escaped, and triple braces for a value inserted raw. Dotted paths resolve into nested objects.
  • Substitution is a single pass, so a value inserted through a triple brace is not re-scanned for placeholders. That is a deliberate defence rather than a limitation: without it, data containing braces would be a template injection.
  • The rendered result is checked against the same 5 MB ceiling after substitution, not before, so a small template with a large data object can still exceed it.
  • Templates are scoped to the API key that created them.

What failure looks like

An unknown template_id returns 404. Sending template_id together with html or url returns 400. A placeholder whose path does not exist in the data renders as an empty string rather than as an error, which is convenient and is also how a document ships with a missing customer name.

When this is the wrong tool

When the markup is generated by the same code that calls the API. Storing a template server-side splits the document across two systems that then have to be versioned together, and the failure mode is a template updated without the data shape that fills it. If the template lives in your repository next to the code that populates it, leave it there.

Frequently asked

Is stored templates available on the free plan?

Yes. There is no plan gate on this one: it behaves the same on the free plan as on every paid plan, and the only limit that applies is the monthly document allowance.

Where do these numbers come from?

The running implementation. Every figure on this page, from payload ceilings to per-plan limits, is what the API enforces today rather than what a specification says it should. If one of them is wrong, the API is the thing to believe.

Related capabilities

Options that come up in the same request, and one from each of the other groups.

100 free documents a month, and a playground that runs a real render without a key.