Versioning & Drafts
Schema versioning in Talonic uses a workshop system with three states: Live (current published version, read-only), Workshop (mutable draft for editing), and Version History (an append-only timeline with diff summaries). When promoting a draft, the system detects breaking changes (field removals, type changes) and warns you before they reach production.
Start by editing fields in the Workshop draft, then use Test Extraction to compare draft results against the live version before publishing. The Version History timeline lets you review diff summaries between any two versions, making it easy to trace when a field was added, renamed, or removed and understand the impact on downstream jobs.
The versioning system is append-only — every time you publish a draft, it creates a new immutable version and the previous version is preserved in the timeline. This means you can always go back and review the exact schema that was used for any historical job. The diff view highlights added fields, removed fields, type changes, and updated instructions, giving you a clear picture of how your schema evolved.
Use the workshop system to iterate safely on your schema without disrupting production jobs. A common workflow is to add a new field in the Workshop, run a Test Extraction on a few documents to verify it produces correct values, then publish when satisfied. If a downstream integration depends on a specific field, the breaking change detection will warn you before you accidentally remove or rename it.
# List published versions, newest first:
curl -s "https://api.talonic.com/v1/schemas/a1b2c3d4-e5f6-7890-abcd-ef1234567890/versions" \
-H "Authorization: Bearer $TALONIC_API_KEY"
# Diff version 2 against version 3:
curl -s "https://api.talonic.com/v1/schemas/a1b2c3d4-e5f6-7890-abcd-ef1234567890/versions/diff?from=2&to=3" \
-H "Authorization: Bearer $TALONIC_API_KEY"The version history is a complete audit trail of your schema evolution. Each version snapshot captures the full field set, data types, instructions, reference tables, format constraints, and modifiers as they existed at publish time. When investigating a historical job result, you can always reconstruct the exact schema configuration that produced it by looking up the version number referenced in the job run metadata. This traceability is critical for compliance workflows and data governance requirements where you need to prove exactly what extraction rules were in effect at any point in time.
Teams with strict governance requirements often ask whether publishing a schema version can require a second approver. Today it cannot: promotion takes effect as soon as a user confirms it, and the Change Review tab in Workspace Settings does not hold schema versions (its approval workflow is not active yet). The practical checkpoint is the draft itself: keep changes in a named Workshop draft, test them, and agree internally on who promotes. Breaking-change detection still forces an explicit acknowledgment before a field removal, rename, or type change goes live.
Draft lifecycle and limits
A draft is forked from the current published version, or from the schema's live fields when nothing has been published yet, and is edited in isolation until it is promoted or discarded. A schema can hold up to 10 active drafts at once, and draft names must be unique among the active drafts of that schema. Only active drafts can be edited, tested, or promoted; a promoted or discarded draft stays in the list for reference but is closed. Several drafts can coexist, which lets two people prepare unrelated changes without overwriting each other, but each promotion is compared against whatever version is live at that moment.
Promotion is atomic. The schema row is locked, the next version number is assigned, the draft's fields replace the live fields, and the draft is marked promoted, all in one transaction, so two simultaneous promotions cannot produce the same version number. Each version records who promoted it, when, the source draft, an optional note, and a diff summary of the fields added, removed, and modified. When the diff is breaking, the first promotion attempt does not publish; it returns the diff with requires_acknowledgment and the affected fields, and the schema editor asks you to confirm before promoting again.
Diffs compare fields by their field name. For each field present in both versions, the diff checks the display name, data type, description, required flag, and reference table. A change is breaking when a field is removed or its data type changes. Because fields are matched by name, renaming a field's machine name shows up as one removal plus one addition and is therefore breaking, while changing only its display name is a non-breaking modification. Entries are sorted with removals first, then modifications, additions, and unchanged fields.
{
"entries": [
{
"fieldName": "po_reference",
"status": "removed",
"liveField": { "field_name": "po_reference", "data_type": "string" },
"draftField": null,
"changes": []
},
{
"fieldName": "total_amount",
"status": "modified",
"liveField": { "field_name": "total_amount", "data_type": "string" },
"draftField": { "field_name": "total_amount", "data_type": "number" },
"changes": [
{ "property": "data_type", "oldValue": "string", "newValue": "number" }
]
},
{
"fieldName": "due_date",
"status": "added",
"liveField": null,
"draftField": { "field_name": "due_date", "data_type": "date" },
"changes": []
}
],
"fieldsAdded": ["due_date"],
"fieldsRemoved": ["po_reference"],
"fieldsModified": ["total_amount"],
"isBreaking": true
}Schemas authored in the Spec composer have a second version line. A Spec's published versions, the "v3" shown in the composer, are listed by GET /v1/specs/{id}/versions, newest first, with a content hash and an is_materialized flag marking the version whose configuration is live. The /v1/schemas/{id}/versions routes described on this page read the template version history, which a Spec-authored schema does not advance, so for those schemas that list is normally empty. Use the spec_id and spec_version fields on a schema response to cross from one ID to the other.