SurfacedBySurfacedBy Docs

Errors

RFC 7807 problem+json error format and the full catalogue of error types the API emits.

Ask an AI:Open in ChatGPTOpen in Claude

Every non-2xx response from the API is a structured problem document per RFC 7807. The content type is application/problem+json. The shape is consistent across every endpoint.

Problem document

{
  "type": "https://docs.surfacedby.com/v1/api/errors#rate_limited",
  "title": "Rate limit exceeded",
  "status": 429,
  "detail": "You exceeded the per-minute request limit for this API key.",
  "request_id": "req_01HR7A2B3C4D5E6F7G8H9J0K1L"
}
  • type: a stable URL identifying the error category. The fragment is the slug and is safe to switch on in code. Slugs never change without a major version bump.
  • title: a short human-readable summary.
  • status: the HTTP status code.
  • detail: a longer explanation of what went wrong in this specific request.
  • request_id: the server-assigned request identifier. Include it when reporting issues.

Some error types include extra fields. rate_limited responses carry X-RateLimit-* headers plus Retry-After. validation_error responses include a violations array naming each failing field. insufficient_credits (Console) includes required_credits, current_balance, and purchase_url.

Error catalogue

The full list of problem-type slugs the API can emit. Each id below matches the fragment in the type URL.

validation_error - Validation error

The request body or query parameters did not match the documented schema. The detail field names the specific field that failed.

missing_api_key - API key missing

The X-API-Key header was absent. Mint a key from Settings -> Developer and include it in every request.

invalid_api_key - API key invalid

The supplied key was malformed, revoked, or expired. Generate a new key and update the calling client; revocation cannot be undone.

tier_required - Subscription tier does not allow this action

The current subscription tier permits read access only. Upgrade to Business to perform write operations on your workspace.

rate_limited - Rate limit exceeded

Too many requests. The Retry-After header indicates how many seconds to wait before the next call. The X-RateLimit-* headers carry the per-window quota and the remaining budget.

idempotency_in_progress - An identical request is already in flight

The same Idempotency-Key was received recently and the original handler has not yet completed. Retry after the Retry-After header.

idempotency_conflict - Idempotency-Key reuse with a different body

The same Idempotency-Key was previously used with a different request body. Either resend the original body verbatim or pick a new Idempotency-Key.

service_disabled - Public API surface temporarily unavailable

The api_v1_ext_enabled kill switch is OFF. Check status.surfacedby.com for incident updates; no application-level retry is required.

data_degraded - Returning stale data

The upstream call timed out and the response was assembled from the last known good cache. The body is structurally identical to a fresh response; X-Data-Degraded: true and X-Data-Age-Seconds tell you how stale the data is.

signature_verification_failed - Webhook signature verification failed

Returned by the example verifier code below when the X-SurfacedBy-Signature header does not match the body under HMAC-SHA256. Most common cause: the receiver re-serialises the body before signing. Always sign the exact bytes received.

Retry semantics

  • 4xx responses are terminal. Retrying without fixing the request will keep failing.
  • 429 and 5xx responses are safe to retry with exponential backoff and jitter. Cap attempts at 5.
  • 409 idempotency_in_progress and 409 idempotency_conflict are client-controlled; see Idempotency.

Reporting issues

When opening a support ticket, include the request_id from the problem document. That single value lets us trace the request end to end, including what the backend saw from upstream AI platforms.

On this page