For developers
From payload to PDF in one request.
The template is already built. You post JSON to our endpoint and get a render result back, which contains the status, a signed download link, and the PDF bytes when you ask for them — synchronously, or as a queued, webhook-notified job for batches. All of this is available through six native SDKs or a plain REST API.
{
"documents": [{
"customer":
"Acme Inc.",
"total": 1240.00,
"lines": [ … ]
}]
}Quickstart
Render your first PDF in a handful of lines
Every SDK follows the same shape, so the sample below is the whole integration in any of them. Pick your stack:
var pagr = new PagrClient( Environment.GetEnvironmentVariable("PAGR_KEY")); var result = await pagr.RenderAsync(templateId, new[] { new { customer = "Acme Inc.", total = 1240.00m, lines = order.Lines } }); // result.Status, result.Documents[0].ViewUrl
The handoff
You get the full markdown specs about the template
Every bound field, its type, whether it is always required or conditional, an example value and the formatting the template applies are all listed. Hand it to your AI assistant to draft the data mapping, or just read it and be done in ten minutes.
# epc certificate — data model · v1 (draft) ## Root object | Field | Type | Required | Example | |---------------------|--------|-------------|--------------| | `certificateNumber` | string | Always | "20240117-1" | | `postalCode` | string | Always | "9000" | | `buildingPhoto` | image | Always | "https://…" | | `energyScore` | number | Always | 148 | | `expiryDate` | date | Always | "2035-01-17" | | `remarks` | string | Conditional | null | `energyScore` prints as "148 kWh/m²", `expiryDate` as "17 January 2035" — send raw values, the template formats. … 4 more fields omitted.
Generated from the template, not from memory
It is read out of the template that renders, so it cannot go stale. When the document changes, generate the spec again and compare it with the previous one to see exactly which fields moved.
Required vs conditional, stated explicitly
“Always” means the field is bound outside any condition. “Conditional” means it sits inside a conditional element or a ternary branch and may legitimately be absent.
Send raw values
A number is a number and a date is an ISO date. The template owns formatting, so you are not string-building on your side.
Images by URL
Send a URL for photos and logos. Barcodes and QR codes you don't send at all — the template generates them from the value in your JSON.
SDKs
Six clients, one behaviour
Every SDK is written to feel native to its language and is held at parity. Each one is on GitHub — pick a language to open its repository.
Bulk generation
Volume goes through code, not through the UI
Bulk rendering means JSON to the API — a documents array in a single call, or an async job over a larger set. It is the version of bulk that still behaves when one record is malformed at 2am.
One document, right now
Call render and the answer comes back in the same response — status, page count and a signed download link, with the PDF bytes inline when you ask for them. Use it in a request path: a user clicks “download invoice” and the document arrives.
Fire and forget at scale
Queue a job and move on. When it completes you get a signed, timestamped webhook — HMAC-SHA256, rotation-aware — instead of being asked to trust a response.
Straight to the user
Ask for the raw PDF and render without persistence, and the bytes go straight through to your response. Nothing to clean up, nothing sitting in a bucket waiting to become a compliance question.
Pagr does not deliver documents. Generation stops at handing you the PDF — sending it to a customer, a portal or an archive stays in your system, where the audit trail already lives. Storage is your call: keep the rendered files in Pagr under a retention window you set, or render without persistence and nothing is kept at all.
Platform
Built to sit under a product, not beside one
Multi-tenancy is not a plan tier here. Organisations, projects, versioned templates, scoped keys and usage tracking are how the platform is put together.
Organisations & projects
Separate your environments and your customers cleanly, with API keys scoped to each.
Versioned templates
Pin a version per call. Roll back a bad edit without touching a deployment.
Usage & audit trails
Know what was rendered, from which template version, by which key.
Grab a key and render something.
A free workspace, a test key and 100 renders a month. No credit card required.


