HTML documents
For content-driven documents (letters, orders, multi-page notices), laying
out absolute boxes is the wrong tool. POST /v1/documents with an html
source renders your HTML/CSS with a real browser layout engine: proper text
flow, CSS styling, and automatic pagination.
curl -s "https://api.pdfs.ecourtdate.com/v1/documents" \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "hearing-notice",
"page": { "size": "letter" },
"html": {
"content": "<h1>Notice of Hearing</h1><p>Your hearing is scheduled for <strong>August 15, 2026</strong> at 9:00 AM.</p>"
},
"response": { "mode": "json" }
}'
How it differs from blank-page generation:
- The content determines the page count:
page.countis rejected;page.sizeandorientationset the paper. - The response must be JSON mode (
422HTML_REQUIRES_JSON_RESPONSE): you receive a download URL (response modes). fieldsstill compose onto the rendered pages afterwards, andoptionsapply as usual: overlay a barcode or a watermark on an HTML-authored document freely.- A
contentfragment is wrapped in a page shell using the built-in fonts; a complete document with its own<style>is used as-is.
Sanitization
HTML is sanitized to a safe allow-list before rendering. Removed, and
reported with an HTML_CONTENT_SANITIZED warning so nothing
disappears silently:
- Scripts and event handlers
- Frames and embedded documents
- Forms
- Anything that fetches from the network
Two practical consequences:
- Images must be
data:URIs: embed them (<img src="data:image/png;base64,…">) rather than linking. - Stylesheets and
styleattributes pass through: style freely with inline CSS and<style>blocks; external resources never load.
The rendering sandbox itself runs with scripting disabled and no network access (Security).
Content is limited to 1 MB (413 HTML_TOO_LARGE).
Fonts
Three embedded font families are available by name in your CSS:
| Family | Coverage |
|---|---|
"Noto Sans" (default) | Latin, Latin-extended, Greek, Cyrillic |
"Noto Sans Hebrew" | Hebrew |
"Noto Sans SC" | Simplified Chinese |
<p style="font-family: 'Noto Sans Hebrew'; direction: rtl;">…</p>
Headers, footers, and margins
html.header and html.footer (≤ 10 KB each) are print templates repeated on
every page. Elements with these classes are substituted:
<div style="font-size: 9px; width: 100%; text-align: center;">
Page <span class="pageNumber"></span> of <span class="totalPages"></span>
</div>
| Class | Substituted with |
|---|---|
pageNumber | Current page number |
totalPages | Total page count |
date | Print date |
title | Document title |
html.margins sets page margins in points (top/right/bottom/left,
0–288, default 36 on every side). print_background (default true) controls
whether CSS backgrounds render.
Accessible tagged PDFs
"html": { "tagged": true, … } emits a tagged PDF: the document's
structure (headings, paragraphs, lists, tables) is embedded so screen readers
can navigate it, supporting Section 508 accessibility requirements.
Tagged output cannot be combined with fields, options, typography,
flatten, or unicode (422 HTML_TAGGED_CONFLICT). Composing drawn
content over a tagged document would corrupt its structure tree. Author the
entire document in HTML when you need tagged output, and set the document
language via semantic HTML (<html lang="en">).
For non-tagged documents, still set
options.metadata.language: it helps
assistive technology choose the right voice.
HTML in a box
To place HTML inside an absolutely-positioned box on any document (blank
pages, an uploaded base PDF, or a rendered HTML document), use the
html field type instead: same sanitization, with
{{merge_tag}} substitution, sized exactly to the field box.
Prefer whole-document html when the content should flow and paginate;
prefer html fields when a template's layout is fixed and one region needs
rich content. Note that whole-document HTML preserves link annotations and
(optionally) tagging; composed HTML boxes keep their visual layout only.