Base URL
All API requests are made to the following base URL:/v1/; the unversioned health check lives at /health.
The base URL does not include a trailing slash. Append endpoint paths exactly as shown in the table below.
Endpoints at a Glance
Pick a curated look with the
theme field (default report-clean) — call GET /v1/themes for the catalog, see Themes. Pick fonts per request with the fontStack field, or pull any Google Fonts family by URL with googleFontsUrl — see Fonts & Typography. Call GET /v1/fonts for the hosted catalog and GET /v1/style-targets for the full rules styling vocabulary.Request Format
RenderPOST requests must include a JSON body and the following headers:
POST /v1/render/validate accepts the same JSON body and x-api-key header, but expects Accept: application/json because the response is JSON, not PDF bytes.
GET requests that require authentication need only the x-api-key header — no request body is sent.
Response Format
A successful call toPOST /v1/render or POST /v1/templates/sandwich-document/render returns a binary PDF (application/pdf). Pipe or write the response body directly to a file rather than reading it as text.
On the public free plan, successful PDF responses from POST /v1/render and template routes include a non-removable bottom-center footer (“Made with Blink PDF” plus the brand mark). The response status and schema are unchanged.
GET /health, POST /v1/render/validate, and all error responses return JSON (application/json).
Validate before render
POST /v1/render/validate runs the same TypeBox schema and cross-field semantic checks as POST /v1/render, without generating a PDF, metering usage, or recording a successful render audit. Use it to iterate on rules, typography, furniture, and related options before spending a render.
A valid body returns 200 with valid: true. When the caller is authenticated, the response also reports the resolved typography (declared pool, active body/heading families, and any unused declarations) and a contentDigest for delivery deduplication:
400 error shape as a failed render request (validation_failed, invalid_body, and related codes). The endpoint does not emit X-Render-* or X-BlinkPDF-Usage-* headers.
Response Headers
Every successful render (POST /v1/render or POST /v1/templates/sandwich-document/render) includes render-status headers and, when the caller is authenticated under plan limits, usage and attribution headers. Both routes share the same spend-cap, tier rate/concurrency, and usage ledger path.
Render status
Each diagnostic object includes
severity, code, message, and help (a blinkpdf://reference/… URI). When applicable, entries also include resource and httpStatus.
Decode X-Render-Diagnostics like this:
Usage and attribution
Successful authenticated renders on bothPOST /v1/render and POST /v1/templates/sandwich-document/render emit usage and attribution headers when billing limits apply:
Sandwich template
POST /v1/templates/sandwich-document/render is metered like POST /v1/render: it counts 1 render unit on a successful billed response, shares spend-cap and tier rate/concurrency, applies the free-tier watermark when applicable, and emits the usage/attribution headers above (except cache and content-digest headers). Successful responses always include X-Template-Version (currently 1.0.0).
Page-1 body clearance uses a flow offset for the header band; bottom margins reserve the repeating page-footer band and, when the last-page signature would not fit under the body, the signature band as well — so the Markdown body never collides with either chrome band.
Client x-idempotency-key is not accepted on template routes (no body fingerprint / pre-check). Do not send it expecting dedupe.
Error Codes
When a request cannot be completed, the API returns a standard HTTP error status code with a JSON body of the shape{ "error": "<code>", "detail": "<message>" }. Field-level validation failures may also include an errors array; each member can carry machine-readable kind, allowed keys/values, relocation hints, and optional variants (accepted shapes for object-valued unions: discriminant when, keys, required, enums — never internal numeric ranges).
Rate Limiting
Rate limits are enforced per API key and vary by plan. Template renders share the same sustained-rate and concurrency buckets asPOST /v1/render. If you exceed your limit, the API returns 429 Too Many Requests and includes a Retry-After header.
Calls to
GET /health and POST /v1/render/validate never consume render units. POST /v1/render/validate is, however, rate-limited in its own per-tier bucket, independent of render and template throughput — a validate burst never spends render throughput, and vice versa, so either can return 429 on its own. Only successful POST /v1/render and POST /v1/templates/*/render responses with X-BlinkPDF-Billing: counted consume render units.Versioning
The current API version isv1, reflected in every endpoint path. When breaking changes are introduced, a new version prefix (e.g. /v2/) will be released alongside the existing version. You will always receive advance notice before an older version is deprecated.