Skip to main content

Document Service

The Document service validates Typograph templates against the schema and upgrades older templates to the current schema version. Both endpoints operate on a template that is hosted at a URL — the service downloads it, processes it, and returns the result inline.

Endpoints​

MethodPathDescriptionToken TypeScopes
POST/v1/document/validateValidate a hosted template against a schema versionuser or clientdocument, document:read
POST/v1/document/upgradeUpgrade a hosted template to a newer schema versionuser or clientdocument, document:write
GET/health/documentLiveness check proxied through the gateway——

Both operational endpoints accept either a user token (Authorization Code / Refresh Token) or a client token (Client Credentials). See Token Types.

Request Body​

Both endpoints share the same request body shape:

FieldTypeRequiredDescription
templateobjectYesWhere the template is downloaded from
template.urlstring (URL, max 2000 chars)YesURL of the template JSON file. Only .json extensions are accepted. /validate takes a template or a template bundle; /upgrade takes a template.
template.headersobjectNoHTTP headers for the download, for example an Authorization header (max 5)
versionstringNoSchema version (e.g. "1.0.0"), matching <major>.<minor>.<patch>. For /validate, the version to validate against; when omitted, the version declared inside the template. For /upgrade, the version to upgrade to; when omitted, the latest schema version.

The service downloads the template once, within 30 seconds, and the file must be ≤ 50 MB.

A template behind authentication​

When the template URL needs a header, give it in template.headers:

{
"template": {
"url": "https://storage.example.com/private/my-template.json",
"headers": { "Authorization": "Bearer your-storage-token" }
},
"version": "1.0.0"
}

The headers follow the same rules as the headers of a publisher or converter job (see Headers for the URLs of a job):

  • at most 5 headers;
  • only allowed names, such as Authorization, X-Api-Key or any other X-… name; Host, Cookie and the forwarding headers are always refused;
  • a value of at most 8 KB, without CR, LF or NUL.

A header that breaks a rule is a 400 validation error on template.headers. The headers are used for this one download only: they are never stored, and never returned.

A presigned URL needs no headers. Don't add an Authorization header to one: object stores refuse a request that carries both.

Validate a Template​

Check whether a template conforms to the Typograph schema.

A saved template​

The editor saves a template as a bundle: the template and its manifest in one document, { "version": "1.0.0", "manifest": {...}, "template": {...} }. That is the file the File Service gives you at GET /v1/file/templates/{id}/file/download-url, and the template_bundle.json the Converter Service produces. Give /validate that URL as it is: a document with a template object is validated as a bundle, its manifest and its template both, and a violation's property_path then starts at the bundle, as in template.spreads[0] or manifest.fonts[1]. version is the bundle's schema version.

curl -X POST https://api.typograph.nl/v1/document/validate \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"template": { "url": "https://example.com/my-template.json" },
"version": "1.0.0"
}'

Response — Valid Template​

If the template is valid, violations is empty:

{
"violations": [],
"has_violations": false
}

Response — Validation Errors​

If the template has violations, violations lists them:

{
"violations": [
{
"message": "This value should be greater than 0.",
"property_path": "spreads[0].elements[2].width",
"invalid_value": -10
},
{
"message": "This value should not be null.",
"property_path": "metadata",
"invalid_value": null
}
],
"has_violations": true
}

Violation Object​

FieldTypeDescription
property_pathstringJSON-path style pointer to the invalid property inside the document you gave: the template, or the bundle
messagestringHuman-readable description of the violation
invalid_valueanyThe value that failed validation
info

A 200 answers whether the template is valid or not: read has_violations, or check that violations is empty. A 400 means the template could not be checked at all.

Upgrade a Template​

Upgrade an older template to a target schema version. The response is the upgraded template JSON.

curl -X POST https://api.typograph.nl/v1/document/upgrade \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"template": { "url": "https://example.com/legacy-template.json" },
"version": "1.0.0"
}'

Response​

The upgraded template is returned inline, matching the target schema version, and always in the current key names: a template saved with the older names (meta_data, page_name, story_data, …) is read and comes back renamed (see Documents):

{
"version": "1.0.0",
"type": "template",
"metadata": { ... },
"font_data": [ ... ],
"swatches": [ ... ],
"spreads": [ ... ],
"active_spread_index": 0
}

See the Documents concept page for the full template shape.

Schema Versions​

The current shipping schema version is 1.0.0. The service validates the version parameter against the <major>.<minor>.<patch> pattern; pass a matching version string, or omit the field: /validate then uses the version declared inside the template, and /upgrade upgrades to the latest schema version.

Errors​

HTTPErrorCause
400Bad Requesttemplate.url missing, not a URL, or not a .json file
400Bad Requesttemplate.headers has more than 5 headers, a name that is not allowed, or a value with CR or LF
400Bad Requestversion provided but doesn't match X.Y.Z pattern
400Bad RequestThe template could not be downloaded.: the URL did not answer, answered with an error status, or took longer than 30 seconds
400Bad RequestThe template is larger than the limit of 50MB.: the template is over the size limit
401UnauthorizedMissing or invalid access token
403ForbiddenToken lacks document scope (or document:read for validate / document:write for upgrade)

All errors follow the standard gateway JSON error format (see API Overview).

A failed download answers with the same message, The template could not be downloaded., whatever the reason, with one exception: a template over the size limit answers The template is larger than the limit of 50MB., because that is something you can fix yourself. The reason (refused connection, timeout, status code) is logged on our side but not returned: it would tell a caller what the service can reach. Errors about the template's content, such as invalid JSON or an unsupported version, do come back in full.

Use Cases​

Pre-Submission Validation​

Validate a template before handing it off to the Publisher service:

async function generatePdf(templateUrl, token) {
const validation = await fetch('https://api.typograph.nl/v1/document/validate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ template: { url: templateUrl }, version: '1.0.0' })
}).then(r => r.json());

if (validation.has_violations) {
throw new Error(`Template invalid: ${validation.violations.length} violation(s)`);
}

return fetch('https://api.typograph.nl/v1/publisher/jobs', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
template: { url: templateUrl },
generator: { type: 'pdf' }
})
}).then(r => r.json());
}

Batch Upgrade​

Upgrade a list of hosted templates to the current schema version:

async function upgradeAll(templateUrls, token) {
const results = [];

for (const url of templateUrls) {
const upgraded = await fetch('https://api.typograph.nl/v1/document/upgrade', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ template: { url }, version: '1.0.0' })
}).then(r => r.json());

results.push({ source: url, upgraded });
}

return results;
}