cuda and on a CPU machine otherwise. You get a scorecard, every evaluator’s value with its confidence interval, and the run directory as one archive.
A sim run is reproducible. Its manifest hash identifies it: the same spec, files and Kite version give the same hash. Its run hash covers every episode’s trace, so two runs that behaved the same have the same run hash.
Beta. Sim runs are open to every account and charged by the minute (see Pricing). Their shapes can still change before they are stable, without a new
Kite-Version. Changes are announced before they ship.Check a spec first
POST /v1/sim_runs/validate runs every check a run would, for free, and creates nothing. It plans the spec, confirms every file it names is accounted for, and quotes the price.
A spec is YAML. This one runs a scripted pick on the demo scene, three episodes, scored by the evaluators Kite ships:
smoke.yaml
../evals is a folder Kite ships, so you name it instead of uploading it:
400 spec_invalid with the field in param, and details.kite_code, details.remediation (the fix) and details.location (the file and line).
Files
files maps each path the spec names, as it names it, to where its bytes come from. A path with no entry is 400 files_required, which lists every missing path in details.files.
Only Python that Kite ships runs on Kite’s machines. Evaluators and task files must be ones Kite ships, or the request is refused with
code_not_allowed.
Create a run
POST /v1/sim_runs takes the same body, plus optional options and label. It answers 202 with a queued run. Send an Idempotency-Key header so a retry can’t run twice.
You can have two runs building at once (
429 concurrency_limit_exceeded past that).
Track progress
GET /v1/sim_runs/{id} returns the run, live. status goes queued → processing → succeeded, failed or canceled. queued includes waiting for a machine: an L4 can take minutes to free up. While processing, phase says what it is doing (materializing, planning, fetching, running, verifying, packaging) and episodes how many are done. Poll every few seconds, or subscribe to the sim_run.succeeded, sim_run.failed and sim_run.canceled webhooks.
Once it has succeeded, result holds the run’s identity and what it measured:
GET /v1/sim_runs/{id}/report returns the full scorecard: every evaluator’s value, interval and count, and what was not measured. GET /v1/sim_runs/{id}/logs?tail=200 returns what the run printed, while it runs and after.
Download the run
Oncesucceeded, download links the run directory as one archive:
url is a signed link, valid for an hour. Fetch it without your API key, check the checksum, and extract. The archive unpacks to <run id>/:
GET /v1/sim_runs/{id}/archive redirects to a fresh link, and GET /v1/sim_runs/{id}/files lists every file with its sha256.
Without writing HTTP
The CLI finds the files a spec names on your disk and sends each one: by hash when Kite ships it, inline otherwise.--wait --out waits for the run, downloads it, verifies its checksum, and unpacks it to ./runs/<run id>/. A checkpoint on the Hugging Face Hub goes as a reference: --hf PATH=OWNER/NAME@COMMIT:FILE. AI agents get the same through the kite_sim_* tools of the MCP server.
Cancel and resume
POST /v1/sim_runs/{id}/cancel stops a queued or processing run. It reads canceling until its machine has stopped, then canceled. POST /v1/sim_runs/{id}/resume runs a failed or canceled run again from its request, as a new attempt.
Pricing
A run costs the minutes its machine runs: 2,000 tokens an hour on an L4 and 5,000 tokens an hour on a CPU machine, counted in whole minutes. A create reserves the run’s cap, and when the run ends the minutes it didn’t use come back. A run that succeeded pays its minutes. One you canceled pays the minutes it ran. One that failed, or never got a machine, costs nothing. Validation is free. A balance short of the cap is402 insufficient_tokens, with details.tokens_required; lower options.max_minutes or top up.
Errors
The sim run object
Every endpoint is in the API reference.