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

# Job polling

> Poll for AI agent job results with status tracking and exponential backoff

Agent endpoints are asynchronous. When you submit a job, you receive a `job_id` and poll until the job reaches a terminal state.

## Polling flow

<Steps>
  <Step title="Submit">
    `POST` to any agent endpoint (`/v1/agents/code-research`, `/medical-necessity`, `/denial-resolution`). The API returns `202 Accepted` with a `job_id`.
  </Step>

  <Step title="Poll">
    `GET /v1/agents/jobs/{job_id}` repeatedly until `status` is `completed` or `failed`.
  </Step>

  <Step title="Read result">
    The completed response includes the agent's output in `result`.
  </Step>
</Steps>

To skip polling, pass `callback_url` and `callback_secret` on submit. See [Agent callbacks](/docs/webhooks).

## Status values

| Status      | Meaning                     | Action              |
| ----------- | --------------------------- | ------------------- |
| `pending`   | Job queued, not yet started | Continue polling    |
| `running`   | Agent is executing          | Continue polling    |
| `completed` | Agent finished successfully | Read `result` field |
| `failed`    | Agent encountered an error  | Read `error` field  |

## Poll endpoint

```bash theme={null}
curl https://api-dev.rcintell.com/v1/agents/jobs/{job_id} \
  -H "X-API-Key: kp_test_..."
```

### Response (completed)

```json theme={null}
{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "agent_type": "code_research",
  "result": {
    "codes": [{ "code": "27447", "type": "CPT", "description": "..." }],
    "guidance": "CPT 27447 is the correct code for total knee arthroplasty..."
  },
  "error": null,
  "latency_ms": 3420,
  "created_at": "2026-03-31T10:00:00Z",
  "completed_at": "2026-03-31T10:00:03Z"
}
```

### Response (failed)

```json theme={null}
{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "failed",
  "agent_type": "denial_resolution",
  "result": null,
  "error": "Agent dispatch failed",
  "latency_ms": null,
  "created_at": "2026-03-31T10:00:00Z",
  "completed_at": "2026-03-31T10:00:05Z"
}
```

## Python polling example

Use exponential backoff to avoid unnecessary requests. Most agent jobs complete within 3-10 seconds.

```python theme={null}
import time
import httpx

API_KEY = "kp_your_key_here"
BASE = "https://api-dev.rcintell.com"
HEADERS = {"X-API-Key": API_KEY}

# 1. Submit the job
resp = httpx.post(
    f"{BASE}/v1/agents/code-research",
    headers=HEADERS,
    json={"query": "CPT for total knee replacement?", "ccn": "170001"},
)
job_id = resp.json()["job_id"]

# 2. Poll with exponential backoff
delay = 1.0
max_delay = 15.0

while True:
    result = httpx.get(f"{BASE}/v1/agents/jobs/{job_id}", headers=HEADERS)
    data = result.json()

    if data["status"] == "completed":
        print("Result:", data["result"])
        break
    elif data["status"] == "failed":
        print("Error:", data["error"])
        break

    time.sleep(delay)
    delay = min(delay * 2, max_delay)
```

## Reasoning trace

After a job completes, retrieve the agent's step-by-step reasoning and SENTINEL security annotations:

```bash theme={null}
curl https://api-dev.rcintell.com/v1/agents/jobs/{job_id}/trace \
  -H "X-API-Key: kp_test_..."
```

```json theme={null}
{
  "job_id": "550e8400-...",
  "steps": [
    { "type": "reasoning", "content": "Looking up CPT 27447 in MPFS..." },
    { "type": "tool_call", "tool": "knowledge_resolve", "input": { "ccn": "170001", "cpt": "27447" } },
    { "type": "security", "finding": "no_phi_detected", "score": 1.0 }
  ],
  "security_annotations": [
    { "type": "security", "finding": "no_phi_detected", "score": 1.0 }
  ]
}
```

## Best practices

<CardGroup cols={2}>
  <Card title="Start at 1 second" icon="clock">
    Most jobs complete in 3-10s. A 1-second initial delay avoids wasted requests without adding latency.
  </Card>

  <Card title="Cap at 15 seconds" icon="gauge-high">
    If a job hasn't completed after several polls, cap the backoff. Jobs rarely exceed 30 seconds.
  </Card>

  <Card title="Set a timeout" icon="hourglass-end">
    Abort after 60 seconds. If a job is still `running`, it may be stuck — contact support.
  </Card>

  <Card title="Check audit scores" icon="shield-check">
    Always inspect `audit_tier` on completed jobs. A `red` tier means the result needs human review.
  </Card>
</CardGroup>
