Async jobs
Async jobs are how RolesAPI handles work too large for one request-response cycle. Instead of holding a connection open while hundreds of roles are processed, the API returns a job id immediately; you poll it (or receive a webhook) and pull results when it completes.
Which endpoints run async?
| Endpoint | When it runs async |
|---|---|
POST /v1/roles/batch | Always — up to 500 roles per request. |
POST /v1/search | Only when max_pages is greater than 3. At 3 pages or fewer it responds synchronously. |
POST /v1/search/with-details | Always. |
POST /v1/listings/posted-today, /posted-this-week, /remote | Always. |
What does the 202 response look like?
An async submission returns HTTP 202 with a job object:
{ "data": { "job_id": "5f0f6c2e-4b3a-4e9c-9c74-31d1f2a30c11", "status": "queued" }, "request_id": "req_3f0a77b1"}Poll the job for progress: progress.total is the number of units the job will process (roles for batch, pages for a deep search).
How do I poll a job?
curl "https://api.rolesapi.com/v1/jobs/job_01hxyz" \ -H "Authorization: Bearer rk_live_your_key"{ "data": { "id": "5f0f6c2e-4b3a-4e9c-9c74-31d1f2a30c11", "type": "batch_detail", "status": "running", "progress": { "done": 45, "total": 120 } }, "request_id": "req_88b1c2d0"}Poll every few seconds with backoff — polls count against your rate limit. The status lifecycle:
| Status | Meaning |
|---|---|
queued | Accepted, waiting for a worker. |
running | In progress; progress.done advances. |
succeeded | Finished; results are ready at /results. |
timed_out / aborted | Stopped before finishing; partial results, if any, remain available. |
failed | Could not complete; the job object includes an error. Partial results, if any, remain available. |
How do I get the results?
curl "https://api.rolesapi.com/v1/jobs/job_01hxyz/results?limit=100&offset=0" \ -H "Authorization: Bearer rk_live_your_key"Results are a paginated list of full role objects in the standard envelope — see Pagination. Add ?format=csv or ?format=ndjson to export the whole set in one response — see Output formats.
Can I skip polling entirely?
Yes. Register a webhook once with POST /v1/webhooks and RolesAPI will POST a signed job.succeeded (or job.failed) event to your URL whenever a job finishes:
curl -X POST "https://api.rolesapi.com/v1/webhooks" \ -H "Authorization: Bearer rk_live_your_key" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/hooks/rolesapi", "events": ["job.succeeded", "job.failed"]}'See the Webhooks guide for payloads and signature verification.
How are credits charged?
Credits are charged per processed role (or per search page), as the job runs — not at submission. A 120-role batch that completes costs 120 credits. If a job fails partway, you are charged only for the units actually processed, and their results remain retrievable. See POST /v1/search for worked with-details math.