Skip to main content
A run is the unit of work in OpenType: one POST /v1/runs request and one stored record. A decision run makes exactly one model call. This page explains what a run returns, the states it moves through, what happens when you send the same request twice, and how a stored run differs from the live response. Read it before you write retry logic or store run results in your own database.

Kinds

The kind field picks what a run does. verdict is the default when kind is absent, so always send "kind": "decision". Neon 1.1 serves decision runs only; see Models and pricing. Fields that belong to the other kind are refused with 400 invalid_body, and the message names the fix. For example, system on a decision run gives “system is only valid on a verdict run; use instructions”. Unknown fields are refused too. max_output_tokens is required on every run and must be greater than zero.

States

POST /v1/runs is synchronous. It admits the run as pending, calls the model, settles the run, and only then answers 200 with the final record. You do not need to poll a fresh request. A run that fails before any model served it (for example 503 decision_unavailable or 504 deadline_exceeded) is not charged: the hold on your credit is released. Its record stays pending, so retry that request with a new Idempotency-Key; see Replays.

The response

A live response to a completed decision run:
Absent optional fields are omitted from run responses, not sent as null.

Replays

POST /v1/runs requires an Idempotency-Key header of 1 to 255 bytes. The key is unique within your organization and never expires. OpenType compares the new request with the run already stored under that key: “The same body” means the same input (state, or system and messages), the same kind, and the same contract: instructions, questions in order, draws and think_tokens (or schema). Changing max_output_tokens or deadline_ms alone does not make it a different request. A replay is never charged, and it is never refused for credit or quota. Two rules follow:
  • Retry a network failure with the same key. If the first request completed, you get its result without paying twice.
  • Retry a 503 or 504 with a new key. A run that failed before a model served it stays pending, and the old key answers 202 with that run on every replay.
This sends a run, then sends the same request again with the same key and gets the stored run back:
The second response is the stored run, so it has no cost_basis and its decision has no model or stages. The Idempotency guide covers key design and retry loops.

Stored runs are thinner

Every run is stored under its run_id. What you can read back depends on the route: If you need the full live record, store the POST response yourself. For per-run cost and token detail later, use GET /v1/usage/runs/{run_id}. GET /v1/runs lists your organization’s runs newest first, with limit (default 20, 1 to 100) and offset (default 0). See Pagination.

Limits on every run

The full table, including question and verdict schema bounds, is on Limits.
  • Decision questions - what goes in questions and what comes back in decision.
  • Idempotency - choose keys and write a retry loop that never pays twice.
  • Polling - read a stored run back with GET /v1/runs/{run_id}.
  • Error handling - which errors to fix and which to retry.
  • Limits - every bound on a run in one place.