Skip to main content
GET
Get Run Status

Result phases

A placement run finishes all of its deterministic scoring before it calls the model, and it persists that answer at the boundary. From that moment the response carries a result while status is still processing. Two fields describe it: Read output_phase for the distinction. Do not infer it from a status and timestamp combination.

final

The run’s terminal answer, complete. Served on completed and degraded runs, exactly as before this field existed.

deterministic_draft

The deterministic answer, served while status is still processing and the model leg runs. A draft is a real answer over part of the decision, not a preview. Its ranks, cluster labels, and overall_level values are real, but they are computed over the deterministic scoring dimensions only, with the weights renormalized over them. The model-scored dimensions are absent from a draft scorecard rather than empty or stubbed. Which dimensions are model-scored is set per engine by scoring_dimensions[*].method in the released engine configuration. Where the configuration also declares an assessed-weight floor, each scorecard carries assessed_weight_fraction: the share of the decision weight that scorecard covers. On a draft it reads well below 1, and on the final answer for the same solution it reads higher. The model-scored dimensions carry real weight, so the final answer can and does reorder the shortlist.
Never treat a draft as the final answer, and never stop polling on one. A draft is provisional until the same run_id returns output_phase: final.
A failed or cancelled run carries no output and no solutions, and therefore no output_phase, even when it reached the boundary before it failed. A draft is never served on a failed run. Only the placement engine has a deterministic boundary today. Runs on engines that have none omit both fields until they reach a terminal status.

Rendering a result before the run finishes

Keep the polling loop exactly as it is: it exits on completed, degraded, or failed. To show a result sooner, render the draft from inside the loop and replace it when the final answer arrives.
Two rules keep this correct:
  1. The loop exits on status, never on output_phase. A draft is not an exit condition.
  2. Anything you render from a draft is labeled provisional in your interface and is replaced by the final response for the same run_id.

Reading the stored output block

The run’s output object carries its own output_phase key, with the same two values as the envelope field. A consumer that reads the output block on its own, rather than the whole response, can still tell a draft from a final answer without the envelope. This applies to placement-engine output blocks.

Webhooks carry no phase

Webhook payloads do not carry output_phase or completed_deterministic_at. Every webhook event type is terminal, so a delivered run has already passed the boundary and its phase would be the constant final. There is no webhook event for the deterministic boundary. Polling is the only surface that serves a draft.

Authorizations

Authorization
string
header
required

Send the credential as Authorization: Bearer <key>.

Scoped partner credentials use the exclusive nxsk_v1_... namespace. Each scoped key is bound at issuance to one organization, one canonical named environment, an explicit engine set, and a least-privilege capability set. A malformed, unknown, rotated, or revoked nxsk_ key fails closed and is never retried as a legacy key.

Capabilities used by this API are runs:write, runs:read, engines:read, catalog:read, webhooks:manage, runs:defensibility:read, runs:test, conversations:use, and conversations:export. Operation descriptions name the required capability. Grandfathered nx_live_... and nx_test_... keys retain their existing broad access during the compatibility window.

Path Parameters

run_id
string<uuid>
required

The run identifier returned by POST /api/v1/engines/{engine_slug}/runs.

Response

Current run status and results (if completed).

run_id
string<uuid>
required

Stable run identifier.

status
enum<string>
required

Current run status. queued and processing are non-terminal: keep polling. completed, degraded, failed, and cancelled are terminal. degraded carries the same output shape as completed plus output.degradation_reason: treat it as a successful response with a warning, not as a state to keep polling on.

Available options:
queued,
processing,
completed,
degraded,
failed,
cancelled
environment
enum<string>
required

Environment the run executed in.

Available options:
test,
live
attempt
integer
required

Execution attempt count. A terminal value of 1 means no worker retry.

Required range: x >= 0
created_at
string<date-time>
required

RFC 3339 timestamp when the run was created.

engine_type
string

Runtime engine type. Omitted on legacy rows without engine metadata.

engine_version
string

The released engine version this run executed against (major.minor), resolved from the engine_version pin at submit time and frozen for the run's lifetime. Absent when the run used the engine's current configuration without a pin.

Example:

"1.3"

engine_config_version_hash
string

Immutable hash of the archived engine configuration this run executed. Resolved and frozen at submission alongside engine_version. Absent on legacy unstamped runs.

Example:

"297c960d80b848c9"

stage
string

Last known pipeline stage (e.g. EVALUATE, FILTER).

output
object

Run summary. Present on terminal runs, and on a processing placement run that reached the deterministic boundary. Read the top-level output_phase to know which answer it is.

duration_ms
integer

Duration of the final execution attempt in milliseconds.

total_duration_ms
integer

Wall-clock milliseconds from creation to terminal completion.

error
string

Error message on failed runs.

error_details
object

Structured failure details.

trace_id
string

Trace identifier for support correlation.

Pattern: ^[0-9a-f]{32}$
completed_at
string<date-time>

RFC 3339 timestamp when the run reached a terminal state.

completed_deterministic_at
string<date-time>

RFC 3339 timestamp when the run finished the deterministic part of its answer. It is stamped mid-run, before the model leg, so it is present while status is still processing, and it is what makes a draft servable ahead of completion. Omitted on runs that have not reached that boundary, and on engines that have no such boundary (only the placement engine has one today). Never present on webhook payloads: every webhook event is terminal and has passed the boundary already.

output_phase
enum<string>

Which answer output and solutions carry. Present whenever the response carries either of them, and omitted when it carries neither, so neither is ever read without its phase. Read this field for the distinction: do not infer it from a status and timestamp combination.

final is the run's terminal answer, complete. It is served on completed and degraded runs.

deterministic_draft is the deterministic answer, served while status is still processing. Its ranks, cluster labels, and overall_level values are real, but they are computed over the deterministic scoring dimensions only, with the weights renormalized over them. The model-scored dimensions are absent from a draft scorecard rather than empty, and they carry real weight, so the final answer can reorder the shortlist. Render a draft as provisional and keep polling.

A failed run carries neither field, and therefore no phase, even when it reached the boundary before it failed. Never present on webhook payloads: every webhook event is terminal, so the phase there would be the constant final.

Available options:
final,
deterministic_draft
solutions
object[]

Ranked solutions. Present on terminal placement runs, and on a processing placement run that reached the deterministic boundary. Read output_phase to know which answer they are.

warnings
object

Structured input-quality warnings. Present only when the released engine configuration enables warning exposure.