The document-render API

JSON in. Paper out.

Formfeed turns a POST request into a pixel-perfect PDF — invoices, contracts, reports — rendered from versioned templates, validated before a single pixel draws.

Test mode free, no cardp95 under a secondEU + US rendering
First render

One endpoint. Five minutes to your first page.

bash
curl -X POST https://api.formfeed.dev/v1/renders \
  -H "Authorization: Bearer ff_test_5k...N2WP" \
  -d '{
    "template": "invoice-eu-vat@v4",
    "data": { "invoice_no": "INV-2107", "total": "4180.00" }
  }'

# 201 Created · 412ms
{ "id": "R-88241", "status": "rendered",
  "pdf": "https://cdn.formfeed.dev/r/R-88241.pdf" }

Templates are versioned. Your data is validated against the template's schema before rendering — bad payloads fail in milliseconds with a field-level error, not a broken PDF.

The problem

Every product ships documents. Nobody wants to own the printer.

The PDF pipeline is always someone's side quest — until month-end, an auditor, or a Turkish character makes it the main one.

  • Headless-browser babysitting

    A pinned Chrome, a flaky container, and a retry loop — hundreds of lines of infrastructure to print an invoice.

  • The month-end break

    The layout that survived every test meets a 47-line invoice with a credit note on the 31st, at volume.

  • Compliance wants the exact page

    "Send us the invoice as issued in March." If your template changed since, what do you regenerate it with?

  • Fonts, scripts, and the box glyph

    The ß that rendered as a box, the RTL address, the currency symbol your system font didn't ship.

Platform

The rendering half of your product, handled.

Templates, validation, environments, and a log you can take to an auditor.

A render log with replay

Every render is traceable: payload, template version, timing, outcome. Replay any of them — including the failures — with one call.

Schema-validated data

Each template publishes a schema; bad payloads fail fast with field-level errors.

Test & live environments

Separate keys, separate quotas, watermarked test renders. CI never touches production paper.

Templates with versions

invoice-eu-vat@v4 renders the same page in March, in July, and in court. Ship v5 without rewriting history.

Webhooks & storage

render.completed and render.failed to your endpoint; PDFs to our CDN or your bucket.

One workspace, this month

What the console reads on June 25.

61,240Renders this month61% of plan, day 25
0.4%Error rate12 today — every one traced
780msp95 render412ms median
4Templates in production12 versions retained
How it works

Design once. Render forever.

The template is the contract — your code only ever sends data.

  1. 01

    Design the template

    Start from our invoice, contract, and report templates or bring your own layout. Every template publishes the schema its data must satisfy.

  2. 02

    Point your data at it

    POST your JSON with a test key. Validation errors name the field; watermarked previews render in the console as you iterate.

  3. 03

    Go live by swapping the key

    Same endpoint, live key, clean paper. Webhooks confirm every render; the log keeps the receipts.

From the render log

Teams that stopped owning the printer.

We deleted four hundred lines of headless-browser babysitting the week we moved invoices over. Month-end just… renders now.
ISIda StrandbergPlatform engineer, Quillbase
Contracts have to look identical in March and in court. Versioned templates mean the PDF we sent is the PDF we can prove we sent.
RIRuben IturbeFounder, Bramblewood Legal
Pricing

Priced by the page, not the seat.

Test mode is free forever. Live plans include renders, then meter at $9 per 1,000 — nothing ever drops at the line.

Test

$0

Build against the real API.

  • Unlimited watermarked renders
  • 3 templates
  • Full console & render log
  • No card required
Popular

Launch

$29/mo

Your first paper in production.

  • 2,500 live renders included
  • Unlimited templates & versions
  • Webhooks + CDN storage
  • Email support

Scale

$199/mo

Month-end at volume.

  • 25,000 live renders included
  • EU + US render regions
  • Your bucket, your retention
  • SSO & audit log
Engineering questions

What your team lead will ask before the key goes in vault.

Is this just a headless browser in a trenchcoat?

Under the hood it's a pinned, patched render farm with deterministic font resolution — but the difference is the contract around it: schema validation before render, snapshot tests on every template version, and a render log you can replay. The flaky part of headless PDF work was never Chrome; it was owning all of that yourself.

What about fonts, scripts, and locales?

Templates bundle their fonts, so the ß, the ₺, and the RTL address render the same on every run. Number, date, and currency formatting follow the locale you pass per render — one template can invoice Berlin and Osaka.

How fast is a render, honestly?

Median 412ms, p95 780ms for a one-page invoice; long reports scale roughly per page. A cold template version adds about a second on its first render, then it's warm. The console shows your real numbers — those are ours.

What do you keep, and for how long?

By default: request payloads are deleted after the render completes, PDFs live on our CDN for 30 days, and the log keeps metadata (template, version, timing, outcome) for a year. On Scale you can point storage at your own bucket and set retention to zero on our side.

Can rendering stay in the EU?

Yes — pick eu-central per key or per render on the Scale plan, and payloads never leave the region. We'll sign a DPA, and the subprocessor list is public and short.

What happens when I hit my included renders?

Nothing dramatic. Renders keep flowing and meter at $9 per 1,000; you can set a hard cap or a spend alert if you'd rather be asked. Month-end invoices don't wait for a quota conversation.

Your first render is five minutes away.

A test key, one POST, and the invoice you've been dreading owning — rendered.

Test mode free forever · No card required