> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squasher.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Runs API

> Create, follow, and cancel hosted agent runs linked to shared investigations.

Use the agent runs API to start and track hosted fix and triage sessions.
Every create request must identify the requester before dispatch.

## Requester identity

`POST /agent-runs` requires one of:

* `requested_by` - `user:<id>` or `service:<name>`
* `user_id` - legacy user id, normalized as `user:<id>`

Optional `requested_by_email` must be a valid email address. If both
`requested_by` and `user_id` are sent, they must identify the same user.
User requesters are capped at 10 active `queued` or `running` agent runs and
receive `429` when the limit is reached.

## List agent runs

```text theme={null}
GET https://api.squasher.ai/v1/projects/{project_id}/agent-runs
```

Query parameters:

* `error_group_id` - optional error group UUID for fix-run history
* `intent` - optional `fix` or `triage`
* `limit` - optional result limit, default `50`, max `200`
* `thread_id` - optional shared conversation thread id

Response:

```json theme={null}
{
  "runs": [
    {
      "id": "11111111-1111-1111-1111-111111111111",
      "projectId": "7063a770-8cc6-4284-b5f9-c0cb19e6fa79",
      "intent": "triage",
      "status": "queued",
      "stage": "setup",
      "threadId": "c_abcdefghijklmnopqrst",
      "artifact": {},
      "errorGroupId": null,
      "incidentId": null,
      "sourceType": null,
      "sourceId": null,
      "requestedByType": "user",
      "requestedBy": "550e8400-e29b-41d4-a716-446655440000",
      "createdAt": "2026-04-24T00:00:00.000Z",
      "updatedAt": "2026-04-24T00:00:00.000Z",
      "startedAt": null,
      "completedAt": null,
      "lastError": null
    }
  ]
}
```

## Create an agent run

```text theme={null}
POST https://api.squasher.ai/v1/projects/{project_id}/agent-runs
```

JSON body:

```json theme={null}
{
  "intent": "triage",
  "requested_by": "user:usr_AbCdEfGhIjKlMnOp",
  "requested_by_email": "engineer@example.com",
  "error_group_id": "22222222-2222-2222-2222-222222222222",
  "thread_id": "c_abcdefghijklmnopqrst"
}
```

Pass `thread_id` to link the run to an existing project conversation. The same
run then remains discoverable from the web, Slack, API, and CLI investigation
record without copying model output between surfaces.

For `intent=fix` or `intent=triage`, include `error_group_id`. Fix runs also
require the project to have a linked GitHub repository:

```json theme={null}
{
  "intent": "fix",
  "requested_by": "user:usr_AbCdEfGhIjKlMnOp",
  "requested_by_email": "engineer@example.com",
  "error_group_id": "22222222-2222-2222-2222-222222222222"
}
```

Automatic runtime, deployment, and CI triage runs also appear in this API.

Responses:

* `201` - agent run created and queued
* `400` - invalid intent, missing identity, malformed `requested_by`, malformed `requested_by_email`, or missing error group context
* `404` - project or error group not found
* `429` - the user already has 10 active agent runs
* `502` - the API created the run but could not start execution

## Get an agent run

```text theme={null}
GET https://api.squasher.ai/v1/projects/{project_id}/agent-runs/{run_id}
```

Returns the agent run object shown in the list response plus
`lifecycleOutcomes`, an oldest-first record of customer-visible outcomes. The
timeline can include safe refusal, pull request open/update/merge/close,
deployment, and post-deploy recurrence.

Completed fix runs may include these validation fields in `artifact`:

* `testsPassed` - `true` or `false` when the isolated sandbox independently reran test commands; `null` when no executable command was available
* `testOutput` - bounded regression-test evidence, commands, exit codes, and output
* `ciPassed` - whether every registered GitHub check on the latest pull request commit passed
* `ciOutput` - bounded check names, conclusions, summaries, and details links
* `ciRepairAttempts` - the number of failed-CI repair iterations, up to three
* `verificationPassed` - whether the separate root-cause and diff verification accepted the fix
* `verificationRiskLevel` and `verificationSummary` - reviewer-facing verification context
* `verificationProvider` and `verificationModelId` - the independently recorded verifier identity
* `proposalUrl` - the resulting pull request URL, present only after validation and verification permit a PR

Missing or failed executable validation blocks the hosted agent from opening a
pull request. After a PR opens, failed CI returns to the same sandbox for a
bounded repair, independent test, push, and recheck loop. The run fails if CI
does not pass.

Lifecycle outcome details are deliberately narrow. They include useful review
and deployment references such as pull request URL, commit SHA, environment,
service, and timestamps. Raw webhook payloads, provider metadata, trace IDs,
fingerprints, credentials, prompts, and reasoning are not returned.

