POST /v1/render. There is no /v1/forms route (404). Same bp_ key. This overview covers the base URL, available endpoints, request and response conventions, and what to expect when something goes wrong.
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
Fill guides: overview, inspect, fill, templates.
/v1/forms is not a route.
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
AuthenticatedPOST requests send JSON (or, on inspect / validate-fill / fill / templates, multipart pdf) and:
POST /v1/render/validate and POST /v1/validate-fill expect 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. GET /v1/templates/{id} may send Accept: application/pdf to stream the stored blank.
Response Format
A successful call toPOST /v1/fill, POST /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. POST /v1/fill streams the bytes and does not keep the output.
On the public free plan, successful PDF responses from POST /v1/fill, POST /v1/render, and sandwich 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/inspect, POST /v1/validate-fill, POST /v1/render/validate, template-library JSON, 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 unit.
Fill has a matching dry-run: POST /v1/validate-fill. Same pdf XOR templateId plus values as fill. No PDF. No unit. Empty required names land in missingRequired; fill still writes.
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. POST /v1/fill shares the same spend-cap, tier rate/concurrency, and usage ledger path. A counted fill is 1 unit. Fill overlay advisories ride X-Fill-Warnings — see Fill.
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, and successful fills on POST /v1/fill, 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 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).
Caller-value fill faults (
unknown_field_name, type_mismatch, skipped_field_name, appearance_unencodable) are 400 with RFC 9457 type https://blinkpdf.io/errors/<code>. One bad key fails the whole fill.
Rate Limiting
Rate limits are enforced per API key and vary by plan.POST /v1/fill, POST /v1/inspect, POST /v1/validate-fill, POST /v1/render, and sandwich template routes share the plan post-auth rate and concurrency buckets. If you exceed your limit, the API returns 429 Too Many Requests and includes a Retry-After header.
Calls to
GET /health, POST /v1/inspect, POST /v1/validate-fill, POST /v1/render/validate, and /v1/templates never consume units. POST /v1/render/validate is rate-limited in its own per-tier bucket, independent of render throughput. Inspect and validate-fill share the fill/render limiters but still spend zero units. Only successful POST /v1/fill, POST /v1/render, and POST /v1/templates/*/render responses with X-BlinkPDF-Billing: counted consume units. A fill is 1 unit.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.