Skip to content

API reference

Runs

12 routes of the published API contract, generated from it.

DELETE/v1/captures/{id}

Auth: API key

Destroy a preserved failure now. The bytes are deleted before the answer says so.

Parameters

idrequiredpath · string

Answer 200 · CaptureDeleted · application/json

bytesrequiredinteger
Bytes freed.
deletedrequiredboolean
deleted_atrequiredstring
RFC 3339.
okrequiredboolean
snapshot_idrequiredstring

GET/v1/runs

Auth: API key

List your org's runs, newest first. Pages are ?limit=N (1..=500, default 50) and ?cursor=; echo back next_cursor and stop when it is null.

Parameters

cursorquery · string
limitquery · integer

Answer 200 · RunList · application/json

next_cursorstring | null
Pass as ?cursor= for the next page; null on the last one.
runsrequiredRunView[]

POST/v1/runs

Auth: API key

Fork N sandboxes from one snapshot, optionally running a command in each. Refused with 409 cap_exceeded before anything starts if the quote exceeds spend_cap. ?wait_ms=N parks until the sandboxes are ready; honours Idempotency-Key.

Parameters

wait_msquery · integer
Idempotency-Keyheader · string
Makes a retried create safe: send the same key on every attempt of ONE create and it starts, and bills, once. Kept 24 hours per org. The same key with the same request (method, path and JSON body) answers with the first answer — same status, same ids — marked Idempotent-Replayed: true. The same key with a different request is refused with 409 idempotency_key_reused. A repeat that arrives while the first is still running waits for its answer, or gets 409 idempotency_key_in_use with Retry-After. Only an answer that started something is kept: a create refused before anything started leaves the key free. The SDKs send one for every create they make.

Request body RunCreate · application/json

allow_partialboolean
Start what fits now rather than refusing the whole run.
captureCaptureMode | null
countrequiredinteger
How many sandboxes, 1–1000.
execExecCreate | null
A command each sandbox runs as it starts; the sandbox's outcome is its exit.
gradeGradeSpec | null
Score each sandbox's work after its command.
grade_outputboolean | null
Keep what the grader prints: the last 16 KiB of its output, stdout and stderr together, in each graded sandbox's grade.output in the run report. Never a held-out grader's. Absent: the setting of the snapshot's default grader when the run uses it, otherwise off. Needs a grader (grade, or the snapshot's default).
labelsmap of string
Your own key/value labels, returned on every answer about the run.
networkNetworkRequest | null
optimize_forOptimizeFor | null
preemptibleboolean
The lower batch rate: the run's sandboxes can be stopped early.
secretsSecretUse[]
Stored secrets every command in the run's sandboxes receives.
snapshotrequiredstring
A snapshot id, alias, alias@commit7, or promigence/base.
spend_capnumber | null
The most the run may cost, in USD.
tierstring | null
The sandbox size. Default: the snapshot's.
timeout_msinteger | null
Each sandbox's lifetime in milliseconds. Default 15 minutes, at most 30 days.
verify_eachboolean
Re-run the snapshot's verification in each sandbox before it takes work.

Answer 200 · RunCreated · application/json

countrequiredinteger
How many sandboxes were asked for.
idempotent_replayrequiredboolean
True when this is the stored answer to an Idempotency-Key that was seen before, and no second run was started.
idempotent_replay_age_sinteger | null
Present when idempotent_replay is true: how many seconds ago that first answer was given, so a client can say which earlier request this repeats.
launchedrequiredinteger
How many were started. Fewer than count only with allow_partial, and the reason is in warnings.
preemptiblerequiredboolean
True when the run was posted at the preemptible rate: its sandboxes can be stopped early, and one stopped that way bills nothing.
quoterequiredQuote
A quote, per second: max_cost = Σ sandbox_count × seconds_per_sandbox × per_second_usd, where per_second_usd = vcpus × vcpu_second_usd + mem_gib × gib_second_usd. The most the run can cost if every sandbox runs its whole timeout; billing is for the seconds actually used.
run_idrequiredstring
sandboxesrequiredRunSandboxRef[]
snapshotrequiredstring
The snapshot, resolved.
snapshot_argrequiredstring
The snapshot as you named it — an id, an alias, or a path.
snapshot_idstring | null
The snapshot's id, as GET /v1/runs/{id} and the report give it: "" for the built-in base. Never null from this API; typed nullable for older answers.
spend_caprequirednumber
The most this run may cost, in USD.
staterequiredstring
"running".
tierrequiredstring
timeout_msrequiredinteger
warningsrequiredstring[]
What was **not** started and why, said when it is decided rather than discovered in the report.

GET/v1/runs/{id}

Auth: API key

One run and its sandboxes. ?wait_ms=N long-polls until the run is finished, or every sandbox has ended or outlived its command (kill_on_exit: false, command_outcome set).

