Doc Gen API
The Doc Gen API (Document Generation) creates print-ready PDF documents for justice agencies over HTTPS. It is a standalone eCourtDate product with its own base URL, its own documentation site, and its own API keys.
This page is a high-level orientation. The full endpoint documentation, request and response schemas, and interactive console live at docs.pdfs.ecourtdate.com.
What it builds
- Reusable templates with merge tags: define a layout once, publish it as an immutable version, then generate documents by posting only the data.
- One-off documents: generate a document from a blank page or from HTML and CSS, without creating a template first.
- Rich field types: text (plain or Markdown), form fields, checkboxes, symbols, AcroForm fill, images, barcodes (QR and Code 128), tables, and HTML.
- Standalone barcodes: render a single barcode or QR code as a PNG, SVG, or PDF without a document around it, choosing from 49 symbologies across the 2D, linear, retail, GS1, and postal families.
- Image assets: upload and reuse logos, seals, and signatures across documents.
- Batch generation: submit up to 200 documents in a single job and poll for the result.
- Audit trail: a per-account record of what was generated and when, including the person each action was carried out on behalf of.
Common uses include hearing notices, summonses, citations, receipts, compliance letters, and any other document a justice agency needs to produce in volume and keep a record of.
Base URL
https://api.pdfs.ecourtdate.com/v1
The service is HTTPS only. The hostnames keep the earlier pdfs name, so api.pdfs.ecourtdate.com and docs.pdfs.ecourtdate.com are the Doc Gen API. There is no separate staging environment for the Doc Gen API. Coordinates in document layouts are expressed in PDF points with a top-left origin.
Authentication
The Doc Gen API uses a scoped API key sent in the x-api-key header on every request. This is different from the eCourtDate platform API, which issues a client_id and client_secret exchanged for a Bearer token.
Create a key in the eCourtDate Console under APIs at console.ecourtdate.com/apis, selecting the Doc Gen API when creating the client. Key management is self-service: keys are created, scoped, rotated, and revoke Doc Gen API keys directly from that page. See eCourtDate APIs for the shared credential process across all eCourtDate APIs.
The Doc Gen API has to be purchased as an add-on, and the eCourtDate help team activates it on the account before it becomes available. Until activation is done, the Doc Gen API does not appear as a choice on the APIs page and it cannot issue a key for it. To buy the add-on or check on activation, open a support ticket in the Console using the Help button in the bottom-right corner.
Scopes
Grant each key the narrowest set of scopes that lets it do its job.
| Scope | Grants |
|---|---|
templates:read | Browse templates and previews |
templates:write | Create and publish templates |
generate | Create documents and barcodes, poll batch jobs, and access the generated outputs |
audit:read | Read the audit trail |
Attributing writes
Write requests, such as creating a template or publishing a version, also require an X-On-Behalf-Of header naming the person the request is being made for. The audit trail records that value as the acting person, so an API key shared by a backend service still produces a per-person record. The documented examples use an email address:
X-On-Behalf-Of: clerk@example.gov
Handling keys
Store keys in a secrets manager. Never commit them to source control and never expose them in client-side code. To rotate a key, create the replacement first, deploy it, then revoke the old key.
Generating the first document
A single POST /v1/documents call takes a page and a list of positioned fields, and returns the PDF as a binary stream. This example produces a hearing notice with Markdown-formatted text and a QR code, with no template required:
curl -o hearing-notice.pdf "https://api.pdfs.ecourtdate.com/v1/documents" \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/pdf" \
-d '{
"page": { "size": "letter" },
"fields": [
{ "type": "text",
"content": "# Notice of Hearing\n\nState v. Avery · Case CR-2026-004821\n\nYour pretrial hearing is set for **August 15, 2026 at 9:00 AM**\nin Courtroom 3B, Summit County Courthouse.",
"content_format": "markdown",
"x": 72, "y": 72, "width": 360, "height": 240 },
{ "type": "barcode", "symbology": "qr",
"content": "CR-2026-004821",
"x": 460, "y": 72, "width": 80, "height": 80 }
]
}'
Each field is placed with x and y in PDF points from the top-left corner of the page, so the text block and the QR code sit side by side. For the full walkthrough, including template creation and merge tags, see the getting started guide.
Templates and versions
Templates separate layout from data so the same document can be produced repeatedly with different values.
| Step | Endpoint |
|---|---|
| Create the template shell | POST /v1/templates |
| Add a version with fields and merge tags | POST /v1/templates/{template_id}/versions |
| Publish the version | POST /v1/templates/{template_id}/versions/{version}/publish |
| Generate a document from it | POST /v1/templates/{template_id}/generate |
The three write calls in that table (creating a template, adding a version, and publishing a version) require an X-On-Behalf-Of header identifying the person the request is made for, which the audit trail records as the acting person.
Versions are immutable and numbered. A version moves through the states draft, ready, published, and superseded. Generation targets the published version unless the request names a specific version, so publishing a new version changes what the integration produces without any change to the generate calls.
Merge tags are declared on the version with a type, a required flag, and an example value. Data that is missing or of the wrong type fails with a 422 before anything is rendered.
Barcodes
The Doc Gen API produces barcodes two ways: as a field placed inside a generated document, and as a standalone image file with no document around it. Both need an API key carrying the generate scope.
Barcode fields in a document
A barcode field is positioned on the page with x, y, width, and height like every other field, and is drawn as vector art with the quiet zone its specification calls for. Fields accept two symbologies:
symbology | What it encodes | Extra options |
|---|---|---|
qr | Any text up to 500 characters, encoded as UTF-8 so non-Latin values scan back intact | ec_level (L, M, Q, or H, default M) and logo |
code128 | Printable ASCII up to 80 characters. Code sets B and C are selected automatically, so a numeric case number encodes at about half the width | None. ec_level and logo are both rejected on code128 |
Set merge_tag on the field to take the encoded value from the data posted at generation time, so one published template version produces a different QR code for every case.
A value the symbology cannot encode never fails the document: the field is skipped and the response reports a BARCODE_INVALID warning. A symbol whose bars are too fine to scan once printed is still drawn, with a BARCODE_TOO_SMALL warning. Send on_warning: "error" on the generate request to get a 422 instead of a document with a missing or unscannable symbol.
Standalone barcodes
POST /v1/barcodes renders one symbol and returns it as a PNG, SVG, or PDF file. The call is stateless and deterministic: nothing is stored, the same request always returns the same bytes, and an Idempotency-Key header is not needed.
curl -o case-number.pdf "https://api.pdfs.ecourtdate.com/v1/barcodes" \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"symbology": "code128",
"content": "24-CR-001937",
"file_format": "pdf",
"height": 36,
"text": true
}'
| Request field | Purpose |
|---|---|
symbology | Required. A catalog name such as qr, code128, pdf417, or usps_imb. Aliases including qrcode, datamatrix, itf, and onecode are accepted, and the response reports the canonical name |
content | Required. The value to encode as UTF-8, up to 4,000 characters. Content a symbology cannot encode returns 422 BARCODE_CONTENT_INVALID with the reason |
file_format | png (default), svg, or pdf |
scale | 1 to 10. For PNG it is pixels per point, default 3 (about 216 dpi). For SVG and PDF it multiplies the point geometry, default 1 |
height | Linear symbologies only: bar height in points before scale is applied, 10 to 720. Defaults to the height the specification calls for |
quiet_zone | The clear margin around the symbol in points before scale, 0 to 72. Defaults to the symbology's specified quiet zone, which is worth keeping unless composing into a layout that already provides one |
text | Draws the human-readable text under a linear symbol. Retail symbologies default to true. Not available on 2D or postal symbologies |
ec_level | QR symbologies only: error-correction level L, M (default), Q, or H |
rotate | Clockwise rotation of 0 (default), 90, 180, or 270 degrees |
color and background | #rrggbb values, black on white by default. background also accepts transparent. Too little contrast between the two warns BARCODE_LOW_CONTRAST |
logo | QR symbologies only: a brand mark drawn over the finished symbol |
name | File name stem for Content-Disposition and the JSON name field. The extension is added automatically |
response | {"mode": "json"} returns the file inline as base64 along with its symbology, dimensions, byte count, and SHA-256, instead of a binary stream |
on_warning | ignore (default), or error to fail the request when a warning is raised |
Geometry is in native PDF points (1/72 inch), so the default output is already print ready: a narrow bar on a linear symbol is 1 point wide and a QR or Data Matrix module is 2 points. Binary responses carry the finished dimensions in the X-Barcode-Width and X-Barcode-Height headers, and any warnings in X-Warning-Count and X-Warnings.
Standalone barcodes are never stored, so there is no output id, no download URL, and nothing to re-sign later. Keep the bytes the response returns, or call again with the same request to get them back.
Symbologies
Standalone requests accept 49 symbologies, well beyond the two a document field takes. GET /v1/barcodes/symbologies returns the catalog: every value with its label, family, aliases, content rules, the options it accepts, and its defaults.
| Family | Symbologies |
|---|---|
| 2D | qr, micro_qr, data_matrix, data_matrix_rectangular, pdf417, micro_pdf417, aztec, maxicode, dotcode, hanxin |
| Linear | code128, code39, code39_ext, code93, code11, codabar, interleaved2of5, itf14, code2of5, msi, plessey, telepen, pharmacode |
| Retail | ean13, ean8, ean5, ean2, upca, upce, isbn, ismn, issn |
| GS1 | gs1_128, gs1_datamatrix, gs1_qr, sscc18, ean14, databar_omni, databar_limited, databar_expanded, databar_stacked, databar_expanded_stacked |
| Postal | usps_imb, postnet, planet, royalmail, auspost, japanpost, kix |
Each catalog entry also carries an informational priority tier (essential, recommended, compatibility, or extended) and, on the prioritized ones, a use_cases note. The tier says how central a symbology is to typical use, not whether it works: every symbology in the catalog is fully supported.
Logos on QR codes
A standalone qr request and a document barcode field with symbology: qr both accept a logo object that draws a mark over the finished symbol. Supply the image either as an https url pointing at a PNG or JPEG, or inline as base64 in content_base64 (up to 2 MB decoded, which keeps the request self-contained and deterministic). Send exactly one of the two.
Error correction is what makes an overprinted logo readable at all: the reader rebuilds the covered modules from the redundancy the level provides (L about 7 percent, M 15, Q 25, H 30), so the covered area has to stay inside that budget. Supplying a logo raises an unstated ec_level to H for that reason.
| Logo field | Purpose |
|---|---|
position | center (default), top_left, top_right, bottom_left, or bottom_right. center is the only placement that never touches a finder pattern. Of the corners, only the one diagonally opposite the three finders is safe, and it moves with rotate: bottom_right at 0 degrees, bottom_left at 90, top_left at 180, top_right at 270 |
size | The logo's longest side as a percentage of the symbol's shorter side, 5 to 30, default 20. The image is fitted inside that square, so its aspect ratio is preserved |
padding | Clear margin around the logo in points before scale, 0 to 20, default 2. It separates the mark from the surrounding modules and counts toward the covered area |
background | The knockout drawn behind the logo as #rrggbb, default #ffffff, or transparent to composite the logo straight onto the modules |
Covering more than the error-correction budget allows warns BARCODE_LOGO_OVERSIZED, and covering a finder pattern warns BARCODE_LOGO_COVERS_FINDER, which no amount of error correction repairs. In a document, a logo that cannot be fetched or read warns BARCODE_LOGO_UNAVAILABLE and the symbol prints unbranded, so one bad image never costs the document.
Conventions
| Convention | Detail |
|---|---|
| Field naming | snake_case for request and response fields, kebab-case for path segments |
| Timestamps | ISO 8601 in UTC, for example 2026-08-01T17:20:04.211Z |
| Pagination | Cursor based. List endpoints take limit (1 to 100, default 25) and an opaque cursor. Responses carry next_cursor, which is null on the last page. Pass a cursor back exactly as received |
| Idempotency | Send an Idempotency-Key header on POST requests to make retries safe. A replayed response carries Idempotent-Replay: true |
| Errors | RFC 9457 application/problem+json. An unrecognized request field returns 400 UNKNOWN_FIELD |
| Throttling | Expect 429 responses under load. Retry with exponential backoff and jitter |
| Versioning | Versioned path segment (/v1). Error codes, warning codes, field types, and merge-tag types are open sets that may gain new values without notice |
Limits and retention
| Limit | Value |
|---|---|
| Fields per document | 200 |
| Pages per document | 100 |
| Documents per batch job | 200 |
| Barcode content | 4,000 characters, and each symbology has its own capacity |
| Barcode scale | 1 to 10, meaning PNG pixels per point or an SVG and PDF size multiplier |
| Barcode output size | 16 MP for PNG, 14,400 points per side for SVG and PDF |
| Download URL validity | 1 hour, and URLs can be re-signed |
| Generated output retention | About 20 hours |
| Batch job status retention | 48 hours |
Download and store any document to keep. Generated outputs are not a long-term document store.
Next steps
- Doc Gen API documentation: guides for authentication, templates, generation, errors, and warnings.
- Interactive API reference: the full endpoint list with a try-it console.
- OpenAPI 3.1 specification: machine-readable spec for generating clients.
- eCourtDate APIs: the directory of every eCourtDate API and how their credentials differ.