# Runs

Start a run, follow it, and read its trace.

## Create a run

```http
POST /v1/runs
```

```bash Terminal
curl https://api.kestrel.dev/v1/runs \
  -H "Authorization: Bearer $KESTREL_API_KEY" \
  -H "Idempotency-Key: ci-build-8812" \
  -d '{ "repo": "acme/web-app", "task": "Fix the flaky checkout test" }'
```

| Field | Type | Description |
|---|---|---|
| `repo` | string | Required. `owner/name` |
| `task` | string | Required. What to do, in plain words |
| `agent` | string | `claude-code`, `codex` or `command` |
| `from` | string | A snapshot name |
| `routing` | object | `{ "floor": "medium" }` |
| `evals` | object | `{ "repeat_tests": 20 }` |

```json Response
{
  "id": "run_8f2c",
  "repo": "acme/web-app",
  "task": "Fix the flaky checkout test",
  "status": "queued",
  "queue_position": 1,
  "created_at": "2026-11-01T09:12:44Z"
}
```

## Get a run

```http
GET /v1/runs/{id}
```

```json Response
{
  "id": "run_8f2c",
  "status": "pr_opened",
  "pull_request": { "number": 412, "url": "https://github.com/acme/web-app/pull/412" },
  "gate": [
    { "check": "build", "passed": true, "ms": 18400 },
    { "check": "tests", "passed": true, "ms": 48200 }
  ],
  "usage": { "sandbox_minutes": 11.2, "tokens": 412880, "cost_usd": 1.84 }
}
```

`status` is one of `queued`, `running`, `pr_opened`, `needs_review`, `cancelled` or `failed`.

## List runs

```http
GET /v1/runs?repo=acme/web-app&status=running&limit=20
```

## Cancel a run

```http
POST /v1/runs/{id}/cancel
```

A queued run leaves the queue. A running run stops at its next step and its sandbox is wiped.

## Get a trace

```http
GET /v1/runs/{id}/trace
```

Returns every step with its model, score, time, tool calls and tokens. See [Run traces](/runs/traces).
