Get started
Errors and retries
Every failure is a JSON problem document (RFC 9457) with a stable code you can branch on. Read the code, not the prose.
The problem document
Failures use the application/problem+json media type and always carry type, title, status, detail, and code. When a request identifier is available, request_id and the X-Request-Id response header carry it — quote that value in a support request.
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
{
"type": "urn:seekout:developer-api:problem:insufficient_scope",
"title": "Insufficient scope",
"status": 403,
"detail": "The credential lacks the required scope for this operation.",
"code": "insufficient_scope",
"request_id": "43fa2cc3-87b8-4ad9-a17a-5790fd0f3760"
}code is the stable contract. detail is written for a human and may change; never parse it. Response bodies may gain fields, so ignore any member you do not recognize.
Status codes
| Status | Meaning | What to do |
|---|---|---|
400 | Malformed authentication, idempotency, or cursor input | Fix the request; do not retry unchanged |
401 | The key is missing, invalid, revoked, or for another audience | Use a valid active key |
402 | The work cannot be funded at its minimum useful size | Add credits or ask for less work; nothing was charged |
403 | The key is valid but lacks the permission for this operation | Request the permission, or use a key that has it |
404 | The resource does not exist, or is not enabled for your organization | Check the path; ask an admin whether the operation is enabled |
409 | An idempotency key, quote, or continuation conflicts with existing state | Refresh the state; do not assume a new hold exists |
410 | A cursor, job, or result is no longer retained | Start the operation again |
413 | The request body exceeds 65,536 bytes | Send a smaller request |
415 | The media type is not supported | Send Content-Type: application/json |
422 | The body did not satisfy the operation contract | Correct the fields named in detail |
429 | Admission was denied before useful work happened | Wait for Retry-After, then retry |
503 | A dependency is unavailable or a terminal state is uncertain | Retry after Retry-After; contact support if it persists |
402, 403, 429, and 503 are deliberately different
These four are never substituted for one another, so each one tells you exactly what to change.
401is about the credential itself: absent, invalid, or revoked.403is about authority: the credential is real but not allowed here.402is commercial: the work is not funded. It is raised before any provider work happens, so nothing was charged and nothing changed. Out of credits is always the codeinsufficient_credits, on every paid operation; the only other402codes arefamily_budget_exhaustedandorganization_budget_exhausted, which mean a spending budget your administrator set refused the spend — raise the budget rather than adding credits.429is operational admission: you asked for more concurrent work than your limits allow. See rate limits.503is dependency uncertainty: a service the request needs is unavailable, or the outcome could not be confirmed.
Retries and idempotency
POST /v1/candidates/search, POST /v1/profiles/unlock, and POST /v1/person-matches require an Idempotency-Key header of 8 to 128 characters, starting with an ASCII letter or digit and then using only ASCII letters, digits, ., _, :, or -. A UUID is valid. Reusing the same key with the same body replays the first successful result instead of doing the work again. GET /v1/whoami and GET /v1/search/sources do not use an idempotency key.
- Safe to retry with the SAME idempotency key:
429,503, and network timeouts where you never saw a response. - Reusing a key with a DIFFERENT body returns
409— generate a new key for genuinely new work. - A
409while an operation is still in progress means the first attempt is running; wait forRetry-Afterand retry the same request. - Never retry
400,403,413,415, or422unchanged — they will fail the same way.
X-Request-Id (up to 128 letters, digits or ._:-) to correlate logs, or read the one the API returns. SeekOut never logs your query text, profile payloads, or credentials, so the request id is how a support conversation starts.