User Templates
User templates are the primary way to define your output structure. Schemas are created and edited in the Spec composer (/specs) via the Extraction stage's schema editor. Templates give you complete control over which fields appear in your output, how they are extracted, and what validation rules apply. Unlike generated schemas, templates are executable: once published, they can be used to run Jobs, and they are also the schema a Spec is composed over. A template plus a composed rail (Data Policies, validation checkpoints, assembly) is a Spec, which runs as a production Pipeline on the engine.
- Create template — Give it a name and description.
- Add fields — Specify display name, data type, and optionally extraction instructions.
- Map to registry — Automatic matching — exact matches auto-apply, semantic matches need confirmation.
- Add reference tables — For code fields (e.g., country name → ISO code), upload key-value pairs.
- Publish — Create an immutable version snapshot ready for job execution.
Most teams start by importing an existing spreadsheet or CSV as a template baseline, then refine field types and add extraction instructions. Once you publish a version, it becomes immutable and available for job execution — any further changes happen in a new Workshop draft, keeping your production schema stable while you iterate.
When adding fields, take advantage of the automatic registry matching system. Fields with names that match existing registry entries are linked instantly, inheriting the AI-synthesized extraction instruction. For fields that do not match, write a clear manual instruction describing exactly what the AI should extract from the document. Well-written instructions are the single biggest lever for extraction accuracy.
For best results, keep templates focused on a single document type or closely related group of types. A template with 10-20 well-defined fields will produce higher accuracy than one with 50+ fields spanning unrelated domains. If you need different field sets for different document types, create separate templates and run targeted jobs for each.
curl -X POST https://api.talonic.com/v1/schemas \
-H "Authorization: Bearer $TALONIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Invoice Schema",
"description": "Standard invoice fields for AP processing.",
"definition": {
"properties": {
"invoice_number": {
"type": "string",
"title": "Invoice Number",
"description": "Unique identifier on the invoice."
},
"vendor_name": { "type": "string", "title": "Vendor Name" },
"total_amount": { "type": "number", "title": "Total Amount" }
}
}
}'{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"short_id": "SCH-A1B2C3D4",
"spec_id": null,
"spec_version": null,
"spec_materialized_version": null,
"name": "Invoice Schema",
"description": "Standard invoice fields for AP processing.",
"definition": {
"type": "object",
"properties": {
"invoice_number": {
"type": "string",
"description": "Unique identifier on the invoice.",
"title": "Invoice Number"
},
"vendor_name": { "type": "string", "title": "Vendor Name" },
"total_amount": { "type": "number", "title": "Total Amount" }
}
},
"field_count": 3,
"version": 1,
"created_at": "2026-04-25T14:30:00.000Z",
"updated_at": "2026-04-25T14:30:00.000Z",
"links": {
"self": "/v1/schemas/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"extractions": "/v1/extractions?schema_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"dashboard": "https://app.talonic.com/schemas/user/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}POST /v1/schemas accepts the field set in three shapes. The first is JSON Schema, as above: a definition with a properties object, where each property's title becomes the display name, type the data type, and an optional top-level required array marks required fields. The second is a flat key-type map such as { "vendor_name": "string", "total_amount": "number" }, accepted when every value is one of string, number, boolean, date, enum, array, or object. The third is a fields array of objects with field_name, display_name, data_type, description, and is_required. If you send a definition or fields array that produces no fields, the request fails with a 400 and nothing is saved.
curl -X POST https://api.talonic.com/v1/schemas \
-H "Authorization: Bearer $TALONIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Invoice Schema (flat)",
"definition": {
"invoice_number": "string",
"vendor_name": "string",
"invoice_date": "date",
"total_amount": "number"
}
}'
# Each key becomes a field whose title is the key itself.
# Rename display names later in the schema editor.After creating a schema via the API, you can update it with PUT /v1/schemas/{id}, which replaces the name, description, and field definition. Note that when definition.properties is provided, all existing fields are replaced, so send the complete field set on every update. Registry matching and publishing remain app workflows in the Spec composer: trigger a Rematch from the schema editor, then publish an immutable version when ready. The API path is useful for teams that synchronize template definitions across environments.
Every schema route accepts either the full UUID or the short ID shown in the app, such as SCH-A1B2C3D4, which is the first eight characters of the UUID. GET /v1/schemas is cursor-paginated and takes a search parameter that matches the schema name. Schema names are capped at 100 characters. The response also carries spec_id, spec_version, and spec_materialized_version: when a schema was authored in the Spec composer, these point to the owning Spec and its published head, because the Spec's own ID differs from the schema ID. The version field is a separate legacy counter and stays at 1 for schemas created through the API.
A schema that is managed by a Spec document is read-only through the public API. PUT, PATCH, and DELETE on such a schema answer 409 Conflict, because the next Spec publish would overwrite any change made outside the composer. Edit those schemas in the Spec composer and publish there. Schemas created through POST /v1/schemas are not owned by a Spec and can be updated or deleted freely; a successful delete returns { "deleted": true, "id": "..." }.
PUT or PATCH that includes definition.properties or a non-empty fields array deletes the existing fields and recreates them from the name, title, type, description, and required flag only. Manual instructions, reference tables, and registry mappings set in the schema editor are not carried over, and every field starts unmatched again. Send only name or description when you want to rename a schema without touching its fields.