Response shape for the read routes (GET detail / list). Runs are read-only to clients.
credits is the customer-facing consumption for the run: the metered
cost_micro_usd COGS converted to whole credits (half-up, the same
ledger conversion), so a run detail can show credits without the dashboard
doing token→cost math. input_tokens / output_tokens / cost_micro_usd
remain on the payload for internal + admin callers (audit precision) but are
never rendered on a normal-user screen (per pricing-v2 §8a).
Frozen credits travel through private state, leaving snapshot columns absent from queryable fields.
checkpoint is deliberately NOT here: it is the run's full saved loop
state (message history, tool schemas, the pending tool-call vector with raw
arguments), i.e. runtime-internal data, exactly like pending_snapshot and
sandbox_seconds_used. Exposing it handed every runs:read holder the raw
pending args the approval surfaces redact per caller. The run timeline is served
by the nested messages / tool-calls / approval reads instead.
message_excerpt is the first line of the opening message of a DIRECTED run
(mention/DM/message), so a run list can say what was asked rather than only how it
arrived. It is not a column on this table — the text lives in the run's first user
Message row — so it is attached by the LIST route alone
(routers.runs._attach_message_excerpts) and is absent from the detail response,
whose caller reads the transcript itself. Like credits it is derived, so it can
never be named in fields=. A scheduled run's instruction is NOT carried here:
that text is trigger_context.prompt, which stays approver-gated.