Errors
Every RolesAPI error, on every endpoint, uses one envelope and one of nine stable machine-readable codes. Branch on error.code, not on the message text — messages can change, codes will not.
{ "error": { "code": "not_found", "message": "No role exists for job_key 'a1b2c3d4e5f60718' in country 'us'.", "request_id": "req_9d41c7be" }}request_id also appears on successful responses. Include it in any support email to nikhil@landkit.pro — it lets us find the exact request.
What are the error codes?
| Code | HTTP status | Meaning | What to do |
|---|---|---|---|
missing_api_key | 401 | No Authorization header was sent. | Send Authorization: Bearer rk_.... See Authentication. |
invalid_api_key | 401 | The key is malformed, unknown, or revoked. | Check for truncation; create a new key if the old one was revoked. Do not retry with the same key. |
out_of_credits | 402 | Your credit balance is zero. | Top up or upgrade in the dashboard, then retry. |
forbidden | 403 | The key is valid but not allowed to perform this action. | Check that you are using the right account’s key. |
not_found | 404 | The role, job, or webhook does not exist (or the posting is no longer live). | Verify the id or URL. For roles, confirm the country parameter matches the posting’s edition. |
invalid_request | 422 | A parameter is missing, out of range, or the wrong type. | Read error.message — it names the offending field. Fix the request; do not retry unchanged. |
rate_limited | 429 | You exceeded your plan’s requests-per-minute. | Wait for the Retry-After header, then retry. See Rate limits. |
internal_error | 500 | Something failed on our side. | Retry idempotent GETs with backoff. If it persists, contact support with the request_id. |
upstream_timeout | 504 | The source did not respond in time. | Retry with backoff; transient by nature. For large workloads, prefer async jobs. |
Which errors are safe to retry?
- 429
rate_limited— always retryable. Respect theRetry-Afterheader (seconds); do not hammer before it elapses. - 500 and 504 — safe to retry for idempotent GET requests, with exponential backoff and a retry cap. For POSTs that create async jobs, check
GET /v1/jobsbefore re-submitting so you do not create a duplicate job. - 4xx other than 429 — not retryable as-is.
401,402,403,404, and422indicate something about the request or account must change first.
A reasonable default policy: retry 429/500/504 up to three times, waiting Retry-After when present and otherwise 1s, 2s, 4s.
Do failed requests consume credits?
No. Credits are charged only for successfully processed work — a role detail delivered or a search page returned. Error responses, including rate limits and timeouts, are free.
RolesAPI is not affiliated with, endorsed by, or sponsored by Indeed, Inc.
Indeed is a registered trademark of Indeed, Inc. RolesAPI provides access to
publicly available data via a stable REST API.