Learn
Your first run from code
Create an org key, start a session with one request, follow it live with curl, read its answer and send a follow-up into the same sandbox.
In this lesson you start an agent from a terminal with nothing but curl. The run needs no
repository, so you can skip GitHub for now. By the end you have one session that took two turns in
the same sandbox, and you know the four calls every integration is built from: create, stream, read
and follow up.
Get a key
1. Create the key
An org admin creates a key in the console under Settings → API keys, or from a signed-in
terminal with createApiKey:
rush http POST /o/$ORG/api-keys -d '{"name": "first-run"}'
The response carries the secret once, in secret, starting rk_live_. Rush never shows it again.
Leave out expires_at for a key that never expires, or set it up to a year out.
2. Keep it on your server
export RUSH_API_KEY=rk_live_...
export ORG=acme
The key acts as the admin who created it, in its own org. Its runs use that admin's own Claude or ChatGPT subscription first, then their Anthropic or OpenAI API key. With no account connected, a run uses the one-time $1 of models Rush covers for a first try.
Start a session
3. Send the request
A session needs a harness (claude, codex or opencode) and an input, the task:
curl -X POST https://api.prix.dev/o/$ORG/sessions \
-H "Authorization: Bearer $RUSH_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: first-run-1" \
-d '{"harness": "claude", "input": "Write a Python function that parses ISO 8601 durations, with tests. Run the tests and report the result."}'
4. Read the answer
The response is 202 with the session, before the sandbox is ready:
{"execution_id": "3f9c2a71d04b8e65", "org_id": "acme", "status": "allocating",
"harness": "claude", "created_at": "2026-10-09T00:56:44.205Z"}
Keep execution_id; every other call names it. The Idempotency-Key header makes a retry safe: the
same key and body return the session it first started instead of starting a second one.
export SESSION=3f9c2a71d04b8e65
Follow it live
5. Hold the event stream
curl -N https://api.prix.dev/o/$ORG/sessions/$SESSION/events \
-H "Authorization: Bearer $RUSH_API_KEY"
-N turns off curl's buffering so each frame prints as it arrives. Each frame is an event: line and
a JSON data: line. First come status events while the sandbox starts, then the agent's own
events: message, tool_use, tool_result, thinking and result.
event: status
data: {"status":"allocating","id":"3f9c2a71d04b8e65"}
event: done
data: {"status":"completed","output":"...","result":{"text":"All 9 tests pass.","structured":null,"schema_valid":null}}
The stream closes after done. If your connection drops, reconnect with the Last-Event-ID header
set to the last id you saw and the stream resumes after it. The
streamSession reference lists every event.
Read the session
6. Read the result
curl https://api.prix.dev/o/$ORG/sessions/$SESSION \
-H "Authorization: Bearer $RUSH_API_KEY"
getSession returns the record. The fields to look at first:
| Field | What it holds |
|---|---|
status |
completed, or paused once the sandbox parks between turns |
result |
The agent's final answer for the last finished turn, in full |
artifacts |
Files the agent saved, each with a download url good for an hour |
turns_count, tool_calls_count |
How much work the run did |
total_cost_usd |
What the run cost so far |
A field with no value is left out of the response, never sent as null.
Send a follow-up
7. Continue in the same sandbox
A run started with a key is resumable: when the turn ends, the sandbox parks with its disk and memory and costs nothing while parked. A follow-up wakes it where it left off:
curl -X POST https://api.prix.dev/o/$ORG/sessions/$SESSION/messages \
-H "Authorization: Bearer $RUSH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input": "Add support for week durations like P2W and rerun the tests."}'
The answer is 202 with the session, status: "running". The agent still has the file it wrote in
the first turn.
8. Wait for the turn to end first
Send a follow-up only after a turn ends. While a turn is running, a key's follow-up is refused with
409 TURN_ACTIVE; it is never queued. Wait for the stream's done event, or for status to leave
running, then send it.
A parked sandbox is kept for 7 days after it last parked, and each new turn starts that clock again.
Next
- Act on the result with a webhook replaces the open stream with a
signed
POSTto your server. - Runs and sessions covers every status a session moves through.