---
title: "Get a Spec's structure"
method: GET
path: "/v1/specs/{id}"
tags: ["Specs"]
---

# Get a Spec's structure

`GET /v1/specs/{id}`

## Request

- Base URL: `https://api.talonic.com`
- URL: `https://api.talonic.com/v1/specs/{id}`
- Auth: HTTP bearer

Spec identity, version state, and its stages with their live ids.

**Two stage lists, and they differ on purpose.**

- `nodes` — the rail **as authored**, in editing order. Includes
  non-executing stages 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 the two lists rarely have the same length.

`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 via `GET /v1/pipelines/{id}?include=phases` — same shape,
same join key.

Structure and ids only: no rules, gate configuration, prompts, samples,
or ground truth. Editing stays in the Spec editor.

## Path parameters

- `id` string, uuid, required

## Response `200`

Spec structure.

- SpecDetail
  - `id` string, uuid, required: The Spec id — the one in the `/specs/{id}` editor URL.
  - `name` string, required
  - `description` string, nullable
  - `schema_id` string, uuid, nullable: The schema this Spec is materialized onto — a DIFFERENT record from the Spec. `null` until the Spec is first published. Use it against `/v1/schemas/{schema_id}` and its sub-resources.
  - `version` integer, nullable: Published head version — what the editor shows. `null` if never published.
  - `materialized_version` integer, nullable: The version whose configuration is live on the schema — what a run executes. Normally equal to `version`; it lags when a publish was refused by the acknowledgement gate or a stale activation no-opped.
  - `materialized_at` string, date-time, nullable
  - `field_count` integer: Fields declared by the Spec.
  - `node_count` integer: Stages in the rail — the `nodes` count on the detail route. NOT the number of executable phases: a Source or Data Product marker compiles to no phase and a validation checkpoint expands to one per gate, so read `phases` on `GET /v1/specs/{id}` for the executable plan.
  - `created_at` string, date-time
  - `updated_at` string, date-time
  - `links` object
    - `self` string
    - `versions` string
    - `schema` string: Present only once the Spec has a schema.
    - `rail` string: Present only once the Spec has a schema.
    - `dashboard` string, uri
  - `schema` object, nullable
    - `id` string, uuid
    - `name` string
  - `nodes` SpecNode[]: The rail as authored, in editing order.
    - `node_id` string, nullable: Stage id within the Spec. `null` on a legacy rail that keyed stages by position.
    - `position` integer: 0-based index in the rail.
    - `type` 'source' | 'registry' | 'schema' | 'resolve' | 'valid' | 'assembly' | 'deliver' | 'dispatch' | 'reconcile' | 'sanitize' | 'triage' | 'switch'
    - `name` string, nullable
    - `schema_id` string, uuid: The schema this stage reads/writes.
    - `policy_ids` string[]: `data_policies` ids — resolve stages.
    - `validation_stage_ids` string[]: `validation_stages` ids — the gates a checkpoint contains.
    - `matcher_stage_id` string, uuid: `matcher_stages` id — reconcile stages.
    - `source_pipeline_id` string, uuid: Upstream run, when the Source stage injects from a pipeline.
  - `phases` SpecPhase[]: The compiled execution plan, in run order — what a NEW run would execute. Shorter or longer than `nodes`: Source and Data Product produce no phase, a checkpoint expands to one phase per gate.
    - `number` integer: 1-based execution order.
    - `phase_id` string, nullable: Positional id within the plan.
    - `type` string, nullable
    - `name` string, nullable
    - `rail_stage_id` string, nullable: The rail stage this phase compiled from — join key to `nodes[].node_id`, and the per-step cost-attribution key on `/v1/usage/pipelines/{id}`. `null` only for a rail-less extraction.
    - `policy_id` string, uuid: Resolution phases.
    - `validation_stage_id` string, uuid: Validation phases — one per gate.
    - `matcher_stage_id` string, uuid: Matching phases.
    - `scope` string: `pipeline` for a post-assembly phase; absent in the per-document loop.
  - `fields` SpecFieldMapping[]: Spec-field ↔ schema-field correspondence.
    - `field_id` string, uuid
    - `user_schema_field_id` string, uuid
    - `name` string, nullable
    - `type` string, nullable

## Other responses

- `401`: Missing or invalid API key.
- `404`: Spec not found

---

[API](https://skmtc.dev/talonic/apis/talonic-api.md) · [All operations](https://skmtc.dev/talonic/apis/talonic-api/llms.txt) · [OpenAPI document](https://skmtc.dev/talonic/apis/talonic-api/revisions/678fe5f8c9c3?raw)
