Roles
The roles endpoints return normalized job-posting objects from any of 60+ Indeed country editions. Fetch one role by URL or job key, fetch a single block of it, or fetch up to 500 roles in one batch.
| Method | Path | Credits | Mode |
|---|---|---|---|
| GET | /v1/roles/by-url | 1 | Sync |
| GET | /v1/roles/{job_key} | 1 | Sync |
| GET | /v1/roles/{job_key}/company | 1 | Sync |
| GET | /v1/roles/{job_key}/salary | 1 | Sync |
| GET | /v1/roles/{job_key}/description | 1 | Sync |
| GET | /v1/roles/{job_key}/benefits | 1 | Sync |
| POST | /v1/roles/batch | 1 per role | Async |
curl "https://api.rolesapi.com/v1/roles/a1b2c3d4e5f60718?country=us" \ -H "Authorization: Bearer rk_live_your_key"GET /v1/roles/by-url
Fetch a full role from an Indeed viewjob URL. Use this when you have a link — from a browser, an alert email, or an agent — and want structured data in one call.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
url | query | string | Yes | An Indeed viewjob URL, e.g. https://www.indeed.com/viewjob?jk=.... URL-encode it if it carries its own query string. |
fields | query | string | No | Field projection. |
Credits: 1.
curl "https://api.rolesapi.com/v1/roles/by-url?url=https%3A%2F%2Fwww.indeed.com%2Fviewjob%3Fjk%3Da1b2c3d4e5f60718" \ -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" }, "request_id": "req_8f3a2b1c"}Errors: 400 invalid_request if url is missing or not a viewjob URL; 404 not_found if the posting no longer exists.
GET /v1/roles/{job_key}
Fetch a full role by its 16-character Indeed job key.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
job_key | path | string | Yes | The Indeed job key, e.g. a1b2c3d4e5f60718. |
country | query | string | No | Indeed country edition code. Default us. |
fields | query | string | No | Field projection. |
Credits: 1.
curl "https://api.rolesapi.com/v1/roles/a1b2c3d4e5f60718?country=us" \ -H "Authorization: Bearer rk_live_your_key"The response is the same full role object shown above.
Errors: 404 not_found if no role exists for that key in that country — check that country matches the edition the posting appeared in; 400 invalid_request for a malformed key.
What do the sub-resources return?
Each sub-resource returns one block of the role inside the standard envelope, for 1 credit — useful when you only need salary data or the description text and want a smaller payload than the full object.
GET /v1/roles/{job_key}/company
{ "data": { "name": "Acme Logistics", "rating": 4.1, "url": "https://www.indeed.com/cmp/Acme-Logistics" }, "request_id": "req_2d90ee17"}GET /v1/roles/{job_key}/salary
{ "data": { "min": 140000, "max": 175000, "currency": "USD", "period": "year", "source": "employer" }, "request_id": "req_60ac3f8b"}GET /v1/roles/{job_key}/description
{ "data": "Acme Logistics is hiring a Senior Backend Engineer to build the services that power our fulfillment network...", "request_id": "req_bb17c9e4"}GET /v1/roles/{job_key}/benefits
{ "data": ["Health insurance", "401(k) matching", "Paid time off"], "request_id": "req_74d2a1f0"}All four accept the same country query parameter as the parent endpoint and return 404 not_found for unknown keys.
POST /v1/roles/batch
Fetch up to 500 roles in one request. Batch always runs as an async job.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
job_keys | body | string[] | No* | Indeed job keys to fetch. |
urls | body | string[] | No* | Indeed viewjob URLs to fetch. |
country | body | string | No | Country edition for job_keys. Default us. |
*Provide job_keys, urls, or both; the combined count must be 1–500.
Credits: 1 per processed role, charged as the job runs.
curl -X POST "https://api.rolesapi.com/v1/roles/batch" \ -H "Authorization: Bearer rk_live_your_key" \ -H "Content-Type: application/json" \ -d '{ "job_keys": ["a1b2c3d4e5f60718", "b2c3d4e5f6071829"], "country": "us" }'Response — HTTP 202:
{ "data": { "job_id": "5f0f6c2e-4b3a-4e9c-9c74-31d1f2a30c11", "status": "queued" }, "request_id": "req_3f0a77b1"}Poll GET /v1/jobs/{job_id}, then page GET /v1/jobs/{job_id}/results — full role objects, also available as CSV or NDJSON. See Jobs.
Errors: 400 invalid_request if both lists are empty or the combined count exceeds 500; 402 out_of_credits if your balance is zero at submission.