Errors
The RFC 7807 problem+json error format and the catalogue of problem types the API returns.
Every error response from the Data API and the Console API is a problem document per RFC 7807, with content type application/problem+json.
Problem document
- type: a URL identifying the error category. The part after
#is the slug; switch on it in code rather than ontitleordetail. - title: a short human-readable summary.
- status: the HTTP status code.
- detail: an explanation specific to this request.
- request_id: the request identifier, also sent as the
X-Request-Idheader. Include it when reporting issues.
Some problem types carry extra fields:
| Slug | Extra fields |
|---|---|
validation_error | errors: one entry per failing field, with field, message, and type (present when the request did not match the endpoint's schema) |
tier_required | current_tier |
scope_required | required_scopes, granted_scopes |
rate_limited | limit_window (per-minute or per-month), scope, plus the Retry-After header |
idempotency_in_progress | retry_after_seconds, plus the Retry-After header |
domain_limit_reached | limit_kind (plan, trial, or free), current, max |
prompt_limit_reached, pin_limit_reached | current, limit |
insufficient_credits (Console) | required_credits, current_balance, purchase_url |
A request to a path or method that does not exist returns a problem whose slug is http_ followed by the status code, for example http_404 or http_405.
Error catalogue
Each id below matches the slug after # in the type URL.
validation_error - Validation error
The request body, a query parameter, or a pagination cursor was not valid. When the request did not match the endpoint's schema, the errors array names each failing field.
missing_api_key - API key missing
The X-API-Key header was absent. Create a key in the dashboard under Settings > Integrations > API keys and send it in the X-API-Key header of every request.
invalid_api_key - API key invalid
The supplied key was malformed, revoked, or expired, or it belongs to the other API (a Console key sent to the Data API, or the reverse). Create a new key and update the calling client; revocation cannot be undone.
tier_required - Subscription tier does not allow this action
The workspace the key belongs to is not on a plan that includes the Data API. The Data API is included with the Professional and Agency plans. The current_tier field names the workspace's plan.
rate_limited - Rate limit exceeded
The key exceeded its per-minute or per-month request quota; the limit_window field says which. The Retry-After header gives the seconds to wait. Successful responses carry the X-RateLimit-Limit-* and X-RateLimit-Remaining-* headers for both windows.
idempotency_in_progress - An identical request is already in flight
The original request with this Idempotency-Key has not finished. Retry after the Retry-After interval. A request that failed releases its key, so a corrected retry with the same Idempotency-Key is processed.
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 - API temporarily unavailable
The API has been switched off temporarily. Check status.surfacedby.com for updates and retry once it is back.
service_unavailable - Service temporarily unavailable
The request could not be completed because an upstream dependency was slow to respond or a required service is not ready yet. This is transient: retry after a short delay. If it persists, check status.surfacedby.com.
managed_cleanup_required - Managed resource cleanup requires review
Removal stopped because managed Cloudflare resources need ownership or authorization review. Reconnect the Cloudflare account that owns the managed zone and retry. If resources changed ownership, contact support. The domain and its cleanup record are preserved.
scope_required - Missing required scope
The key does not have the scope this endpoint needs. Write endpoints need the write scope, which only keys created on the Agency plan carry, and the browser-extension endpoints need the engagement scope that only extension keys carry. The required_scopes and granted_scopes fields list what was needed and what the key has.
workspace_access_required - Workspace access does not allow this
The workspace role, or the access limited to specific brands, of the signed-in member or of the member who created the key does not allow this. A key acts with its creator's current role: adding or removing a domain needs an admin or owner, pinning a prompt needs an editor or above. Console actions apply to the whole workspace, so they need an admin or owner with access to all brands. Ask a workspace owner to change the access.
billing_payer_required - Only the member who pays can do this
Buying credits and changing the spend cap or low-balance reminder charge the card that pays for this workspace, so only that member can do them. The buyer field names who that is. Ask them to add credits.
workspace_read_only - Workspace is read-only
The workspace this key or session belongs to is read-only right now, so changes are paused. Reads keep working, and revoking a key or disconnecting the browser extension is always allowed. Retry the change once the workspace is active again.
prompt_limit_reached - Tracked prompt limit reached
The workspace already tracks as many prompts as its plan allows. The current and limit fields give the count and the cap. Unpin a prompt, or upgrade the plan, before tracking another.
idempotency_required - Idempotency-Key header required
This request must carry an Idempotency-Key header: requests that add or remove a domain or a prompt, or start a check, require one. Generate a fresh UUID for each logical operation and resend the request with it.
rate_limit_unavailable - Rate limiter temporarily unavailable
The rate limiter could not be reached, so the request was refused rather than served unmetered. Retry after the Retry-After interval.
domain_not_found - Domain not found
No domain with that id is accessible to this key. A domain that does not exist, one that was removed, one in another workspace, and one outside the key creator's brand access all return the same response.
not_found - Resource not found
No resource with that id is accessible. Returned for competitors, scans, prompts, Console keys, and Console webhook endpoints. An id that belongs to another workspace returns the same response.
domain_already_tracked - Domain already tracked
The domain is already tracked in this workspace. List domains to find its id.
domain_limit_reached - Domain limit reached
The workspace already tracks as many domains as its plan allows. The current and max fields give the count and the cap. Remove a domain, or upgrade the plan, before adding another.
pin_limit_reached - Pinned prompt limit reached
The domain already has as many pinned prompts as it can hold. The current and limit fields give the count and the cap. Unpin a prompt before pinning another.
workspace_not_found - Workspace not found
No workspace with that id is accessible to the signed-in user. A workspace that does not exist and one you are not a member of return the same response.
internal_error - Internal server error
An unexpected error occurred. Retry reads with backoff. Include the request_id when contacting support.
console_account_required - Console account required
The signed-in user has no Console account, or the account behind the key no longer exists. Create a Console account before using the Console API.
insufficient_credits - Not enough credits
Your credit balance does not cover this check. The required_credits, current_balance, and purchase_url fields say how many credits are needed, what the balance is, and where to buy more.
scan_already_running - Check already running
Another check is pending or running for this domain. Wait for it to finish, or cancel it, before starting a new one.
platform_unavailable - AI platform temporarily unavailable
One or more of the requested AI platforms is paused right now, so the check was not started and no credits were charged. The unavailable_platforms field lists which. Remove them from platforms and resend, or retry later; the platforms endpoint reports each platform's enabled state.
results_not_ready - Check results not available
Results exist only for a completed check. The status field says why there are none: pending or running means the check is still collecting answers, so retry once it completes (the scan.completed webhook carries the results URL); failed or cancelled means it ended without results, and its credits were refunded unless it was cancelled while running.
http_404 - Not found
The path does not exist. Check the URL against the API reference.
http_405 - Method not allowed
The path exists but does not accept this HTTP method.
Retry semantics
- Most 4xx responses are final: retrying the same request will fail the same way. The exceptions are
429 rate_limitedand409 idempotency_in_progress; wait for theRetry-Afterinterval and retry. 404 domain_not_foundis returned only for a domain id: the domain does not exist, was removed, or is not accessible to the key. A missing competitor, scan, or prompt returns404 not_found.- When a domain cannot be read because of a temporary outage, the API answers
503 service_unavailablewith aRetry-Afterheader rather than404, so a404always means the domain is not there for your key. - 5xx responses to reads are safe to retry with exponential backoff and jitter. Cap attempts at 5.
- A write that failed is not stored for replay, and it releases its
Idempotency-Key: a corrected retry with the same key is processed as a new request. After a 5xx on a write, check whether the change was applied (for example, list the domains) before resending it. See Idempotency.
Reporting issues
When contacting support, include the request_id from the problem document. It lets us trace that request end to end.