# Get a candidate's pipeline progress

A candidate's step progress across all their roles. Scope: pipeline:read.

Returns where a candidate stands in their hiring pipeline — their per-step progress across every role they're in. **Scope:** `pipeline:read`. The parent candidate must be visible to the key (else `404`). The list is not paginated (it is inherently small, ordered by role then step order).

## Path parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `id` | string | The candidate id. |

## Example request

```bash
curl https://app.talent-ray.com/api/v1/candidates/cand_1/steps \
  -H "Authorization: Bearer tr_YOUR_KEY"
```

## Response

`200 OK`

```json
{
  "data": [
    {
      "id": "crs_1",
      "roleId": "role_eng_be",
      "roleStepId": "step_cv",
      "name": "CV Screening",
      "order": 1,
      "stepType": "cv_screening",
      "status": "validated",
      "startedAt": "2026-06-01T10:00:00Z",
      "completedAt": "2026-06-01T11:00:00Z",
      "validatedAt": "2026-06-01T11:05:00Z",
      "rejectedAt": null,
      "validationScore": 78,
      "rejectionReason": null,
      "offerResponse": null,
      "createdAt": "2026-06-01T10:00:00Z",
      "updatedAt": "2026-06-01T11:05:00Z"
    }
  ]
}
```

`status` is one of `locked`, `active`, `completed`, `validated`, `rejected`, `skipped`.

## Status codes

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `401` | No valid API key. |
| `403` | `insufficient_scope` — the key lacks `pipeline:read`. |
| `404` | Candidate not found, or not visible to the key. |
| `429` | Rate limit exceeded. |