Skip to main content
Version: v5.6.1

Chain, chain hop and chain triage

Included from Basic tier

JSON:API types: chain (the index summary), chain_activity (one hop of a chain), chain_triage (the triage digest). All three verified in their serializers (endpoints_chains_index.go, endpoints_chains.go, endpoints_chains_triage.go).

The v2 OpenAPI document declares this resource's schema; the resource-field coverage gate holds this page to it.

A chain is a correlation cascade: every event, change and workflow run sharing one correlation id. The chain key is coalesce(correlation_id, id) — a pre-spine row is its own chain root at read time, so no backfill ever rewrites the large tables.

Endpoints​

VerbPathServes
GET/api/chainschain summaries inside a required time window, keyset-paginated on (last_activity_at, correlation_id) descending. 206 with meta.next_after when another page may exist.
GET/api/chains/{correlation_id}The full cascade as chain_activity hops, chronological (created_at, id — UUIDv7 ids break timestamp ties).
GET/api/chains/{correlation_id}/triageOne chain_triage resource — the server-side triage digest serving both the GUI Triage panel and opschain chains triage.

Visibility and redaction​

Hops are RBAC-filtered per viewer: a hop whose node path the viewer cannot read renders as a redacted stub (kind, depth, timestamp only), so the chain's shape survives without leaking another project's detail. Events with no event_node_path (system-wide events) render unredacted, matching the events index. A chain lists in the index only when the viewer can read at least one member; a summary's node_paths is narrowed to the readable ones.

chain (the index summary)​

Resource id = the correlation id. links.self = /api/chains/<id>.

AttributeTypeMeaning
correlation_idstringThe chain key (repeated from the id).
rootobjectThe chain's first hop (ordered by chain_depth, then objects before events): kind, summary, username (nullable), initiated_by_type (nullable), node_path (nullable), created_at.
first_activity_at / last_activity_atstringThe activity bounds (ISO8601, 6 fractional digits).
countsobjectMember tally by kind: changes, workflow_runs, events.
has_failuresbooleanTrue when any member event's type matches the failure shapes (api:*:error, api:*:system_error, api:*:pre_execution, error:*).
node_pathsarray of stringsThe involved node paths the viewer can read (capped at 10 per row before filtering).

Index parameters​

ParameterMeaning
sinceRequired (or filter[created_at_gteq]): a relative window <N>m, <N>h or <N>d. Clamped by the chains_max_window_days global setting (default 90 days); exceeding it is a named 422.
filter[created_at_gteq]The absolute-window alternative, RFC3339.
nodeAn absolute node-path prefix; matches a chain with ANY member on or under it, not just the root.
originRoot-origin filter: user, schedule, trigger or api. A root with no initiated_by_type counts as user.
has_failuresBoolean; keeps only failing chains.
limit1–200, default 50.
afterThe previous page's meta.next_after keyset cursor (<last_activity_at>,<correlation_id>).

chain_activity (one hop)​

Always present:

AttributeMeaning
kindevent, change or workflow_run.
created_atHop timestamp.
chain_depthCause depth within the chain.
redactedTrue when the viewer cannot read the hop's node path; the attributes below are then absent.

Present only when readable (null where the underlying column is null):

AttributeMeaning
summaryThe hop's one-line identity: the event type, or the change/run action path.
node_pathThe authorisation/display path (null for events without one).
caused_by_event_idThe causing event.
initiated_by_type / initiated_by_idThe initiator (e.g. workflow_step + its id).
source_type / source_idEvent hops: the stored polymorphic source.
usernameThe acting username (events fall back to the payload's username).
messageEvent hops: the payload's message/error/reason.
step_name / step_change_idEvent hops sourced from a step: the step's name and owning change.
author / executed_asEvent hops: the payload's author and run-as identity.
spawned_by_step / spawned_by_stageChange/run hops initiated by a workflow step: that step's name and its stage step's name.
template_versionA template label ("<template name> <version>") where the hop resolves one (a templated change, or a template-version-history event); null otherwise.
exchange_idEvent hops: the agent exchange the event evidences — the exchange_id of an info:agent:invoked, info:agent:chat or info:agent:adapter_transcript event (the last names the redacted adapter transcript at /api/projects/{project}/agents/{code}/adapter_transcripts/{exchange}); null otherwise.

Agent work on a chain​

A unit of agent work is one chain (the SDK-managed correlation scope, opschain docs ai-agents): invoking an agent's capability through the platform proxy stamps a correlation id on the exchange — inherited from the caller's X-Opschain-Correlation-Id header when it carries one (an integration relaying an incident's chain, a trigger), else minted for the invocation — and lands the info:agent:invoked root hop. Every call the agent then makes through its SDK inside that scope joins the chain automatically: each governed read (info:agent:request), a filed recommendation (info:recommendation:filed), the sealed adapter transcript (info:agent:adapter_transcript), a brokered model call (info:agent:model_call) and the change or workflow run it creates (the run row itself, initiated_by_type agent). A human accepting the recommendation later joins the accepted change to the same chain. The approvals inbox reads this chain back as the approval context's chain_summary, so an approver sees the lineage without leaving the inbox.

links.self points at the member (/api/events/<id>, /api/changes/<id> or /api/workflow_runs/<id>) on readable hops; redacted hops carry no links.

chain_triage (the digest)​

Resource id = the correlation id. Links: self, chain. Query parameter lines bounds each hop's log tail (1–200, default 40).

AttributeMeaning
failure_classThe chain's headline classification: none when nothing failed, otherwise the first failing hop's class — one of the folded object statuses error, system_error, aborted, cancelled, the whole-chain override pre_execution, event (an orphan error event with no failed parent object), or stalled.
attributed{runner, group} — the runner (and its registered group) every failure executed on, set only when all failing hops name exactly one runner; empty object otherwise.
failing_hopsThe failing members, each: id, kind, summary, node_path, failure_class, error (omitted when empty), runner (omitted when empty), log_tail (last N log lines, child steps included), links (self, and log_lines for change/run hops).

Per-hop failure_class values, verbatim: the folded statuses error, system_error, aborted, cancelled; event for orphan error events; pre_execution (never started — infrastructure, git or secrets) for a pre-execution rejection; and stalled for a non-terminal member with no dispatch-plane activity anywhere (no queued scheduler job, no live lease, no wait/approval gate, no live nested run) once the whole chain has been quiet for 2 minutes — the shape a mid-run server restart leaves behind. Its error text names the stuck step and the remedy. Hops the viewer cannot read never appear.

  • opschain docs events — the event members and their vocabulary.
  • opschain docs triggers — chains rooted in a trigger firing.