# Get a run

Source: https://docs.coderhelm.com/api/reference/runs/get-run

`GET /api/runs/{run_id}`

Returns one run in full: its status and current step, the pull requests and branches it opened, the files it changed, token use and cost, and the notes it wrote while working. Poll it to follow a run; a few seconds apart is plenty.

## Authentication

A team API key: `Authorization: Bearer chk_...`. The key needs the `view` scope. See [Authentication](https://docs.coderhelm.com/api/authentication).

## Parameters

### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `run_id` | string | yes | The run's id. |

## Responses

### 200

The run.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `applied_standards` | array of string | yes | The team standards the run was given in full ("always apply"). |
| `branch` | string or null | no | The branch the run pushed. |
| `branches` | array of string or null | no | Their branches, in the same order. |
| `cache_read_tokens` | integer | yes | Tokens read from the prompt cache. |
| `cache_write_tokens` | integer | yes | Tokens written to the prompt cache. |
| `close_reason` | string or null | no | Why it was closed. |
| `closed_at` | string or null | no | When it was closed (RFC 3339). |
| `closed_by` | string or null | no | Who closed the run on purpose. |
| `closed_from` | string or null | no | The status it had when it was closed. |
| `cost_usd` | number | yes | What the run cost in model usage, in US dollars, as recorded. |
| `created_at` | string or null | no | When the run started (RFC 3339). |
| `current_pass` | string or null | no | The step the run is on or ended on. |
| `duration_s` | integer or null | no | How long the run took, in seconds. |
| `error` | string or null | no | Why the run failed, when it did. |
| `files_modified` | array of string or null | no | The files the run changed. |
| `fix_location` | string or null | no | Where the fix belongs: `code`, or somewhere outside the code. |
| `lesson` | string or null | no | A lesson recorded for the repository when the fix was elsewhere. |
| `mcp_servers` | array of string or null | no | The MCP servers the run used. |
| `outside_change_report` | string or null | no | The report written when (part of) the fix is a change outside the code. |
| `pass_history` | array of RunPass or null | no | The steps it went through, in order. |
| `pass_history[].pass` | string or null | no | The step, such as `triage`, `plan`, `implement`, `test`, `security`, `pr`, `review`, `feedback` or `ci_fix`. |
| `pass_history[].started_at` | string or null | no | When it started (RFC 3339). |
| `pr_number` | integer or null | no | That pull request's number. |
| `pr_numbers` | array of integer or null | no | Their numbers, in the same order. |
| `pr_url` | string or null | no | The pull request the run opened. |
| `pr_urls` | array of string or null | no | Every pull request, when the work spans several repositories. |
| `progress_notes` | array of RunNote or null | no | Notes it wrote while working, in order. |
| `progress_notes[].message` | string or null | no | What it said. |
| `progress_notes[].timestamp` | string or null | no | When (RFC 3339). |
| `repo` | string or null | no | The repository, `owner/name`. |
| `status` | string or null | no | Where the run is: `pending`, `running`, `awaiting_ci`, `completed`, `failed`, `needs_input`, `needs_outside_change`, `cancelled`, `retried` or `closed`. Treat a value you don't know as in progress. |
| `ticket_id` | string or null | no | The ticket's key or issue number in its source. |
| `ticket_source` | string or null | no | What started it, such as `github`, `jira` or `alert`. |
| `title` | string or null | no | The ticket's title. |
| `tokens_in` | integer | yes | Input tokens, not counting cache reads and writes. |
| `tokens_out` | integer | yes | Output tokens. |
| `updated_at` | string or null | no | When it last changed (RFC 3339). |

Headers: `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`.

### 401

The key is missing, malformed, revoked or expired, or the person who made it left the team.

### 403

The key lacks the scope this endpoint needs (`missing_scope`).

### 404

No run with this id in the team.

### 429

Over the key's rate limit (`rate_limited`), or, for endpoints that start work, over the team's monthly token limit (`token_limit_reached`).

Headers: `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`, `Retry-After`.

### 500

Something failed on CoderHelm's side. Safe to retry reads.

## Example request

cURL:

```bash
curl -X GET 'https://api.coderhelm.com/api/runs/01JB8X6F4M2C9QZ3T7V5W1K0HA' \
  -H "Authorization: Bearer $CODERHELM_API_KEY"
```

TypeScript:

```ts
const res = await fetch("https://api.coderhelm.com/api/runs/01JB8X6F4M2C9QZ3T7V5W1K0HA", {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CODERHELM_API_KEY}`,
  },
});
if (!res.ok) {
  const { error, code } = await res.json();
  throw new Error(`${res.status} ${code}: ${error}`);
}
const data = await res.json();
```

Python:

```python
import os
import requests

headers = {
    "Authorization": f"Bearer {os.environ['CODERHELM_API_KEY']}",
}
res = requests.request("GET", "https://api.coderhelm.com/api/runs/01JB8X6F4M2C9QZ3T7V5W1K0HA", headers=headers)
if not res.ok:
    raise RuntimeError(f"{res.status_code}: {res.json().get('error')}")
data = res.json()
```

## Example response

```json
{
  "applied_standards": [
    "api-error-format"
  ],
  "branch": "coderhelm/web-42-login-rate-limit",
  "branches": [
    "coderhelm/web-42-login-rate-limit"
  ],
  "cache_read_tokens": 905112,
  "cache_write_tokens": 64002,
  "close_reason": null,
  "closed_at": null,
  "closed_by": null,
  "closed_from": null,
  "cost_usd": 1.42,
  "created_at": "2026-10-22T14:03:11Z",
  "current_pass": "pr",
  "duration_s": 734,
  "error": null,
  "files_modified": [
    "src/auth/login.ts",
    "src/auth/login.test.ts"
  ],
  "fix_location": "code",
  "lesson": null,
  "mcp_servers": [],
  "outside_change_report": null,
  "pass_history": [
    {
      "pass": "triage",
      "started_at": "2026-10-22T14:03:11Z"
    },
    {
      "pass": "implement",
      "started_at": "2026-10-22T14:05:40Z"
    },
    {
      "pass": "pr",
      "started_at": "2026-10-22T14:14:50Z"
    }
  ],
  "pr_number": 318,
  "pr_numbers": [
    318
  ],
  "pr_url": "https://github.com/acme/web/pull/318",
  "pr_urls": [
    "https://github.com/acme/web/pull/318"
  ],
  "progress_notes": [
    {
      "message": "Tests pass; opening the pull request.",
      "timestamp": "2026-10-22T14:15:02Z"
    }
  ],
  "repo": "acme/web",
  "status": "completed",
  "ticket_id": "WEB-42",
  "ticket_source": "jira",
  "title": "Add rate limiting to the login form",
  "tokens_in": 182340,
  "tokens_out": 20511,
  "updated_at": "2026-10-22T14:15:25Z"
}
```
