# Async Job Polling Guide

Question-asking and study-completion operations are asynchronous.
These endpoints return queued job IDs instead of immediate final results.

## Endpoints That Queue Jobs

- `POST /v1/research-agents/{agent_id}/questions`
- `POST /v1/research-groups/{group_id}/questions`
- `POST /v1/research-studies/{study_id}/questions`
- `POST /v1/research-studies/{study_id}/complete`
- `POST /v1/free/questions`

Poll status with:

- `GET /v1/jobs/{job_id}`

## Standard Polling Pattern

1. Submit a question/completion request and store one returned `job_id`.
   For direct agent/group questions, also store the returned `question_id` or
   `question_uuid`.
2. Wait before first poll (recommended: ~45-50 seconds for question jobs).
3. Call `GET /v1/jobs/{job_id}`.
4. If `status` is `started`, wait ~20 seconds and poll again.
5. If `status` is `finished`, parse `result` and continue workflow.
   For direct agent/group questions, follow with
   `GET /v1/direct-questions/{question_id}` to retrieve the canonical saved
   record, normalized answers, and any summary artifact. Use
   `GET /v1/direct-questions` when you need to browse recent saved direct
   questions across the organization.
6. If `status` is `failed`, inspect `error` and stop/retry appropriately.

## One `job_id` Is Usually Enough

Study and group question endpoints can return multiple `job_ids`.
For jobs created by the same question request, polling one `job_id` is usually sufficient to track completion state.
If your workflow requires strict per-agent confirmation, poll each `job_id`.

## Response Shapes

Example (still running):

```json
{
  "status": "started",
  "result": null,
  "error": null,
  "meta": {}
}
```

Example (finished):

```json
{
  "status": "finished",
  "result": {},
  "error": null,
  "meta": {}
}
```

## Workflow Guardrails

- Ask study questions sequentially: queue one question, wait for finish, then ask the next.
- Do not call study completion until question jobs have finished.
- Persist `job_id`, endpoint context, and submitted question text for traceability.
- For direct question endpoints, persist `question_id` / `question_uuid` so the
  saved question can be fetched after the async job completes.
