Get a Spec
Read a Spec's structure: stages in authoring order and compiled execution order with the live IDs each points at, plus the Spec-field to schema-field mapping.
Returns the Spec's identity, version state, and structure. Structure and IDs only — no rules, gate configuration, prompts, samples, or ground truth.
Two stage lists, and they differ on purpose
The response carries the stages twice, because "the stages of a Spec" has two legitimate answers and collapsing them would misrepresent one of the two.
nodes— the rail as authored, in editing order. Includes stages that do not execute on their own, such as Source and Data Product.phases— the compiled execution plan, in run order. Source and Data Product produce no phase; a validation checkpoint expands to one phase per member gate. So this list is often a different length fromnodes.
rail_stage_id on a phase is the join key back to nodes[].node_id. It is also the per-step cost-attribution key, so a phase here lines up with its spend on GET /v1/usage/pipelines/{id}.
phases describes what a new run would execute, compiled from the current rail. To see what a specific run actually executed, read its frozen plan with GET /v1/pipelines/{id}?include=phases — same shape, same join key. Comparing the two shows configuration drift since that run./v1/specs/{id}Path parameters
/specs/{id} editor URL, not the schema ID.Get a Spec
curl -H "Authorization: Bearer $TALONIC_API_KEY" \
"https://api.talonic.com/v1/specs/e2144027-39c0-44e8-a196-72be1e360749"Response
Structure fields
Response (abridged)
{
"id": "e2144027-39c0-44e8-a196-72be1e360749",
"name": "Order Intake V25",
"schema_id": "2e3ddf8c-b9ab-4934-bb11-a371e9c5d7a8",
"version": 3,
"materialized_version": 3,
"schema": { "id": "2e3ddf8c-b9ab-4934-bb11-a371e9c5d7a8", "name": "Order Intake V25" },
"nodes": [
{ "node_id": "s-source", "position": 0, "type": "source", "name": "Source" },
{ "node_id": "s-schema", "position": 1, "type": "schema", "name": "Extraction",
"schema_id": "2e3ddf8c-b9ab-4934-bb11-a371e9c5d7a8" },
{ "node_id": "res-1", "position": 2, "type": "resolve", "name": "Resolution",
"policy_ids": ["fadfb451-7c2e-4849-a6f1-1f5d20116336"] },
{ "node_id": "rec-1", "position": 3, "type": "reconcile", "name": "Matching",
"matcher_stage_id": "d055b6f8-b324-4bc2-98ef-048e893ba762" },
{ "node_id": "s-deliver", "position": 4, "type": "deliver", "name": "Data Product" }
],
"phases": [
{ "number": 1, "phase_id": "phase-1", "type": "extraction", "name": "Extraction",
"rail_stage_id": "s-schema" },
{ "number": 2, "phase_id": "phase-2", "type": "resolution", "name": "Resolution",
"rail_stage_id": "res-1", "policy_id": "fadfb451-7c2e-4849-a6f1-1f5d20116336" },
{ "number": 3, "phase_id": "phase-3", "type": "matching", "name": "Matching",
"rail_stage_id": "rec-1", "matcher_stage_id": "d055b6f8-b324-4bc2-98ef-048e893ba762" }
],
"fields": [
{ "field_id": "c086cb2d-06bf-4c22-9007-c6e455531133",
"user_schema_field_id": "a3952c40-9f78-41a3-975f-57c5c79c3fae",
"name": "shipper_number", "type": "string" }
]
}Note that the five rail nodes compiled to three phases: Source and Data Product mark composition, they do not execute as phases of their own.
The field mapping
Every field in a Spec carries a field_id that is minted once and never changes, even when the field is renamed. Everything inside the Spec references that ID rather than the name: switch-lane conditions, assembly anchors, gate scopes, ground-truth keys, rule bindings. The values themselves live on a schema field row with its own ID.
fields pairs the two, which is what lets you resolve a Spec-level reference to actual extracted data. That pairing is not available on any other endpoint.
Errors
Error responses
schema: null with empty nodes, phases, and fields. That is a valid read, not an error.Frequently asked questions
Why do nodes and phases have different lengths?+
nodes is the rail as authored, including composition markers such as Source and Data Product that produce no phase. phases is the compiled execution plan, where a validation checkpoint expands to one phase per member gate. Join them on rail_stage_id.How do I tell what a specific run actually executed?+
GET /v1/pipelines/{id}?include=phases. That returns the plan frozen when the run was created, in the same shape and with the same rail_stage_id join key, so you can diff it against the Spec's current phases.How do I attribute cost to a stage?+
rail_stage_id is also the per-step cost-attribution key. Match it against the step IDs on GET /v1/usage/pipelines/{id}.What does a never-published Spec return?+
schema is null and nodes, phases, and fields are empty arrays. The header still carries version: null and materialized_version: null. Publish from the Spec editor to materialize it onto a schema and populate the structure.