```json theme={null}
{
  "id": "11111111-1111-1111-1111-111111111111",
  "status": "completed",
  "artifact": {
    "testsPassed": true,
    "testOutput": "bun test: passed",
    "ciPassed": true,
    "ciOutput": "build: success",
    "ciRepairAttempts": 0,
    "verificationPassed": true,
    "verificationRiskLevel": "low",
    "verificationSummary": "The regression test covers the production failure.",
    "verificationProvider": "provider",
    "verificationModelId": "model-id",
    "proposalUrl": "https://github.example/acme/app/pull/42"
  },
  "lifecycleOutcomes": [
    {
      "id": "33333333-3333-4333-8333-333333333333",
      "kind": "pull_request_merged",
      "occurredAt": "2026-04-24T01:00:00.000Z",
      "summary": "Pull request merged.",
      "details": {
        "proposalUrl": "https://github.example/acme/app/pull/42",
        "commitSha": "abc123"
      }
    },
    {
      "id": "44444444-4444-4444-8444-444444444444",
      "kind": "deployed",
      "occurredAt": "2026-04-24T01:10:00.000Z",
      "summary": "Fix deployed.",
      "details": {
        "environment": "production",
        "serviceName": "checkout"
      }
    }
  ]
}
```

## Follow run events

```text theme={null}
GET https://api.squasher.ai/v1/projects/{project_id}/agent-runs/{run_id}/events?after=0&limit=100
```

Events are ordered by `sequence`. Persist the returned `nextAfter` cursor and
send it as `after` on the next request. `terminal` becomes `true` when the run
is completed, failed, or cancelled.

The journal contains lifecycle state, attempt count, linked thread id, and the
names of produced artifact fields. It intentionally excludes raw prompts,
reasoning, logs, diffs, test output, and artifact values. Fetch those through
the authorized run-detail workflow when needed.

Stages progress through `setup`, `context`, `execute`, `verify`, `pr`,
`finalize`, and `done`. A run may finish early or skip a stage when no safe
fix is available.

## Cancel an agent run

```text theme={null}
POST https://api.squasher.ai/v1/projects/{project_id}/agent-runs/{run_id}/cancel
```

Optional JSON body:

```json theme={null}
{ "reason": "user_cancelled" }
```

The response is the updated agent run.

## HTTP usage

```text theme={null}
curl https://api.squasher.ai/v1/projects/7063a770-8cc6-4284-b5f9-c0cb19e6fa79/agent-runs \
  -H "x-squasher-key: $SQUASHER_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "intent": "triage",
    "requested_by": "user:usr_AbCdEfGhIjKlMnOp",
    "requested_by_email": "engineer@example.com",
    "error_group_id": "22222222-2222-2222-2222-222222222222"
  }'
```

## CLI usage

List runs for a project, optionally filtering by intent or error group:

```bash theme={null}
squasher agent-runs list --project 7063a770-8cc6-4284-b5f9-c0cb19e6fa79
squasher agent-runs list --project 7063a770-8cc6-4284-b5f9-c0cb19e6fa79 --intent fix --error-group 22222222-2222-2222-2222-222222222222 --thread c_abcdefghijklmnopqrst --limit 10
```

Create a hosted fix or triage run with explicit requester identity:

```bash theme={null}
squasher agent-runs create --project 7063a770-8cc6-4284-b5f9-c0cb19e6fa79 --intent triage --requested-by user:usr_AbCdEfGhIjKlMnOp --requested-by-email engineer@example.com --error-group 22222222-2222-2222-2222-222222222222 --thread c_abcdefghijklmnopqrst
```

Inspect or cancel a run:

```bash theme={null}
squasher agent-runs get --project 7063a770-8cc6-4284-b5f9-c0cb19e6fa79 11111111-1111-1111-1111-111111111111
squasher agent-runs events --project 7063a770-8cc6-4284-b5f9-c0cb19e6fa79 11111111-1111-1111-1111-111111111111 --after 0
squasher agent-runs cancel --project 7063a770-8cc6-4284-b5f9-c0cb19e6fa79 11111111-1111-1111-1111-111111111111 --reason user_cancelled
```

Omit `--reason` to use the default cancellation reason, `user_cancelled`.

## Agent handoff

Agents should treat run creation and cancellation as write actions:

```text theme={null}
Review hosted Squasher agent runs for project <project_id>. List active runs first, inspect any run related to <error_group_id>, and ask before creating, canceling, or retrying a run.
```

Use MCP `search("agentRuns")` and `execute` for the same operations when an MCP client is connected.
