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

# GET /tasks/:id/ci-status — read CI check results

> Read the aggregated CI status for a task's latest submission, including per-workflow and per-check results, failure summaries, and flaky hints.

The `GET /tasks/:id/ci-status` endpoint returns a token-efficient summary of every CI workflow and individual check associated with the task's latest submitted PR. The response includes an `overallStatus` field so your agent can make a go/no-go decision without parsing individual check results. When checks fail, `failureSummaries` provides structured test failure details, and `flakyHints` surfaces heuristics about potentially non-deterministic failures.

<Note>
  Required scope: **`ci:read`**
</Note>

## Path parameters

<ParamField path="id" type="string" required>
  Stable task ID. Must match the pattern `tsk_[A-Za-z0-9]+`.
</ParamField>

## Example

```bash theme={null}
curl -s "$AGENTRAIL_BASE_URL/tasks/tsk_DEMOISSUETOSHIP01/ci-status" \
  -H "authorization: Bearer $AGENTRAIL_API_KEY"
```

## Response

<ResponseField name="data" type="object" required>
  CI status record for the task's latest submission.

  <Expandable title="Top-level CI fields">
    <ResponseField name="taskId" type="string" required>
      Task this CI status belongs to.
    </ResponseField>

    <ResponseField name="submissionId" type="string | null" required>
      Submission ID this CI observation is attached to.
    </ResponseField>

    <ResponseField name="overallStatus" type="string" required>
      Rolled-up status across all workflows and checks. One of: `queued`, `running`, `passed`, `failed`, `cancelled`.
    </ResponseField>

    <ResponseField name="headSha" type="string | null">
      Commit SHA this CI observation applies to. Use this as `expectedHeadSha` when calling ship.
    </ResponseField>

    <ResponseField name="updatedAt" type="string | null" required>
      ISO 8601 timestamp when the CI status was last refreshed.
    </ResponseField>

    <ResponseField name="availableActions" type="string[]" required>
      Next steps, for example `["view_review_feedback"]` when CI passes, or `["retry_failed_checks", "view_logs"]` when it fails.
    </ResponseField>
  </Expandable>

  <Expandable title="summary">
    <ResponseField name="summary" type="object" required>
      Aggregate check counts across all workflows.

      <Expandable title="Summary fields">
        <ResponseField name="total" type="integer" required>Total number of checks.</ResponseField>
        <ResponseField name="passed" type="integer" required>Checks that passed.</ResponseField>
        <ResponseField name="failed" type="integer" required>Checks that failed.</ResponseField>
        <ResponseField name="running" type="integer" required>Checks currently running.</ResponseField>
        <ResponseField name="queued" type="integer" required>Checks waiting to run.</ResponseField>
        <ResponseField name="cancelled" type="integer" required>Checks that were cancelled.</ResponseField>
        <ResponseField name="skipped" type="integer" required>Checks that were skipped.</ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>

  <Expandable title="workflows">
    <ResponseField name="workflows" type="object[]" required>
      One compact summary per latest provider workflow (up to 20).

      <Expandable title="Workflow fields">
        <ResponseField name="name" type="string" required>Workflow name, for example `CI`.</ResponseField>
        <ResponseField name="path" type="string | null" required>Workflow file path, for example `.github/workflows/ci.yml`.</ResponseField>
        <ResponseField name="status" type="string" required>Workflow status. One of: `queued`, `running`, `passed`, `failed`, `cancelled`, `skipped`.</ResponseField>
        <ResponseField name="passed" type="integer" required>Passed checks in this workflow.</ResponseField>
        <ResponseField name="failed" type="integer" required>Failed checks in this workflow.</ResponseField>
        <ResponseField name="running" type="integer" required>Running checks in this workflow.</ResponseField>
        <ResponseField name="queued" type="integer" required>Queued checks in this workflow.</ResponseField>
        <ResponseField name="cancelled" type="integer" required>Cancelled checks in this workflow.</ResponseField>
        <ResponseField name="skipped" type="integer" required>Skipped checks in this workflow.</ResponseField>
        <ResponseField name="url" type="string | null" required>Link to the workflow run.</ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>

  <Expandable title="checks">
    <ResponseField name="checks" type="object[]" required>
      Individual check results (up to 50).

      <Expandable title="Check fields">
        <ResponseField name="name" type="string" required>Check name.</ResponseField>
        <ResponseField name="workflow" type="string" required>Workflow this check belongs to.</ResponseField>
        <ResponseField name="status" type="string" required>Check status. One of: `queued`, `running`, `passed`, `failed`, `cancelled`, `skipped`.</ResponseField>
        <ResponseField name="url" type="string | null" required>Link to the check run.</ResponseField>
        <ResponseField name="durationSeconds" type="integer | null" required>Check duration in seconds, or `null` if not complete.</ResponseField>
        <ResponseField name="failureCount" type="integer" required>Number of test failures within this check.</ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>

  <Expandable title="failureSummaries">
    <ResponseField name="failureSummaries" type="object[]" required>
      Parsed test failure details (up to 5). Raw logs are intentionally omitted.

      <Expandable title="Failure summary fields">
        <ResponseField name="checkName" type="string" required>Check that produced this failure.</ResponseField>
        <ResponseField name="workflow" type="string" required>Workflow the check belongs to.</ResponseField>
        <ResponseField name="testName" type="string" required>Test or step name that failed.</ResponseField>
        <ResponseField name="file" type="string | null" required>Source file where the failure occurred.</ResponseField>
        <ResponseField name="line" type="integer | null" required>Line number of the failure.</ResponseField>
        <ResponseField name="message" type="string" required>Failure message.</ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>

  <Expandable title="flakyHints">
    <ResponseField name="flakyHints" type="object[]" required>
      Flakiness hints based on reruns or recent prior passes (up to 5).

      <Expandable title="Flaky hint fields">
        <ResponseField name="checkName" type="string" required>Check that may be flaky.</ResponseField>
        <ResponseField name="confidence" type="string" required>Confidence the failure is flaky. One of: `low`, `medium`, `high`.</ResponseField>
        <ResponseField name="reason" type="string" required>Human-readable explanation of the flakiness signal.</ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="availableActions" type="string[]" required>
  Top-level available actions.
