Skip to main content

Document Definition

The document definition is the core of DocPayload. It's a JSON object that declaratively describes your entire PDF — layout, styles, content, headers, footers, and more.

Root structure

{
"document": {
"metadata": { ... },
"pageSetup": { ... },
"styles": { ... },
"fonts": { ... },
"images": { ... },
"header": { ... },
"footer": { ... },
"watermarks": [ ... ],
"content": [ ... ],
"ref": [ ... ],
"encryption": { ... },
"signature": { ... },
"attachment": { ... },
"bookmark": { ... },
"diagnostics": { ... }
}
}

Only content is required. The other keys are optional — omit any you don't need.

Root keys

The API accepts three root keys — all map to the same internal structure:

Root keyPurpose
"document"Full document definition. The primary and recommended root key.
"component"A reusable piece of a document (styles + content, no page setup required). Used for composition.
"documentDefinition"Backward-compatible alias for "document". Works identically but "document" is preferred.

An optional "$schema" key can be added alongside the root key to enable IDE validation — it is ignored by the engine. See Editor setup below.

Editor setup

The JSON Schema is published at:

https://docpayload.com/docs/schemas/v1/document-definition.schema.json

Pointing your editor at it gives you autocomplete on every property, value-set hints on enum-bound fields (e.g. textAlign, fontWeight, page size), and red squiggles on typos and unknown discriminators — before you render.

Option 1 — $schema keyword (per file)

Add a $schema key at the top of the document. Any JSON-Schema-aware editor picks it up automatically:

{
"$schema": "https://docpayload.com/docs/schemas/v1/document-definition.schema.json",
"document": {
"content": [
{ "p": "Hello." }
]
}
}

The engine ignores $schema at render time, so it's safe to leave in production files.

Option 2 — VS Code workspace setting

Associate every JSON file under a folder (or matching a glob) with the schema once, in .vscode/settings.json:

{
"json.schemas": [
{
"fileMatch": ["templates/**/*.json", "documents/**/*.json"],
"url": "https://docpayload.com/docs/schemas/v1/document-definition.schema.json"
}
]
}

Adjust the fileMatch globs to wherever you keep your DocPayload sources. No need to add $schema to each file with this approach.

Option 3 — JetBrains IDEs (IntelliJ, WebStorm, Rider, …)

Settings → Languages & Frameworks → Schemas and DTDs → JSON Schema Mappings → +. Set Schema URL to the URL above, then add a file path pattern matching where your DocPayload JSON lives.

Option 4 — Cursor and other JSON-Schema-aware editors

The $schema keyword (Option 1) is the universal path — any editor that honors draft-07 JSON Schema will resolve it.

What enforcement actually does

MistakeCaught?
Unknown style property (fontWieght instead of fontWeight)Red squiggle on the key
Unknown content discriminator ({ "canvas": { … } } instead of { "shapes": [...] })Red squiggle on the key
Wrong value type (fontSize: "big")Type error
Out-of-list enum (textAlign: "diagonal")Enum error with the allowed list
Bad border shorthand (borderTop: { width: 1 } instead of "1pt solid #000")Type error
Page size not in the catalog (size: "QUARTO")Enum error suggesting LETTER, A4, etc.

Wrong-cased keys (FontWeight instead of fontWeight) may also squiggle, even though the runtime honors them — author with IntelliSense and you get canonical casing for free.

Properties

PropertyTypeRequiredDescription
metadataobjectNoTitle, author, subject, keywords
pageSetupobjectNoPage size, orientation, margins, page borders
stylesobjectNoNamed reusable style definitions
fontsobjectNoCustom font-family definitions loaded from font files
imagesobjectNoKeyed image dictionary referenced by name from [image, key] inline tags or { "image": "key" } body nodes
headerobjectNoRepeating page header
footerobjectNoRepeating page footer with page numbering
watermarksarrayNoPage-chrome overlays applied across every page (text, image, or shape content; one entry per layer)
contentarrayYesArray of content elements
refarrayNoComponent references merged into the document (used for composition)
encryptionobjectNoPassword protection and permissions
signatureobjectNoDigital signature (PAdES or detached CMS)
attachmentobjectNoEmbed a file attachment in the PDF
bookmarkobjectNoDocument outline / bookmark tree
diagnosticsobjectNoPer-render diagnostics — appends a development appendix listing every style, font, image, and ref resolved during the render

Content elements

The content array accepts the following element types. Each item is an object carrying exactly one of these discriminator keys (plus optional siblings like style, colspan, rowspan).

ElementKeyDescription
ParagraphpText with inline formatting
Headingh1h5Semantic headings with built-in sizing
TabletableRows and columns with cell styling, colspan / rowspan
Ordered ListolNumbered list
Unordered ListulBulleted list
ColumnscolumnsMulti-column layout
SeparatorseparatorHorizontal line
ImageimageStandalone image element
Barcodebarcode63 supported symbologies — 1D, 2D, GS1, HIBC, postal
Form Fieldinline tags7 interactive field types — text, textarea, checkbox, radio, choice, list box, date picker
CanvasshapesSVG-aligned drawing primitives (line, rect, circle, path, text, image…) with optional viewBox and padding
Page breakbreakpage, section, or line break
Table of contentstocAuto-generated TOC from h1h5 headings

Unknown discriminator keys are rejected at validation time — typos like { "canvas": { … } } (the old, no-longer-recognized wrapper) won't render silently empty; the engine errors out so the typo is obvious.

Minimal example

The simplest valid document:

{
"document": {
"content": [
{ "h1": "Hello, World!" },
{ "p": "Generated by DocPayload." }
]
}
}