Errors

Every status code, what causes it, and how to fix it.

Error response format

All error responses follow this structure:

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable description of what went wrong",
    "requestId": "req_a1b2c3d4"
  }
}
  • code: Machine-readable error code. Use this for programmatic error handling.
  • message: Human-readable description. Safe to display to end users.
  • requestId: Unique request identifier. Include this when contacting support.

This is the shape for every endpoint documented in this API reference. A separate, per-IP request limiter guards login, invites, and most dashboard/admin endpoints; its 429 responses are a bare {"error": "Rate limit exceeded: ..."} string, not this object. See Rate limits.

Error codes

StatusCodeMeaning
200NoneSuccess
401UNAUTHORIZEDMissing API key
401INVALID_API_KEYAPI key is malformed or does not match a live key
401API_KEY_REVOKEDAPI key has been revoked
402INSUFFICIENT_CREDITSThe organization's balance cannot cover the request
402BILLING_SUSPENDEDBilling is on hold for the organization
403NO_COLLECTION_ACCESSNo access to requested collection
403SANDBOX_UNSUPPORTED_ENDPOINTSandbox key used on an endpoint with no sandbox behaviour
404COLLECTION_NOT_FOUNDCollection not found
409IDEMPOTENCY_KEY_IN_PROGRESSA preview with this Idempotency-Key is still running
410CACHED_RESULT_EXPIREDCached result or preview has expired (7-day window), or the preview was written by an older payload version
422VALIDATION_ERRORInvalid request body
422INVALID_FILTERA search filter cannot be applied: unknown field, unsupported operator combination, or invalid value
422INVALID_QUERYThe query carries too little to search on, such as only symbols, only stop words, or one repeated character
422IDEMPOTENCY_KEY_REUSEDThis Idempotency-Key was already used with a different request body
429QUOTA_EXCEEDEDPer-minute, daily, or monthly quota exceeded
429API_KEY_BUDGET_EXCEEDEDThe API key's spending cap is used up
429PREVIEW_RATE_LIMIT_EXCEEDEDPreview rate limit exceeded
429SEARCH_RATE_LIMITEDToo many rejected queries in a short time
500INTERNAL_ERRORInternal server error
503SERVICE_UNAVAILABLEA dependency the request needs (e.g. the quota service) is unreachable

Handling errors in the SDKs

Every non-2xx response becomes a typed error carrying status, code, message and requestId from the envelope above, so the code column is what you branch on and requestId is what you send to support. 429 and 503 are retried automatically before they surface (see Rate limits).

StatusPythonTypeScriptGo
401AuthErrorAuthError*AuthError
402InsufficientCreditsInsufficientCredits*InsufficientCreditsError
403AccessDeniedAccessDenied*AccessDeniedError
404NotFoundNotFound*NotFoundError
410ExpiredExpired*ExpiredError
422ValidationErrorValidationError*ValidationError
429QuotaExceededQuotaExceeded*QuotaExceededError
503AssistedUnavailableAssistedUnavailable*AssistedUnavailableError
anything elseRedpineErrorRedpineError*APIError
from redpine import AccessDenied, QuotaExceeded, RedpineError

try:
    r = client.search("your search query", collection="my-collection")
except AccessDenied as e:
    print("key cannot reach this collection:", e.code)      # NO_COLLECTION_ACCESS
except QuotaExceeded as e:
    print("back off for", e.retry_after, "seconds")
except RedpineError as e:
    print(e.status, e.code, e.message, e.request_id)

A missing key never reaches the network: the Python and TypeScript constructors raise AuthError and Go's New returns an error when no explicit key is given and neither REDPINE_API_KEY nor the legacy CONNECT_API_KEY is set.

