Skip to main content

Generating documents

There are two ways to render:

  • From a template: POST /v1/templates/{templateId}/generate with merge data. Requires the generate scope.
  • One-off: POST /v1/documents with the full layout in the request: blank pages of any geometry, or a document authored in HTML/CSS. No stored template involved.

Both run the same rendering pipeline and accept the same fields, typography, and document options.

Generating from a template

curl -o notice.pdf "https://api.pdfs.ecourtdate.com/v1/templates/$TEMPLATE_ID/generate" \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/pdf" \
-d '{
"data": { "client_name": "Jordan Smith", "hearing_date": "2026-08-15" },
"name": "hearing-notice-smith"
}'
  • The published version renders unless the request pins one with "version": N (lifecycle).
  • data is validated against the version's merge-tag schema: strict by default, with dry_run available as a pre-flight.
  • Merged checkbox values render as drawn check symbols; fill fields set the base PDF's own form fields.

One-off documents

POST /v1/documents renders without any stored template. Without html, the server synthesizes blank pages from page and draws fields on them:

{
"page": { "size": "letter", "orientation": "portrait", "count": 1 },
"fields": [],
"typography": { "font_size": 11 },
"name": "receipt-1042"
}
  • page.size is letter (default), legal, a4, or { "width", "height" } in points (72–7200); count is 1–100 blank pages.
  • fill fields are rejected (422 FILL_REQUIRES_TEMPLATE): there is no existing form to fill. Every other field type works exactly as in template versions.
  • With html, the content is rendered with real CSS layout and determines its own page count. See HTML documents.

Response modes

Choose per request with "response": { "mode": "binary" | "json" }.

Binary (default): the response body is the PDF. Rendering warnings arrive in the X-Warning-Count / X-Warnings headers.

JSON: the document is stored and the response returns download details:

{
"files": [
{
"output_id": "4406d607-16bf-427c-808c-26a7fc26ab0c",
"url": "https://…signed…",
"name": "hearing-notice-smith.pdf",
"format": "pdf",
"content_type": "application/pdf",
"bytes": 24831,
"sha256": "0a33d20b…",
"page_count": 2,
"expires_in": 3600
}
],
"template_id": "5f0c2a4e-…",
"version": 1,
"warnings": []
}

Use JSON mode when the document is handed to another system or user rather than consumed by the caller, and always for HTML documents and batch jobs.

The sha256 is the exact digest of the generated file: store it alongside your case record to later prove which bytes were issued.

Outputs and download URLs

Download URLs are valid for 1 hour. The output itself is retained for about 20 hours, and GET /v1/outputs/{outputId} returns a freshly signed URL any time in that window:

curl -s "https://api.pdfs.ecourtdate.com/v1/outputs/4406d607-…" \
-H "x-api-key: $API_KEY"

After the retention window the output is gone (404 OUTPUT_NOT_FOUND): the API is a rendering service, not a document store. Download and file generated documents in your system of record promptly.

Flattening

"flatten": true converts every interactive form field (including field and checkbox widgets created by the same request) into static page content. The result prints and archives identically everywhere and can't be edited in a viewer. Flatten issued documents; leave forms meant to be filled in unflattened.

Filenames

"name" sets the output filename; a single .pdf suffix is ensured ("hearing-notice-smith"hearing-notice-smith.pdf).

Formats

"file_format" currently accepts pdf (the default).

Reliability

Send an Idempotency-Key on every generate call: a retried timeout then returns the originally generated document instead of rendering a duplicate. Rendering issues that don't fail the document are reported as warnings; to treat them as failures, set "on_warning": "error".