# Runs

A run is one task given to a mech. Each run gets a fresh sandbox that starts from the mech's latest
checkpoint.

## Submitting

`POST /v1/mechs/{id}/runs` with `{ "input": "..." }` and an `Idempotency-Key` header. The response is `202`
with the run. Optional `settings` override the mech's `instructions` and `reasoningEffort` for this run
only.

A mech runs one task at a time. Submitting while a run is active returns `409`. Reusing an idempotency key
with different input or settings also returns `409`; reusing it with the same request returns the original
run.

## Statuses

| Status       | Meaning                                                 |
| ------------ | ------------------------------------------------------- |
| `queued`     | Accepted; checking credits and preparing the sandbox.   |
| `running`    | The mech is working.                                    |
| `cancelling` | Cancellation was requested; the sandbox is stopping.    |
| `completed`  | Finished, and the new checkpoint is saved.              |
| `failed`     | Stopped with an error; the previous checkpoint is kept. |
| `cancelled`  | Stopped on request; the previous checkpoint is kept.    |

If the mech does not have enough credits, the run fails with an error that says so. Add credits and submit
again.

## Events

`GET /v1/mechs/{id}/runs/{runId}/events` streams server-sent events:

- `run.status` carries `{ "status": ... }`.
- `run.output` carries `{ "text": ... }`, the full output observed so far.

Each event has an `id`. To resume after a disconnect, send `Last-Event-ID`, or pass `?after=<id>`. Events
are replayed from that point. Disconnecting never cancels a run.

## Reading and cancelling

`GET /v1/mechs/{id}/runs/{runId}` returns the run's status, output, profile, resolved settings, and the
checkpoint it started from. `POST /v1/mechs/{id}/runs/{runId}/cancel` requests cancellation; repeating it is
safe.
