codesays what went wrong. Build your error handling on it; it won’t change.messagedescribes the problem for a person reading logs. It can change, so don’t match on it.traceIdidentifies this request. Include it when you contact Reclosed, so the request can be found.
Error codes
unauthorized (401)
The key is missing, malformed or revoked.
What to do: check the request sends the full key as Authorization: Bearer rk_live_…. If the key was revoked or lost, generate a new one.
forbidden (403)
Reserved: no endpoint returns it today. It would mean the key is valid but not allowed to read this.
What to do: if you ever get it, contact Reclosed.
not_found (404)
No such item, or it belongs to another account. The two look the same on purpose, so an id can’t be tested for existence.
What to do: check the id, and use ids the API has returned to you.
invalid_params (400)
A query parameter isn’t in a form the API accepts. Today this happens on /opt-outs, when the cursor isn’t one it issued.
What to do: pass nextCursor back exactly as you received it.
rate_limited (429)
Too many requests.
What to do: wait the number of seconds in the Retry-After header, then retry. See Rate limits.
result_too_large (413)
The request would read more rows than the endpoint allows, for example on a very large campaign.
What to do: retrying won’t help. The message says what to narrow; if you can’t, contact Reclosed.
unavailable (503)
A temporary problem on Reclosed’s side, such as being unable to verify your key at that moment. Your key is fine.
What to do: retry after a short wait, waiting longer after each failure.
internal_error (500)
Something unexpected failed on Reclosed’s side.
What to do: retry later. If it keeps happening, contact Reclosed with the traceId.
Each endpoint in the API reference lists which of these it can return. Treat any code you don’t recognise as a general failure, so your integration copes if a new one is added.
