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

# Poll jobs

> Use staplehire jobs poll to wait for async sourcing and enrichment jobs to finish, with stable exit codes, then read the generated results.

Some commands — `candidates enrich` and `sourcing start` — kick off **async jobs** and return immediately. Before reading their results, wait for the job to finish with `jobs poll`.

```bash theme={null}
JOB_ID=$(staplehire candidates enrich <candidateId> | jq -r '.job.id')
staplehire jobs poll "$JOB_ID"
```

## How `jobs poll` works

`jobs poll` blocks, re-fetching the job on an interval until it reaches `done` or `failed` (or the timeout elapses). It exits with a stable code so scripts and agents can branch on the outcome.

```bash theme={null}
JOB_ID=$(staplehire sourcing start <roleId> | jq -r '.job.id')
staplehire jobs poll "$JOB_ID"
staplehire sourcing prospects <roleId>
```

```json theme={null}
{
  "job": {
    "id": "job_…",
    "type": "source_role_prospects",
    "status": "done",
    "role_id": "550e8400-e29b-41d4-a716-446655440000"
  }
}
```

### Parameters

| Flag              | Required | Default           | Description                               |
| ----------------- | -------- | ----------------- | ----------------------------------------- |
| `<jobId>`         | Yes      | —                 | Job ID returned by an async command       |
| `--interval <ms>` | No       | `2000`            | Milliseconds between status checks        |
| `--timeout <ms>`  | No       | `600000` (10 min) | Maximum time to wait before exit code `9` |

### Job statuses

| Status    | Meaning                        |
| --------- | ------------------------------ |
| `pending` | Queued, not yet picked up      |
| `claimed` | A worker is processing the job |
| `done`    | Completed successfully         |
| `failed`  | The worker failed the job      |

### Exit codes

| Code | Meaning                                             |
| ---- | --------------------------------------------------- |
| `0`  | Job reached `done`                                  |
| `1`  | Job reached `failed` (error JSON printed to stderr) |
| `9`  | Poll timed out — the job may still be running       |

## Inspect and list jobs

### Get a job without blocking

```bash theme={null}
staplehire jobs get <jobId>
```

### List jobs with filters

```bash theme={null}
staplehire jobs list --role-id <roleId> --type source_role_prospects --status done --include-history
```

| Flag                  | Description                               |
| --------------------- | ----------------------------------------- |
| `--role-id <id>`      | Filter to one role                        |
| `--candidate-id <id>` | Filter to one candidate                   |
| `--type <type>`       | `enrich` or `source_role_prospects`       |
| `--status <status>`   | `pending`, `claimed`, `done`, or `failed` |
| `--include-history`   | Include historical/superseded jobs        |

<Note>
  `--type` and `--status` are validated by the CLI. An unsupported value fails fast with exit code `8` (CLI usage).
</Note>

## Examples

### Poll with a longer window

```bash theme={null}
staplehire jobs poll <jobId> --interval 5000 --timeout 300000
```

### Handle a timeout gracefully

```bash theme={null}
if ! staplehire jobs poll "$JOB_ID" --timeout 120000; then
  code=$?
  if [ "$code" -eq 9 ]; then
    echo "Still running — checking later"
    staplehire jobs get "$JOB_ID"
  fi
fi
```

## Common errors

| Error           | Exit code | Fix                                                                     |
| --------------- | --------- | ----------------------------------------------------------------------- |
| Poll timeout    | `9`       | Re-run `jobs poll`, raise `--timeout`, or inspect with `jobs get`       |
| `failed` status | `1`       | Read the job's `error.message`; retry the source command if appropriate |
| `NotFoundError` | `4`       | Wrong job ID — use the `job.id` returned by the async command           |

## FAQ

<AccordionGroup>
  <Accordion title="Does a timeout cancel the job?">
    No. Exit code `9` only means the CLI stopped waiting. The job may still finish — check it later with `jobs get`.
  </Accordion>

  <Accordion title="Which commands create jobs?">
    `candidates enrich` (type `enrich`) and `sourcing start` (type `source_role_prospects`).
  </Accordion>

  <Accordion title="Should agents always poll?">
    Yes. After any async command, poll the job before reading generated results. An exit code of `0` on the start command does not mean the work is done.
  </Accordion>
</AccordionGroup>

Related: [Source candidates](/docs/source-candidates-cli) · [Enrich a candidate](/docs/enrich-candidate-cli) · [CLI errors](/docs/cli-errors)