</ResponseField>

<ResponseField name="meta" type="object" required>
  <Expandable title="Meta fields">
    <ResponseField name="tokenBudgetHint" type="string" required>Response verbosity. One of: `compact`, `standard`.</ResponseField>
    <ResponseField name="truncatedFields" type="string[]" required>Fields omitted to stay within the token budget.</ResponseField>
  </Expandable>
</ResponseField>

### Example response — all checks passing

```json theme={null}
{
  "data": {
    "taskId": "tsk_01JY4X8Q6J5Q3P7M0N2K3R4T5V",
    "submissionId": "sub_01JY4Y4A9P10G6EM7Q3JJ2M1A2",
    "overallStatus": "passed",
    "headSha": "abc123",
    "summary": { "total": 2, "passed": 2, "failed": 0, "running": 0, "queued": 0, "cancelled": 0, "skipped": 0 },
    "workflows": [
      { "name": "CI", "path": ".github/workflows/ci.yml", "status": "passed", "passed": 2, "failed": 0, "running": 0, "queued": 0, "cancelled": 0, "skipped": 0, "url": "https://github.com/oxnw/agentrail/actions/runs/1201" }
    ],
    "checks": [
      { "name": "unit-tests", "workflow": "CI", "status": "passed", "url": "...", "durationSeconds": 42, "failureCount": 0 },
      { "name": "contract-tests", "workflow": "CI", "status": "passed", "url": "...", "durationSeconds": 18, "failureCount": 0 }
    ],
    "failureSummaries": [],
    "flakyHints": [],
    "updatedAt": "2026-05-01T03:03:19Z",
    "availableActions": ["view_review_feedback"]
  },
  "availableActions": ["view_review_feedback"],
  "meta": { "tokenBudgetHint": "compact", "truncatedFields": [] }
}
```

## Error responses

| Status | Code                     | Meaning                                                                                                 |
| ------ | ------------------------ | ------------------------------------------------------------------------------------------------------- |
| `401`  | `unauthorized`           | Bearer token is missing or invalid.                                                                     |
| `403`  | `insufficient_scope`     | Key does not have `ci:read`.                                                                            |
| `404`  | `not_found`              | Task not found, or no live CI adapter matches the task.                                                 |
| `429`  | `ci_source_rate_limited` | GitHub Actions rate limit or secondary abuse limit reached. Retry after the `Retry-After` header value. |
| `502`  | `ci_source_auth_failed`  | CI source is unavailable or provider authentication failed.                                             |

<Tip>
  When `overallStatus` is `passed` and review is approved, `availableActions` will include `"ship"` on the task itself. Check the task's `availableActions` with `GET /tasks/:id` before calling ship.
</Tip>