Parameters

idrequiredpath · string
wait_msquery · integer

Answer 200 · RunView · application/json

canceledrequiredboolean
capacityCapacity | null
Only on GET /v1/runs/{id}: whether the waiting sandboxes can start, so a client that is already long-polling this route does not need a second call to find out why it is waiting.
capturerequiredstring
What this run does with a sandbox's state when it ends: on_failure | off | always. Stated on every answer, so nobody has to remember what the default was.
countrequiredinteger
How many sandboxes were asked for.
countsobject | null
How many sandboxes are in each state, keyed by state or by outcome. Only on GET /v1/runs/{id}.
execobject
The command each sandbox was created with, if any.
finished_atstring | null
RFC 3339; null while the run is still going.
gradeobject
The grading block this run was submitted with, if any.
grade_outputboolean
The run keeps what its grader prints (grade_output). Absent when it does not.
labelsrequiredmap of string
networkrequiredobject
The policy as it was submitted: "egress" / "none" stay strings, an allowlist comes back as the object you sent, normalised.
quoterequiredRunQuote
The price a run was quoted at, frozen when it started. The same numbers POST /v1/runs/quote answers with, without the per-line breakdown: a run that exists has one line.
run_idrequiredstring
sandboxesRunSandboxRef[] | null
Only on GET /v1/runs/{id}: one compact row per sandbox. The full records, with their timings, are GET /v1/runs/{id}/sandboxes.
snapshotrequiredstring
The snapshot this run forks from, as it was asked for.
snapshot_idrequiredstring
The same value under the name the validity report uses. Both are sent so a client can read either.
spend_caprequirednumber
The most this run may cost, in USD.
started_atrequiredstring
RFC 3339.
staterequiredstring
queued | running | completed | aborted.
tierrequiredstring
timeout_msrequiredinteger
Each sandbox's lifetime, in milliseconds.
verify_eachrequiredboolean
Whether each sandbox re-ran the snapshot's own verification before taking work.

DELETE/v1/runs/{id}

Auth: API key

Cancel the queue and kill every live sandbox of the run.

Parameters

idrequiredpath · string

Answer 200 · RunKilled · application/json

killedrequiredinteger
How many live sandboxes were killed. Each is billed for the seconds it used.
okrequiredboolean
run_idrequiredstring

POST/v1/runs/{id}/cancel

Auth: API key

Stop what is still queued. Live sandboxes keep running — use DELETE /v1/runs/:id for those.

Parameters

idrequiredpath · string

Answer 200 · RunCanceled · application/json

canceledrequiredinteger
How many queued sandboxes were dropped. They were never started, so they are not billed.
okrequiredboolean
run_idrequiredstring

GET/v1/runs/{id}/captures

Auth: API key

What is preserved of this run's failures, and when each goes.

Parameters

idrequiredpath · string

Answer 200 · CaptureList · application/json

capturesrequiredCaptureView[]
okrequiredboolean
run_idrequiredstring

POST/v1/runs/{id}/open

Auth: API key

Reopen a preserved failure as a new, live sandbox — the state the sandbox was in when it broke, not a re-run from the start. It has its own id and its own billing clock, out of what is left of the run's cap.

Parameters

idrequiredpath · string
Idempotency-Keyheader · string
Makes a retried create safe: send the same key on every attempt of ONE create and it starts, and bills, once. Kept 24 hours per org. The same key with the same request (method, path and JSON body) answers with the first answer — same status, same ids — marked Idempotent-Replayed: true. The same key with a different request is refused with 409 idempotency_key_reused. A repeat that arrives while the first is still running waits for its answer, or gets 409 idempotency_key_in_use with Retry-After. Only an answer that started something is kept: a create refused before anything started leaves the key free. The SDKs send one for every create they make.

Request body RunOpen · application/json · optional

sandbox_idstring | null
Which captured sandbox; required when the run has more than one capture.
spend_capnumber | null
timeout_msinteger | null

Answer 200 · RunOpened · application/json

coderequiredstring
The original's failure code.
committed_secondsrequiredinteger
Billable seconds committed to the new sandbox.
detailrequiredstring
expires_atrequiredstring
When the preserved state expires, RFC 3339.
failed_atrequiredstring
When the original failed, RFC 3339.
max_costrequirednumber
The most the new sandbox may cost, in USD.
okrequiredboolean
opened_fromrequiredstring
The failed sandbox this one was opened from.
outcomerequiredstring
The original's outcome.
ready_msrequirednumber
Milliseconds until it was ready.
run_idrequiredstring
sandbox_idrequiredstring
The new sandbox.
snapshot_idrequiredstring
The preserved state it was opened from.
staterequiredstring
"ready".
timeout_msrequiredinteger

POST/v1/runs/{id}/replay

