Skip to main content

Word Templates

Upload a .docx or .dotx as a template, list and read its field sheet, change metadata and field sources by key, and delete it through /v1/doc-gen/templates.

A template is a Word file kept exactly as uploaded, plus a field sheet derived from its content controls. POST /v1/doc-gen/templates stores the file and creates the sheet with every field unconfirmed and a suggested source. kind is letter unless the request or the file name says agreement; group is a free label for organizing templates; version defaults to a (MM-YYYY) date found in the file name; and pairId links a companion template that is generated together with this one when a request sets with_pair.

The list route returns templates in the order they were created, without their fields. Each entry carries field_count, unconfirmed and entered_per_document (fields with a case source) instead, so a client can find the templates that still need attention in one call. GET /v1/doc-gen/templates/{id} returns the full field sheet together with the state of the latest proposal, null when none ran. The q filter is a case-insensitive substring over the name, group and file name; group is an exact match.

PATCH changes metadata and fields by key, and fields it does not name stay as they are. A field accepts a new label, a new source, a confirmed flag and a reason. Unknown field keys, a source of no known shape and conditions that read themselves are refused with 422 and nothing is stored. With dry_run: true the response is the template as it would be after the change and nothing is written, which is the safe way to check a generated source before committing it.

GET/v1/doc-gen/templates

Query parameters

qstringCase-insensitive substring over the template name, group and file name.
groupstringExact group name.

Response fields (per entry)

iduuidThe template id.
indexintegerPosition in creation order, starting at 1.
name, file, group, kind, versionstringTemplate metadata. kind is letter or agreement; group and version are empty strings when unset.
pairIduuid | nullThe companion template generated with this one.
dataProductIduuid | nullThe data product the field sheet was last proposed for; null until a proposal ran.
field_countintegerNumber of fields on the sheet.
unconfirmedintegerFields whose source nobody has confirmed.
entered_per_documentintegerFields with a case source, entered for each document.
generated, lastUsedAt, uploadedBy, updatedAtmixedHow many batches used the template, when it was last used, who uploaded it, and when it last changed.
POST/v1/doc-gen/templates

Body fields

filename*stringThe file name, 1 to 300 characters. A .docx or .dotx extension is expected.
content_base64*stringThe .docx or .dotx bytes as base64; line breaks are allowed. Bounded by the 5 MB request body limit.
namestringUp to 300 characters. Defaults to the file name without its extension.
groupstringUp to 200 characters.
kindstringletter or agreement. Letter unless this field or the file name says agreement.
versionstringUp to 60 characters. Defaults to a (MM-YYYY) date found in the file name.

Response: 201 Template with its field sheet (excerpt)

{
  "id": "3b1f6a52-8c0e-4f0a-9d5e-2a7c1e4b9d10",
  "index": 3,
  "name": "contract-letter",
  "file": "contract-letter.docx",
  "group": "Letters",
  "kind": "letter",
  "pairId": null,
  "version": "",
  "fields": [
    {
      "key": "addressee",
      "label": "Addressee",
      "kind": "text",
      "options": [],
      "dateFormat": null,
      "where": ["body"],
      "zone": "address",
      "group": "address",
      "controls": ["1048211"],
      "source": { "type": "product", "field": "counterparty_name" },
      "confirmed": false,
      "reason": "The product column holds the counterparty name."
    }
  ],
  "dataProductId": null,
  "updatedAt": "2026-10-21T09:12:44.000Z",
  "uploadedBy": "api:5d1c0e7a",
  "generated": 0,
  "lastUsedAt": null
}
GET/v1/doc-gen/templates/{id}

Field fields (each entry of fields[])

keystringThe stable key requests address the field by.
label, kindstringDisplay label, and the control kind: text, choice or date.
options, dateFormatstring[] | string | nullThe choices a dropdown control offers, and the Word date format of a date control such as dd.MM.yyyy.
where, zone, groupmixedThe document parts the field sits in (body, header or footer), its zone (header, address, reference, body, signature or footer), and the block of text it belongs to.
controlsstring[]The Word content controls (by id) this field fills.
sourceobjectWhere the value comes from. type selects the shape; see the overview for the types.
confirmedbooleanTrue once a person confirmed the source; until then it is the platform's suggestion.
reason, spotstring | object | nullWhy the platform suggested the source, and for a red passage of the template, spot.original with the words as the template prints them.
proposalobject | nullOn the template itself: the state of the latest proposal, null when none ran.
PATCH/v1/doc-gen/templates/{id}

Body fields (all optional)

namestringUp to 300 characters.
groupstring | nullUp to 200 characters; null clears it.
kindstring | nullletter or agreement.
pair_template_iduuid | nullThe companion template generated together with this one; null removes the link.
versionstring | nullUp to 60 characters.
fieldsobject[]Up to 500 changes, each { key (required, 1 to 200 characters), label (up to 120), source, confirmed, reason (up to 400, or null) }.
dry_runbooleanReturn the template as it would be and store nothing.

cURL: Re-source one field and confirm it (dry run)

curl -X PATCH "https://api.talonic.com/v1/doc-gen/templates/$TEMPLATE_ID" \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": [
      {
        "key": "addressee",
        "source": { "type": "reference", "column": "contact_name" },
        "confirmed": true
      }
    ],
    "dry_run": true
  }'
DELETE/v1/doc-gen/templates/{id}
Upload errors: 400 for a body that fails validation, 413 when the request exceeds the body limit, 422 when the file is not a Word document (.docx or .dotx) or cannot be read, and 502 when the template file could not be stored.

Frequently asked questions

Why is the file sent as base64 instead of multipart?+
The upload route takes a JSON body so a script or an MCP tool can send it without building a multipart form. The request body limit is 5 MB, and base64 adds a third to the size, so the Word file can be about 3.7 MB at most.
What does dry_run do on PATCH?+
The response is the template as it would be after the change, and nothing is stored. The same validation runs, so an unknown key, an unreadable source or a self-referencing condition still returns 422. Use it to check a generated field change before committing it.
What happens to a companion template when I delete its pair?+
The companion template that named the deleted one as its pair loses that link and otherwise stays as it was. Batches already generated from the deleted template keep their documents and history.