Sign inConnect your AI
api

Errors

Every error is a problem details object with a stable code and the request id.

Updated · API v1

The format

Errors answer with Content-Type: application/problem+json (RFC 9457) and the HTTP status of their type. The type is the URL of the type's page below; code is the same type as a short string, for your code to switch on.

A 400 answer
{
  "type": "https://www.adspy.sh/docs/api/errors/invalid-request",
  "title": "Invalid request",
  "status": 400,
  "detail": "Invalid query: query.limit: Too big: expected number to be <=100",
  "code": "invalid_request",
  "request_id": "a91c4e07-2b6d-4f38-8e15-c7d09b3f62a4",
  "instance": "/api/v1/creatives",
  "errors": [{ "path": "query.limit", "message": "Too big: expected number to be <=100" }]
}
FieldMeaning
typeThe URL of the error type's documentation page.
titleThe type's short title, the same for every occurrence.
statusThe HTTP status.
detailWhat went wrong with this request, in English.
codeThe type as a stable string, such as invalid_request.
request_idThe request's id, also in the X-Request-Id header. Quote it to support.
instanceThe path that was requested.
errorsOn invalid_request only: each field problem, with its path (query.limit, body.brand_keys.0) and message.

Handling errors

  • Switch on code, not on detail: detail is for people and can change.
  • New codes may be added; treat an unknown code by its HTTP status.
  • 5xx answers never carry internal messages, and nothing was charged. A 401 never says whether a key exists.
  • Retry only the types marked retryable, after Retry-After when it is sent, with the same Idempotency-Key for a POST.

Error types

StatusCodeMeaningRetry
400invalid_requestA path parameter, query parameter or body field is missing, unknown or out of range, or the body is not valid JSON.No
400invalid_cursorThe cursor was not issued by Adspy, was altered, expired after 24 hours, belongs to another organization or another list, or was sent with different filters than the request that returned it.No
400idempotency_key_requiredEvery POST needs an Idempotency-Key header.No
401unauthorizedThe Authorization header is missing, or the key is unknown, expired or revoked.No
402payment_requiredThe organization's contract does not cover this request, or a spending limit an organization admin set in Adspy stops it.No
402partner_key_cap_reachedPartner keys only: the credits this key's requests settled this calendar month (UTC), plus the most this request can settle, pass the key's monthly cap.No
402partner_tenant_cap_reachedPartner keys only: the request named a trial cap in X-Partner-Credit-Cap, and the credits this tenant settled since it was created, plus the most this request can settle, pass it. The answer carries cap and used.No
403enterprise_requiredThe REST API is part of Adspy Enterprise, and this organization has no active Enterprise contract.No
403insufficient_scopeThe key lacks the permission this route needs (read, actions or export).No
403forbiddenThe credential is recognized but may not make this request, for example a partner key that names another tenant than the one it is pinned to.No
403not_offered_to_partnerPartner keys only: exports and usage are not offered to partner keys. Exports settle in the background, after the answer that would bill them; a partner's usage is its own feed.No
404not_foundThe route does not exist, or the brand, creative, post, collection, fetch or export is unknown to the key's workspace.No
405method_not_allowedThe route exists but not with this HTTP method.No
409idempotency_conflictThis Idempotency-Key was already used for a different request, or for a request that failed without a charge.No
409operation_in_progressA request with this Idempotency-Key is still running.Yes
409conflictThe resource changed while the request ran (a fetch replaced, a report expired).Yes
413payload_too_largeThe body, the query string or the result passes its size limit.No
415unsupported_media_typeA POST or PATCH body was not sent as JSON.No
422instagram_not_in_apiThe request names Instagram: a platform, a post id, an account, a profile link or an export of Instagram data. Instagram data is not offered through the API.No
429rate_limitedThe key sent more requests a minute than its contract allows, or the organization more research reads than its limit (120 reads a minute, or the contract's per-key rate when that is higher), shared by its keys and its MCP connections.Yes
429fetch_quota_exceededThe organization started its contract's number of new brand or account collections this calendar month (UTC; 200 by default), counted across its API keys and its MCP connections.Yes
429partner_fair_usePartner keys of a client with a fair use policy only: this tenant settled its rolling 48-hour research allowance (scope research), or started its rolling 30-day number of new brand or account collections (scope collections). The answer carries scope and retry_at, the exact time the request fits again.Yes
429fetch_limitedThe organization has three fetches running, or this advertiser was requested in the last hour.Yes
500internal_errorAdspy failed to answer. Nothing was charged.Yes
503service_unavailableA dependency (the creative library, collection or exports) is temporarily unavailable. Nothing was charged.Yes
504timeoutThe library query exceeded its time limit. Nothing was charged.Yes