Auth: API key

Re-fork the sandboxes whose outcome was an environment failure. Each replay is a new sandbox row with replay_of set, billed like any other sandbox; what the failed original is billed is in the run's report (cost), and a failure our side shows was ours is credited back.

Parameters

idrequiredpath · string
Idempotency-Keyheader · string
Makes a retried create safe: send the same key on every attempt of ONE create and it starts, and bills, once. Kept 24 hours per org. The same key with the same request (method, path and JSON body) answers with the first answer — same status, same ids — marked Idempotent-Replayed: true. The same key with a different request is refused with 409 idempotency_key_reused. A repeat that arrives while the first is still running waits for its answer, or gets 409 idempotency_key_in_use with Retry-After. Only an answer that started something is kept: a create refused before anything started leaves the key free. The SDKs send one for every create they make.

Request body RunReplay · application/json · optional

envmap of string
Values for the environment variables the run's command was started with. A run keeps their names, never their values, so a replay of a command that had any needs every one.
sandbox_idsstring[] | null
The sandboxes to replay; omitted, every one that may be replayed.

Answer 200 · RunReplayed · application/json

detailstring | null
Present only when there was nothing to replay, saying so.
okrequiredboolean
replayedrequiredinteger
run_idrequiredstring
sandboxesrequiredReplayRef[]

GET/v1/runs/{id}/report

Auth: API key

The validity report: every sandbox, its outcome, and whether the failure was the environment's or the task's. Run through your project's secret redactor before it is serialised.

Parameters

idrequiredpath · string

Answer 200 · Run · application/json

aliasstring | null
costrequiredCost
finished_atstring | null
forkrequiredForkStats
gradeGradeStats | null
The two pass rates and the **gap** between them. Absent when the run was not graded.
labelsmap of string
quoterequiredQuote
A quote, per second: max_cost = Σ sandbox_count × seconds_per_sandbox × per_second_usd, where per_second_usd = vcpus × vcpu_second_usd + mem_gib × gib_second_usd. The most the run can cost if every sandbox runs its whole timeout; billing is for the seconds actually used.
requestedrequiredRequested
run_idrequiredstring
sandboxesrequiredSandbox[]
schemarequiredstring
snapshot_idrequiredstring
spend_caprequirednumber
started_atrequiredstring
staterequiredRunState
totalsrequiredTotals

GET/v1/runs/{id}/sandboxes

Auth: API key

Only the sandboxes of a run. ?wait_ms=N long-polls until nothing is queued any more.

Parameters

idrequiredpath · string
wait_msquery · integer

Answer 200 · RunSandboxes · application/json

capacityrequiredCapacity
Whether this run's sandboxes can start, in the words a waiting caller needs. Three states: ok — nothing is waiting; arriving — sandboxes are waiting and should start within eta_s; blocked — they cannot start now, and the reason is named. A block is a refusal, and it arrives at once rather than after a countdown.
run_idrequiredstring
sandboxesrequiredSandboxView[]

POST/v1/runs/quote

Auth: API key

Price a run without starting one. No side effects, nothing reserved. Matched ahead of /v1/runs/:id, so a run can never be named quote.

Request body RunQuoteRequest · application/json

countrequiredinteger
1–1000.
preemptibleboolean
snapshotrequiredstring
spend_capnumber | null
tierstring | null
timeout_msinteger | null

Answer 200 · RunQuoteView · application/json

billingrequiredstring
per_second.
breakdownrequiredQuoteLine[]
countrequiredinteger
credits_availablenumber | null
Trial credits available, in USD; null when the organisation is not on a trial.
egressQuoteEgress | null
Data out, priced beside compute: the rate, what the month includes and what is left of it. max_cost does not cover it. null when the organisation's plan could not be read.
gib_second_usdrequirednumber
granularity_secondsrequiredinteger
max_costrequirednumber
The most the run can cost if every sandbox runs its whole timeout, in USD.
mem_gibrequiredinteger
min_billable_secondsrequiredinteger
per_hour_usdrequirednumber
per_second_usdrequirednumber
preemptiblerequiredboolean
quoterequiredQuote
The same quote, whole — what POST /v1/runs and the report echo back.
seconds_per_sandboxrequiredinteger
ceil(timeout_ms / 1000): what one full sandbox may bill.
snapshotrequiredstring
The snapshot as you named it.
snapshot_idstring | null
null for a snapshot this service holds no record of.
spend_caprequirednumber
The cap the run would be held to: the one you passed, or the organisation's default.
tierrequiredstring
timeout_msrequiredinteger
vcpu_second_usdrequirednumber
vcpusrequiredinteger
warningsrequiredstring[]
Anything that would make POST /v1/runs refuse this, said now.

Get started

Leave your work email and we will get you started.

See our Privacy Policy for how we use your email.