Error Codes
All errors follow a consistent JSON envelope:
{ "error": { "code": "ERROR_CODE", "message": "Human-readable message", "request_id": "req_...", "details": {} }}Error codes
Section titled “Error codes”| Code | HTTP | Description | Action |
|---|---|---|---|
UNAUTHORIZED | 401 | Missing, invalid, or revoked token | Verify your token is correct and active |
FORBIDDEN | 403 | Scope, site, plan, or workspace restriction | Check token scope and site access |
INVALID_METHOD | 405 | HTTP method is not supported on this endpoint | Use the method documented in the API reference |
INVALID_PARAMS | 422 | Invalid query parameters or unsupported values | Fix parameters per the OpenAPI spec |
RETENTION_EXCEEDED | 422 | from date is older than plan retention | Adjust from — check details.min_allowed_from |
REPORT_RESPONSE_TOO_LARGE | 422 | Serialized report response exceeds the hard 5 MiB budget | Use Content summary or reduce the range/limit |
RATE_LIMITED | 429 | Token exceeded short-window rate limit | Wait until X-RateLimit-Reset and retry |
HARD_CAP_REACHED | 402 | Monthly hard cap exhausted | Wait for next billing period or upgrade plan |
REPORT_LOCKED_BY_PROFILE | 409 | The route family requires Extended collection | Use a compatible site/profile or stay on a Strict-safe route |
REPORT_NOT_AVAILABLE_FOR_REQUESTED_PERIOD | 409 | The site is Extended now, but the requested period predates compatible Extended data | Retry on a later period and inspect details |
NOT_FOUND | 404 | Unknown endpoint | Check the URL path |
SITE_NOT_FOUND | 404 | Dashboard/query route requested an unknown site | Verify the selected site_id and org access |
SITE_INACTIVE | 409 | Dashboard/query route requested an inactive site | Reactivate the site or switch to an active one |
QUERY_TIMEOUT | 504 | Athena/reporting query exceeded the timeout | Retry with a shorter range or try again later |
INTERNAL_ERROR | 500 | Unexpected backend failure | Retry with exponential backoff |
Example responses
Section titled “Example responses”UNAUTHORIZED (401)
Section titled “UNAUTHORIZED (401)”{ "error": { "code": "UNAUTHORIZED", "message": "Invalid API token", "request_id": "abc123" }}RATE_LIMITED (429)
Section titled “RATE_LIMITED (429)”{ "error": { "code": "RATE_LIMITED", "message": "Rate limit exceeded for this token", "request_id": "abc123", "details": { "retry_after_seconds": 60 } }}Response headers: X-RateLimit-Limit: 300, X-RateLimit-Remaining: 0,
X-RateLimit-Reset: 1740000060.
RETENTION_EXCEEDED (422)
Section titled “RETENTION_EXCEEDED (422)”{ "error": { "code": "RETENTION_EXCEEDED", "message": "Query start is outside plan retention", "request_id": "abc123", "details": { "min_allowed_from": "2025-12-01" } }}HARD_CAP_REACHED (402)
Section titled “HARD_CAP_REACHED (402)”{ "error": { "code": "HARD_CAP_REACHED", "message": "Hard cap reached for current billing period", "request_id": "abc123" }}REPORT_RESPONSE_TOO_LARGE (422)
Section titled “REPORT_RESPONSE_TOO_LARGE (422)”{ "error": { "code": "REPORT_RESPONSE_TOO_LARGE", "message": "The report response exceeds the maximum response budget.", "request_id": "abc123", "details": { "include": "full", "range_days": 90, "measured_bytes": 5300000, "max_bytes": 5242880 } }}This rejection is not truncated, consumes zero units, and does not create a final response-cache entry.
REPORT_LOCKED_BY_PROFILE (409)
Section titled “REPORT_LOCKED_BY_PROFILE (409)”{ "error": { "code": "REPORT_LOCKED_BY_PROFILE", "message": "This report requires Extended collection for the selected site.", "request_id": "abc123", "details": { "route": "goals", "classification": "extended_only", "currentProfile": "strict", "availability": { "route": "goals", "classification": "extended_only", "currentProfile": "strict", "collectionProfileEffectiveAt": "2026-03-18T09:00:00.000Z", "current": { "status": "locked_by_profile", "reason": "extended_data_required", "requestedStart": "2026-03-01T00:00:00.000Z", "requestedEnd": "2026-03-31T23:59:59.999Z", "compatibleStart": null, "compatibleEnd": null }, "compare": null, "sections": [] } } }}Recommended client behavior
Section titled “Recommended client behavior”- Always log
request_idon failures for support troubleshooting - Retry with exponential backoff for
500 INTERNAL_ERROR - Wait for
X-RateLimit-Resetbefore retrying429 RATE_LIMITED - Do not retry
401,403,402, or422— these require fixing the request or token configuration - For
409 REPORT_LOCKED_BY_PROFILEorREPORT_NOT_AVAILABLE_FOR_REQUESTED_PERIOD, inspecterror.details.availabilityand adjust the route family or the requested period - For mixed routes that still return
200, inspectavailability.readModelfirst to identify the strict-safe baseline, thenavailability.sectionsto detect attribution or advanced slices that remain locked inStrict - For
402 HARD_CAP_REACHED, check usage withGET /v1/usage/currentand wait for the next billing period
Dashboard site setup errors
Section titled “Dashboard site setup errors”The dashboard and control plane also use stable site-centric codes during site registration and ownership verification:
| Code | Meaning | Typical user action |
|---|---|---|
INVALID_SITE_HOSTNAME | The entered hostname is malformed | Enter a valid hostname without an email or unrelated path |
SITE_SCOPE_NOT_ALLOWED | The requested domain-wide scope is not allowed for this hostname | Track the site hostname-by-hostname |
HOSTNAME_PATTERN_OUT_OF_SCOPE | An advanced hostname pattern is outside the site’s scope | Create another site or adjust the allowlist |
SITE_SCOPE_ALREADY_CLAIMED | Another workspace already verified this site scope | Contact support if ownership should be transferred |
SITE_DNS_VERIFICATION_FAILED | The TXT record was not found yet | Check the record name, value, and DNS propagation |
SITE_DNS_VERIFICATION_UNAVAILABLE | DNS verification does not apply to this site type | Keep collecting data and skip verification for now |