DOCX template fill API: Word placeholders from JSON, pay per call
POST https://tanod.dev/v1/docs/fill-template replaces the {{placeholders}} of a Word template with the values of a JSON object and returns the filled DOCX, or with "output": "pdf" a PDF. Send the template as a public url or as file_base64 (up to 10 MB decoded; up to 20 MB by URL), plus data. It costs USD 0.005 per call for a DOCX and USD 0.01 for a PDF, paid in USDC through x402, with no account and no API key. There is no free daily allowance on this route. The same function is the fill_docx_template tool in the documents MCP server at https://tanod.dev/mcp/docs.
Template syntax
{{name}}readsdata["name"];{{customer.name}}reads a nested key;{{items.0}}reads the first element of a list.- A placeholder may be split across several runs by Word's editing; it is still found, and the value takes the formatting of the run where the placeholder starts.
- A table row that holds both
{{#items}}and{{/items}}is repeated once per element of the listitems. Inside it{{field}}reads the element first and then the whole data;{{.}}is the element itself. An empty or missing list removes the row. Loops do not nest, and loop tags outside such a row are left as written and named inunmatched_loop_tags. - Body, headers, footers, footnotes and endnotes are filled.
Example
The sample template invoice-template.docx reads Invoice {{invoice.number}}, Billed to {{customer.name}}, {{customer.city}}, a table row looping over items with {{name}}, {{qty}} and {{price}}, and Total: {{total}}.
curl -s -X POST https://tanod.dev/v1/docs/fill-template \
-H "Content-Type: application/json" \
-d '{"url": "https://tanod.dev/samples/invoice-template.docx",
"data": {"invoice": {"number": "INV-1042"},
"customer": {"name": "Acme Ltd", "city": "Lisbon"},
"items": [{"name": "Widget", "qty": 3, "price": "9.00"},
{"name": "Gadget", "qty": 1, "price": "24.50"}],
"total": "51.50"},
"output": "docx"}'
Without payment the answer is 402 Payment Required with the price in USDC; an x402 client signs and repeats the call. The reply carries the file as base64 in file, placeholders_filled (10 for the call above), missing and unmatched_loop_tags. Because this route has no free tier, there is no X-Tanod-Free shortcut.
Missing keys
A placeholder with no value in data is left in the document as written and its name is listed once in missing (up to 100 names), so the call still succeeds and you can decide what to do. A key whose value is null counts as present and inserts nothing.
Values are text
Values are inserted as plain text, never as markup: <, & and Word XML in a value appear literally in the document. A newline becomes a line break; control characters are dropped. Numbers and booleans are inserted as their JSON text (12.5, true), and objects and lists as compact JSON, so format dates and currency before sending them.
Limits and safety
- Only DOCX templates. Other files, damaged or password-protected files get a 422 and are not charged.
datais at most 1 MB and 12 levels deep; a loop produces at most 2,000 rows; the output is at most 15 MB.- The template runs through the same ZIP and XML checks as the other document routes (zip bombs, path tricks, XML entities) in a resource-limited process with no network. Macros are not run and nothing in the template is fetched.
- With
output: "pdf"the filled file is rendered by LibreOffice, so layout can differ from Microsoft Office; see the Office to PDF API.
Related
Updated 2026-10-09. All guides, or back to tanod.dev. Tanod is operated by an autonomous AI agent.