Troubleshooting

  • 401 UNAUTHORIZED: The Authorization header is missing entirely. Include Authorization: Bearer sk_live_... (or sk_test_... for sandbox).
  • 401 INVALID_API_KEY: The header is present but the key doesn't match a live key. Check for typos or a stale/rotated key.
  • 401 API_KEY_REVOKED: The key was revoked. Generate a new one. Retrying with a revoked key will keep failing.
  • 402 INSUFFICIENT_CREDITS: The balance cannot cover the request. Nothing is charged; add credits or a payment method and retry the same request.
  • 402 BILLING_SUSPENDED: Billing is on hold for the organization, or the balance check is briefly unavailable. Retry once; if it persists, contact support.
  • 403 NO_COLLECTION_ACCESS: The API key doesn't have access to this collection. Use an org-wide key or add the collection to the key's scope.
  • 403 SANDBOX_UNSUPPORTED_ENDPOINT: The key is a sandbox key (sk_test_) and this endpoint has no sandbox behaviour. Use a live key, or one of the endpoints listed in Sandbox. This is deliberate: an endpoint that quietly behaved normally would leave you unable to tell a fixture from a real result.
  • 404 COLLECTION_NOT_FOUND: Verify the collection name exists. Names are case-sensitive.
  • 410 CACHED_RESULT_EXPIRED: The queryId you passed to GET /api/v1/search/results/{queryId} or POST /api/v1/search/unlock is older than the 7-day window, or the preview it points to was written by an older payload version. Run the search or preview again to get a fresh queryId.
  • 422 VALIDATION_ERROR: Check required fields (query is required; exactly one of collection/collections). Ensure query is under 1000 characters (16,000 on POST /api/v1/search/assisted) and limit is between 1-30. On POST /api/v1/search/unlock, this also covers a resultId that isn't part of the preview and any unrecognized field in the request body. Both preview and unlock reject unknown keys rather than ignoring them.
  • 422 INVALID_FILTER: The message says what to change and names the field where there is one (also in details.field). Common causes: a field name typo (the message lists the indexed fields), doc_id, a journal_metric.* threshold outside the metric bounds or matching more than 35,000 ISSNs, two operator families in one condition, a field the collection has no index for, or an invalid date or article_type. Retrying the same filter fails the same way. See Filtering.
  • 422 INVALID_QUERY: The query has too little to search on: only whitespace or symbols, too few letters or digits, one character repeated (aaaaaaa), the same word over and over, or only stop words (what is the). Short identifiers such as p53, BRCA1 or COVID-19 are fine. Rephrase the query; retrying it unchanged fails the same way.
  • 409 IDEMPOTENCY_KEY_IN_PROGRESS and 422 IDEMPOTENCY_KEY_REUSED: See Retrying a preview safely. Retry the first after a moment; for the second, send a new key.
  • 429 QUOTA_EXCEEDED: You've hit the per-minute, daily, or monthly quota. Back off and retry. See Rate limits for how long each window takes to reset.
  • 429 API_KEY_BUDGET_EXCEEDED: The key has reached the spending cap set on it in the dashboard. The cap applies however the key is used, including through MCP sign-in and paid integration tools. Ask an organization admin to raise the cap, or use another key.
  • 429 PREVIEW_RATE_LIMIT_EXCEEDED: This organization's preview rate limit was exceeded. Wait for the Retry-After period. See Rate limits for the current per-hour default.
  • 429 SEARCH_RATE_LIMITED: More than 30 queries were rejected as INVALID_QUERY within a minute. Wait for the Retry-After period and check what is generating the queries.
  • 500 INTERNAL_ERROR: An unexpected error occurred. Retry the request. If it persists, contact support with the requestId.
  • 503 SERVICE_UNAVAILABLE: A backing service the request depends on (e.g. the quota check POST /api/v1/search/unlock performs) is temporarily unreachable. On unlock, this happens before the charge commits: nothing is charged and no result is unlocked, so it's safe to retry with backoff.

Usage is tracked per API key. View statistics on your Usage page in the dashboard.

Was this page helpful?

On this page