Errors
Every error the Revnu API returns, the JSON body each one carries, and whether to retry, fix the request or re-read the card.
Every error is JSON with an error field, sent with Cache-Control: no-store. Some carry one more field that tells you what to do next.
{ "error": "forbidden", "requiredScope": "review:write" }| Status | error |
Extra fields | What to do |
|---|---|---|---|
400 |
A sentence naming the problem, such as limit must be a positive integer |
none | Fix the request. Retrying it unchanged gets the same answer. |
401 |
unauthorized |
none | The token is missing, malformed, unknown or revoked. Mint a new one. |
402 |
setup_pending |
message |
The account hasn't started its trial yet. Only /me and the setup routes answer. Finish setup with GET /setup. |
403 |
forbidden |
requiredScope |
The token lacks that scope. Mint a token that has it. |
404 |
not found |
none | The id does not exist or belongs to another account. |
404 |
unknown workflow run |
none | GET /leads?workflowRunId= named a run that isn't yours. |
409 |
invalid_action |
actions |
The card no longer accepts that verb. Re-render from actions. |
409 |
use_send |
message, actions |
A Gmail card was sent to /answer. Use POST /review/{id}/send. |
409 |
rejected |
message |
A settled refusal, such as a card that was already handled, a card that must be approved in the dashboard, or an account paused for payment. Show the message. |
409 |
paused, schedule_pending, schedule_error |
message |
Running a workflow that is paused, still being scheduled, or has a schedule Revnu couldn't read. |
409 |
this address unsubscribed and cannot be unblocked |
none | The address opted out, so it stays on the block list. |
429 |
rate limited |
Retry-After header |
Wait that many seconds, then retry. |
500 |
server misconfigured |
none | Our fault. Retrying will not help until we fix it. |
503 |
temporarily unavailable |
Retry-After header |
Infrastructure, not your request. Retry the same call unchanged. |
503 |
delivery_pending, unavailable |
message, Retry-After header |
Gmail sends only: delivery is still being confirmed, or the mail service is down. Retry the same send. |
400: the request is wrong
The message is written to be shown to a developer, so log it. Common ones: body must be JSON (the body is not a JSON object), cursor is not valid (pass back the nextCursor you were given, unmodified), limit must be a positive integer, text required, unrecognized status. Routes that take a body name any field they don't know (unknown field: …), so a typo fails loudly instead of being ignored. A workflow too big for one run says how far over it is, for example steps are too long for one run, about 800 characters over. Shorten some details or split this into two workflows.
401 and 404 look alike on purpose
A card, lead or workflow id from another account is a 404, exactly as if it did not exist, so a token cannot probe for ids it should not see. An unknown or revoked token is always 401, never 404.
409: re-read, don't retry
A 409 is a decision, not an outage. Two people, or a person and the trust ladder, can act on the same card, so a verb that was valid when you listed the queue can be gone a second later:
{ "error": "invalid_action", "actions": ["snooze", "dismiss"] }Draw the card again from actions and move on. rejected carries a message a person can read, for example This was already handled.
Some refusals are about the account, not the card. While a trial is waiting for a card, or an account is paused for a failed payment, agent messages answer 409 rejected with a message saying how to fix it in the dashboard. LinkedIn invite and message cards and gift cards answer 409 to approve through the API: approve those on the dashboard's Review page.
429 and 503: back off and retry
Both send Retry-After in seconds. It is computed from the bucket, so retrying sooner only spends another request. See Rate Limits for the numbers. A 503 means the token could not be checked, the limiter was down for a write, or a delivery answer was lost. Retrying is safe: approving a card that already shipped comes back as a 409, and agent messages and workflow runs take a clientRequestId so a retried call does not happen twice.
Frequently Asked Questions
Is there a machine-readable list of routes and errors?
Yes. /openapi.json describes every route, its scope and the error statuses it can return. Each operation links back to its page here.
Why did an approve return 409 when the card was pending a moment ago?
Someone else resolved it, or it shipped itself at autoResolveAt. The body's actions says what the card accepts now; an empty list means it is settled.
Which errors are safe to retry unchanged?
429 and 503, after Retry-After. Everything else answers the same way until you change the request or the state behind it.