Skip to content
Get started

Data & JSON Schema

The data object you send with a render is the input to your template. A template can declare a JSON Schema for that input. Doquill then validates every render against it before running the template, so bad input fails with a clear error instead of producing a document with blanks in it.

Edit the schema in the editor’s Schema tab, or send it as draft.schema when updating the template through the API. It’s published with the rest of the template, so each version validates against the schema it was published with.

{
"type": "object",
"required": ["number", "issued_at", "customer", "items", "total"],
"properties": {
"number": { "type": "string" },
"issued_at": { "type": "string" },
"customer": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string" },
"vat_id": { "type": "string" }
}
},
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["description", "quantity", "unit_price"],
"properties": {
"description": { "type": "string" },
"quantity": { "type": "number", "exclusiveMinimum": 0 },
"unit_price": { "type": "number" }
}
}
},
"total": { "type": "number" }
}
}

Doquill uses JSON Schema draft 2020-12. Some tips for document templates:

  • Mark every field the template prints unconditionally as required. A missing field otherwise renders as an empty string.
  • Leave optional fields (wrapped in {{ if }} or {{ with }}) out of required.
  • Use pattern for values a function validates anyway, like the IBAN and BIC passed to epcQR. The render then fails with a field-level validation error instead of a template error.
  • Type numbers as number, not string, if you format or calculate with them.

A template without a schema accepts any data.

When the data doesn’t match, the render returns 400 with code validation_failed. Each detail names the failing field as a JSON Pointer into your data:

{
"error": {
"code": "validation_failed",
"message": "Invalid input",
"details": [
{ "field": "/customer/name", "reason": "Required property 'name' is missing" },
{ "field": "/items/1/quantity", "reason": "Value is string but should be number" }
]
}
}

A problem with the data as a whole, such as sending a list instead of an object, is reported with the field data.

Each template also stores sample data: the data the editor previews with. Keep it valid against the schema and fill every field, with at least one entry in each list, so the preview shows the whole layout. Edit it in the Sample Data panel, or send it as draft.sample_data through the API.

Sample data is never used for API renders. Every render uses the data in its request.