Updated Apr 27, 2026
reference

Templates #

All /templates endpoints: list, create, get, update, delete, patch schema, clone, categories.

The /templates/* endpoints let you create, version, clone, and retire reusable extraction schemas. For the conceptual model see Templates; for a worked walkthrough see Working with templates.

GET /templates/

List templates owned by the authenticated account.

ParamTypeDefaultNotes
categoryenum–invoice, receipt, id_card, contract, custom.
searchstring–Case-insensitive prefix on name / description.
limitinteger501–100.
offsetinteger0Standard offset pagination.
bash
curl -u "$DD_KEY:$DD_SECRET" \
  'https://api.datadistillers.com/api/v1/templates/?category=invoice&limit=25'

GET /templates/categories

Returns the canonical list of category strings:

bash
curl -u "$DD_KEY:$DD_SECRET" \
  https://api.datadistillers.com/api/v1/templates/categories
json
["invoice", "receipt", "id_card", "contract", "custom"]

Use this to populate UI selectors instead of hard-coding the list.

POST /templates/

Create a new template.

json
{
  "name":        "Acme invoice v1",
  "description": "Standard US-format vendor invoices.",
  "category":    "invoice",
  "tags":        ["acme", "us-invoice"],
  "fields": [
    { "key": "invoice_number", "label": "Invoice #", "data_type": "string", "required": true },
    { "key": "total",          "label": "Total",     "data_type": "currency",
      "required": true,
      "validation": { "min_value": 0 } }
  ],
  "settings": { "confidence_threshold": 0.8, "ocr_engine": "default" },
  "is_public": false
}
FieldConstraints
nameMin length 3.
categoryDefaults to custom.
tagsString array.
fieldsArray of TemplateFieldDef.
settingsauto_save, confidence_threshold (0–1), ocr_engine.
is_publicDefaults to false.

Returns 201 Created + TemplateResponse.

TemplateFieldDef

FieldRequiredNotes
keyyes^[a-z0-9_]+$. Becomes the JSON key in the result.
labelyesHuman-readable.
data_typeyesstring, number, date, currency, table, boolean.
requirednoDefault false.
descriptionnoFree-form.
validationno{ regex?, min_value?, max_value?, required? }.

GET /templates/{id}

Returns the full template:

json
{
  "id":            "tpl_x8y9z",
  "user_id":       "usr_…",
  "name":          "Acme invoice v1",
  "slug":          "acme-invoice-v1",
  "description":   "Standard US-format vendor invoices.",
  "category":      "invoice",
  "tags":          ["acme", "us-invoice"],
  "schema_definition": { "fields": [...] },
  "status":        "active",
  "version":       3,
  "is_public":     false,
  "usage_count":   2841,
  "settings":      { "confidence_threshold": 0.8, "ocr_engine": "default" },
  "created_at":    "2026-04-01T00:00:00Z",
  "updated_at":    "2026-05-01T00:00:00Z"
}

PUT /templates/{id}

Replace template metadata: name, description, category, tags, status, settings, public flag. Does not modify the schema; use PATCH /templates/{id}/schema for that.

bash
curl -u "$DD_KEY:$DD_SECRET" \
  -X PUT https://api.datadistillers.com/api/v1/templates/tpl_x8y9z \
  -H 'Content-Type: application/json' \
  -d '{ "status": "archived" }'

All fields are optional. Anything you omit is left unchanged.

DELETE /templates/{id}

Soft-deletes by default. Pass ?hard_delete=true to permanently remove.

bash
curl -u "$DD_KEY:$DD_SECRET" \
  -X DELETE 'https://api.datadistillers.com/api/v1/templates/tpl_x8y9z'

curl -u "$DD_KEY:$DD_SECRET" \
  -X DELETE 'https://api.datadistillers.com/api/v1/templates/tpl_x8y9z?hard_delete=true'

Soft-deleted templates can't be referenced by new jobs but existing jobs are unaffected. Hard-delete is irreversible and breaks historical references.

Returns 204 No Content on success.

PATCH /templates/{id}/schema

Incrementally modify the field schema.

json
{
  "add_fields":   [
    { "key": "po_number", "label": "PO #", "data_type": "string" }
  ],
  "update_fields":[
    { "key": "total", "label": "Grand total", "data_type": "currency",
      "required": true, "validation": { "min_value": 0 } }
  ],
  "remove_fields": ["legacy_notes"]
}
OpBehavior
add_fieldsAppend. Returns 400 if a key already exists.
update_fieldsOverwrite by key. Returns 404 if any key is missing.
remove_fieldsDelete by key. Silently no-ops if missing.

Each successful patch increments version. In-flight jobs continue against the schema version they started under.

POST /templates/{id}/clone

Clone an existing template into a new draft.

bash
curl -u "$DD_KEY:$DD_SECRET" \
  -X POST https://api.datadistillers.com/api/v1/templates/tpl_x8y9z/clone \
  -H 'Content-Type: application/json' \
  -d '{ "new_name": "Acme invoice v2 (draft)", "include_settings": true }'

Body fields (all optional):

FieldDefaultNotes
new_name"{name} (clone)"Name for the clone.
include_settingstrueIf false, settings reset to defaults.

Returns 201 Created + TemplateResponse for the new draft (status draft, version 1, fresh id and slug).

Errors

StatusCause
400Validation failed (duplicate field key on add, invalid data_type, etc.).
401Auth missing or invalid.
403Template belongs to a different account.
404template_id or a key referenced by update_fields doesn't exist.
409Trying to delete a template currently in use by an in-flight job (hard-delete only).
422Body shape didn't validate.
Esc
↑↓Navigate↵OpenEscClose