Jobs
The jobs endpoints are the read side of async jobs: list your jobs, poll one for status, and page through its results. All three are GETs and consume no credits — you paid when the job processed its roles.
| Method | Path | What it returns |
|---|---|---|
| GET | /v1/jobs | Your jobs, newest first, filterable by status |
| GET | /v1/jobs/{id} | One job object |
| GET | /v1/jobs/{id}/results | The job’s output, paginated, in JSON, CSV, or NDJSON |
curl "https://api.rolesapi.com/v1/jobs?status=running&limit=20" \ -H "Authorization: Bearer rk_live_your_key"What is in a job object?
{ "data": { "id": "5f0f6c2e-4b3a-4e9c-9c74-31d1f2a30c11", "type": "batch_detail", "status": "succeeded", "progress": { "done": 120, "total": 120 }, "result_count": 120, "error": null, "created_at": "2026-07-01T09:15:00Z", "started_at": "2026-07-01T09:15:01Z", "completed_at": "2026-07-01T09:32:41Z" }, "request_id": "req_e01b7d2c"}| Field | Type | Meaning |
|---|---|---|
id | string | Job id (UUID). |
type | string | What created it: batch_detail (roles batch), search (deep search), chained_search_detail (search with details). |
status | string | queued, running, succeeded, failed, timed_out, or aborted. |
progress | object | { "done": n, "total": n } — units processed vs. planned. |
created_at | string | Submission time, ISO 8601. |
result_count | integer or null | Rows produced, set on completion. |
started_at / completed_at | string or null | Set when the job starts / reaches a terminal state. |
error | string or null | Set when the job fails. |
What is the lifecycle?
| From | To | When |
|---|---|---|
| — | queued | Submission accepted (the 202 response). |
queued | running | A worker picks the job up; progress.done starts advancing. |
running | succeeded | Every unit processed; results ready. |
running | failed | Unrecoverable error; error is set, partial results (if any) remain readable. |
succeeded, failed, timed_out, and aborted are terminal. Poll every few seconds with backoff, or skip polling with a webhook.
GET /v1/jobs
| Parameter | In | Type | Description |
|---|---|---|---|
status | query | string | Filter: queued, running, succeeded, failed, timed_out, aborted. |
limit | query | integer | Page size. |
offset | query | integer | Items to skip. See Pagination. |
Returns an array of job objects with the standard meta block.
GET /v1/jobs/{id}
Returns the single job object shown above. 404 not_found if the id does not exist on your account.
GET /v1/jobs/{id}/results
| Parameter | In | Type | Description |
|---|---|---|---|
limit | query | integer | Page size. |
offset | query | integer | Items to skip. |
format | query | string | json (default), csv, or ndjson. See Output formats. |
JSON results are full role objects in the standard envelope:
curl "https://api.rolesapi.com/v1/jobs/job_01hxyz/results?limit=100&offset=0" \ -H "Authorization: Bearer rk_live_your_key"{ "data": [ { "job_key": "a1b2c3d4e5f60718", "title": "Senior Backend Engineer", "company": { "name": "Acme Logistics", "rating": 4.1, "url": "https://www.indeed.com/cmp/Acme-Logistics" }, "location": "Austin, TX", "remote": false, "employment_type": "Full-time", "salary": { "min": 140000, "max": 175000, "currency": "USD", "period": "year", "source": "employer" }, "benefits": ["Health insurance", "401(k) matching", "Paid time off"], "description": "Acme Logistics is hiring a Senior Backend Engineer to build the services that power our fulfillment network...", "posted_at": "2026-06-28", "url": "https://www.indeed.com/viewjob?jk=a1b2c3d4e5f60718", "country": "us" } ], "meta": { "total": 120, "count": 1, "limit": 1, "offset": 0, "has_more": true }, "request_id": "req_ab44c8e0"}With format=csv or format=ndjson, the whole result set is returned as one download — rows only, no envelope. Results for a failed job return whatever was processed before the failure. Calling /results on a queued or running job returns the rows processed so far, so you can stream partial output from long jobs.