Validate a template
curl -H "X-Api-Key: $KEY" -F template=@letter.docx \ http://localhost:9027/v1/templates/validateimport { openAsBlob } from 'node:fs';
const form = new FormData();form.append('template', await openAsBlob('letter.docx'), 'letter.docx');
const response = await fetch('http://localhost:9027/v1/templates/validate', { method: 'POST', headers: { 'X-Api-Key': process.env.KEY }, body: form,});if (!response.ok) throw new Error(await response.text());console.log(await response.json());import os
import requests
response = requests.post( "http://localhost:9027/v1/templates/validate", headers={"X-Api-Key": os.environ["KEY"]}, files=[("template", open("letter.docx", "rb"))],)response.raise_for_status()print(response.json())package main
import ( "bytes" "io" "log" "mime/multipart" "net/http" "os" "path/filepath")
func main() { var body bytes.Buffer form := multipart.NewWriter(&body) attach(form, "template", "letter.docx") form.Close()
request, err := http.NewRequest("POST", "http://localhost:9027/v1/templates/validate", &body) if err != nil { log.Fatal(err) } request.Header.Set("X-Api-Key", os.Getenv("KEY")) request.Header.Set("Content-Type", form.FormDataContentType())
response, err := http.DefaultClient.Do(request) if err != nil { log.Fatal(err) } defer response.Body.Close() if response.StatusCode >= 300 { message, _ := io.ReadAll(response.Body) log.Fatalf("%s: %s", response.Status, message) } if _, err := io.Copy(os.Stdout, response.Body); err != nil { log.Fatal(err) }}
// attach adds the file at path to the form as the named field.func attach(form *multipart.Writer, field, path string) { file, err := os.Open(path) if err != nil { log.Fatal(err) } defer file.Close() part, err := form.CreateFormFile(field, filepath.Base(path)) if err != nil { log.Fatal(err) } if _, err := io.Copy(part, file); err != nil { log.Fatal(err) }}curl -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \ -d '{"templateId":"letter"}' http://localhost:9027/v1/templates/validateconst response = await fetch('http://localhost:9027/v1/templates/validate', { method: 'POST', headers: { 'X-Api-Key': process.env.KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ templateId: 'letter' }),});if (!response.ok) throw new Error(await response.text());console.log(await response.json());import os
import requests
response = requests.post( "http://localhost:9027/v1/templates/validate", headers={"X-Api-Key": os.environ["KEY"]}, json={"templateId": "letter"},)response.raise_for_status()print(response.json())package main
import ( "io" "log" "net/http" "os" "strings")
func main() { body := strings.NewReader(`{"templateId":"letter"}`)
request, err := http.NewRequest("POST", "http://localhost:9027/v1/templates/validate", body) if err != nil { log.Fatal(err) } request.Header.Set("X-Api-Key", os.Getenv("KEY")) request.Header.Set("Content-Type", "application/json")
response, err := http.DefaultClient.Do(request) if err != nil { log.Fatal(err) } defer response.Body.Close() if response.StatusCode >= 300 { message, _ := io.ReadAll(response.Body) log.Fatalf("%s: %s", response.Status, message) } if _, err := io.Copy(os.Stdout, response.Body); err != nil { log.Fatal(err) }}Checks a template against sample data without converting anything.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”The multipart form /v1/render, /v1/render/batch and
/v1/templates/validate accept.
object
Images (PNG, JPEG, GIF, SVG), stylesheets and fonts an HTML page names
by file name, as in <img src="logo.png">. Every stylesheet applies to
the whole page. Nothing is fetched from anywhere else.
For /v1/render/batch: each file’s name, as a template.
For bookmarks: a JSON array of {"title", "page", "children"} that
replaces the outline, sent as text.
object
For sign: certify with DocMDP permission 1, 2 or 3 instead of
approving.
For sign: how to reach the signer.
JSON object visible as ctx, sent as text or as a file.
The currency currency uses when given none, such as EUR. Wins over
the template’s.
JSON object the template sees as its root, sent as text or as a file.
Example
{"customer": {"name": "Ada"}}Files to fetch from URLs instead of uploading them, as a JSON array of
{"url": "..."} sent as text. At most 10 entries.
object
For embed: the files to attach.
For embed: a JSON object mapping a file name to
{"mimeType": "..."}, sent as text.
For factur-x: MINIMUM, BASIC_WL, BASIC, EN16931 (default) or
EXTENDED.
For factur-x: the invoice XML to embed.
Further files, used by merge.
With a PDF template and data, true fixes the filled values into the
page.
Fonts for this request only.
What turns HTML into PDF: fulgur (default), a layout engine with
no browser and no network, or libreoffice.
Example
fulgurWhat an Office template’s result may keep of what rendering takes
out, comma-separated: macros, objects (OLE objects and ActiveX
controls), externalLinks, privateLinks (hyperlinks to private
addresses), or all. Default: none of them.
Example
privateLinksThe language, such as fr, fr-CA or en-us, in any case. It wins
over the template’s lang: it picks translations for t, and when CLDR
has data for it, how number, currency and date write numbers,
money and month names.
Example
fr-CAFor sign: b-b, b-t, b-lt or b-lta, as on /v1/pdf/sign.
For sign: where it was signed.
JSON object of metadata fields for metadata, sent as text.
File name of the result, without extension.
For encrypt: the password that lifts its restrictions. Defaults to
userPassword.
For a visible sign: the 1-based page. Default 1.
PDF/A level for pdfa: PDF/A-1b, PDF/A-2b, PDF/A-3b.
For sign: why the document was signed.
For rotate: 90 (default), 180, 270 or -90.
For rotate: the pages to turn, such as 1-3. Default all.
For sign: a PNG or JPEG to show the signature with, at page, x,
y and width. With x and y and no image, the signature is shown
as text: the signer, the date and the reason.
For sign: the signer’s name as shown.
For sign: a named key instead of the default one.
For /v1/render/batch: the array to render once per element.
For split: pages (default) or intervals.
For split: page ranges such as 1-3,5 with pages, or a page count
with intervals. Required by the step.
For split with pages: true gives one document holding the pages
instead of one per range.
For stamp with an image or pdf source: the files to draw. At
most five marks a request.
For stamp with a text source: the text to draw.
For stamp: a JSON object of pos, op, rot, sc, fontsize and
fillc, each value a string, sent as text.
For stamp: the pages to mark, such as 1-3. Default all.
For stamp: what to draw over the page content, text, image or
pdf.
Comma-separated steps, run in the order given: convert, pdfa,
pdfua, merge, split, watermark, stamp, underlay, rotate,
flatten, optimize, bookmarks, metadata, embed, factur-x,
encrypt, sign. Each reads the fields described as its own. sign
signs cryptographically with the service’s key; it must be last and
cannot be combined with encrypt.
Example
convert,pdfa,encryptWith a PDF template and data, false keeps the annotations that held
tags. They are removed by default.
The template file. Send this or templateId.
The hex SHA-256 of a template this caller sent recently, in place of the file.
The id of a stored template, from POST /v1/templates, or an alias as
name or name@version. Send this or template. Files in the form are
then only further inputs, for merge.
The time zone date shows moments in: an offset such as +02:00, or an
IANA zone such as Europe/Paris. Wins over the template’s.
Example
Europe/ParisOutput format for convert. Default pdf.
Translations for t, by language, each a flat object of keys and texts.
They win over the service’s dictionaries and the template’s own. At most
10,000 entries, keys of 256 bytes and texts of 16 KiB.
true prints a value missing from the data as nothing instead of
failing the render. Default false, so a misspelt name is an error.
For underlay: the PDF the document is laid over, page by page, such
as letterhead or a pre-printed form.
For encrypt: the password that opens the document.
For watermark with an image or pdf source: the files to draw. At
most five marks a request.
For watermark with a text source: the text to draw.
For watermark: a JSON object of pos, op, rot, sc, fontsize
and fillc, each value a string, sent as text.
For watermark: the pages to mark, such as 1-3. Default all.
For watermark: what to draw under the page content, text, image
or pdf.
For a visible sign: width in points. Default the image’s natural
size, or 200 for text.
For a visible sign: points from the page’s left edge.
For a visible sign: points from the page’s bottom edge.
The JSON body /v1/render, /v1/render/batch and
/v1/templates/validate accept with Content-Type: application/json, for a
stored template: there are no files to send. Every text field of the
multipart form is accepted under the same name, with the same meaning and
limits; objects such as data and metadata are sent as JSON rather than as
text, and steps may be a list. Fields that carry files cannot be sent.
object
For /v1/render/batch: each file’s name, as a template.
The object visible as ctx.
The currency currency uses when given none, such as EUR. Wins over
the template’s.
The object the template sees as its root.
URLs to fetch as further inputs, as on the multipart form.
object
fulgur (default) or libreoffice, for HTML.
What an Office template’s result may keep of what rendering takes
out, comma-separated: macros, objects (OLE objects and ActiveX
controls), externalLinks, privateLinks (hyperlinks to private
addresses), or all. Default: none of them.
Example
privateLinksThe language, such as fr, fr-CA or en-us, in any case. It wins
over the template’s lang: it picks translations for t, and when CLDR
has data for it, how number, currency and date write numbers,
money and month names.
Example
fr-CAMetadata fields for metadata.
File name of the result, without extension.
PDF/A level for pdfa.
For /v1/render/batch: the array to render once per element.
The steps in order, as a list or as comma-separated text.
Example
[ "convert", "pdfa"]The stored template: its id, or an alias as name or name@version.
Example
invoiceThe time zone date shows moments in: an offset such as +02:00, or an
IANA zone such as Europe/Paris. Wins over the template’s.
Example
Europe/ParisOutput format for convert. Default pdf.
Translations for t, by language, each a flat object of keys and texts.
They win over the service’s dictionaries and the template’s own. At most
10,000 entries, keys of 256 bytes and texts of 16 KiB.
true prints a value missing from the data as nothing.
Responses
Section titled “Responses”The validation result
object
Every problem found: severity, message, and a location with
part, place and snippet where known.
object
The engine that would handle it: office, text or none.
The first error, when ok is false.
Fonts the template names that the service has neither loaded nor
mapped to a substitute with the same metrics. Text set in them renders
in a fallback font, which moves line and page breaks. Each also appears
in diagnostics as a warning.
True when the template renders with the sample data.
SHA-256 of the template, the cache key.
Example generated
{ "diagnostics": [ {} ], "engine": "example", "error": "example", "format": "example", "missing_fonts": [ "example" ], "ok": true, "template_hash": "example"}The request is wrong
The JSON body of every error response.
object
A stable, machine-readable kind.
What went wrong, for a person.
Example
{ "error": "invalid_request", "message": "unknown step 'teleport'"}