Errors

Pre-release v1, published 2026-09-14. This page commits to the shape of the API, not to a date. We will build exactly what is documented here. The shape can still change until 2026-10-14; after that, changes follow Versioning and stability.

The banner comes off one page at a time as each route goes live. While it is here, build against the contract and assume the route is not callable yet.

Shape

{
"error": {
"code": "plan_inactive",
"message": "Your plan is not active.",
"request_id": "req_8f2Kq9mR"
}
}

Always log request_id. It is what lets us find your exact request when you contact support.

Codes

StatuscodeMeaningWhat to do
400bad_requestA parameter is missing, unparseable, or out of rangeFix the query string
401invalid_keyKey wrong or revokedCheck the header; contact sales
401key_expiredKey past its expiry dateAsk for a new key
403plan_inactivePlan lapsedNot transient. See When a plan lapses
403capacity_exhaustedRobot or channel capacity used upDelete one, or ask sales to raise it
403channel_not_in_planPlan does not include this channel typeContact sales
403forbiddenThe required role is not on your accountContact your account manager
404not_foundNo such resource, or not yoursCheck the id
409conflictDuplicate external_id, or channel type already presentUse a different value
409handshake_pendingAn unexpired Instagram handshake existsWait for it to expire, or reuse it
410handshake_expiredThe page owner took too longStart a new one
422validation_failedMalformed requestFix the payload
422return_url_not_configuredNo return URL configured for youContact us before connecting
429rate_limitedToo many requestsHonour Retry-After. See Rate limits
503upstream_unavailableA channel provider is downRetry with backoff

400 and 422 are different failures

400 means the request never got as far as validation: a required parameter is missing, a timestamp will not parse, a limit is out of range. 422 means the request was well formed and its contents were rejected, such as a comment rule with no reply and no DM.

{
"error": {
"code": "bad_request",
"message": "`from` must be earlier than `to`.",
"request_id": "req_8f2Kq9mR",
"details": { "from": "2026-09-30T00:00:00Z", "to": "2026-09-01T00:00:00Z" }
}
}

404, not 403, for someone else’s resources

If you request a resource that exists but belongs to another partner, you receive 404, not 403. A 403 would confirm the id exists, which is information you should not be able to probe for.

details

Some errors carry a details object where a number helps you act:

{
"error": {
"code": "capacity_exhausted",
"message": "You have reached the maximum number of channels your plan allows.",
"request_id": "req_8f2Kq9mR",
"details": { "occupied": 10, "requested": 1, "capacity": 10 }
}
}

It is never present on 401 or 404, where extra detail would confirm something you should not learn.

Which errors are worth retrying

RetryDo not retry
429 (after Retry-After)400. The request is malformed
401. The key will not fix itself
503 (with backoff)403. A plan or role state, not a transient fault
422. The payload is wrong
409. The conflict is real

We never name an internal host or service in an error. If you need to know why something upstream failed, send your request_id to your account manager.