Status Codes
Every error looks the same
Whatever goes wrong, the response body has the same four fields:
{
"code": 503,
"reason": "RISK_SCORE_NOT_READY",
"message": "risk score is still being computed",
"metadata": { "retry_after": "2" }
}reason— branch your handling on this one. It is the stable, machine-readable identifier for what happened.code— the HTTP status, repeated in the body.message— human-facing prose. It may change without notice; do not match on it.metadata— extra key/value context when there is any. The example above carriesretry_after, in seconds.
What you can receive
These are every status and reason the endpoints published on this site return. Values without the GATEWAY_ prefix are just as stable as the ones with it — the prefix says where the outcome was decided, not how much you can rely on it.
| HTTP | reason | What happened | What to do |
|---|---|---|---|
| 400 | PROVIDER_INVALID_ADDRESS | The address was rejected for the chain in the path — either it is not a valid address on that chain, or the intelligence source refused it. | Not retryable. Correct the address and send again. |
| 400 | PROVIDER_UNSUPPORTED_CHAIN | This endpoint does not cover that chain. Coverage is decided per endpoint, so a chain one endpoint accepts another may still reject. | Not retryable. Use a chain supported by this endpoint. |
| 400 | PROVIDER_UNSUPPORTED_TRANSACTION | Transaction endpoints only: the transaction or one of its screening inputs was rejected. On the transaction custom-score endpoint this can surface during polling. | Not retryable. Correct the request and send again. |
| 401 | GATEWAY_CREDENTIAL_INVALID | The request did not pass credential authentication. | Check the Authorization header and credential before sending the request again. |
| 429 | GATEWAY_QUOTA_EXCEEDED | This credential has used up its request quota for the current window. | Retry after the rate-limit window. |
| 502 | GATEWAY_PROVIDER_UNAVAILABLE | We could not get an authoritative answer from the intelligence source behind this endpoint — it was unreachable, timed out, answered with something we could not use, or is not currently in service. | Do not retry immediately. Retry after the source is back in service. |
| 502 | RISK_SCORE_TASK_FAILED | The asynchronous scoring task behind this request reached a terminal, non-transient failure. | Do not keep polling or reuse that task. Send the request again to start a new task. |
| 503 | RISK_SCORE_NOT_READY | The asynchronous scoring task had not finished inside the response window (a few seconds). This is the normal in-progress outcome, not a failure — deep transaction screening returns it routinely. | Retryable. Wait metadata.retry_after seconds and send the same request again. It usually attaches to the task already running rather than starting a new one, but that reuse is the common case, not a guarantee. |
| 503 | GATEWAY_ACCOUNT_UNAVAILABLE | The gateway could not determine whether the credential was valid, so it rejected the request. | Retry. Do not replace the credential based on this response alone. |
Why the status alone is not enough
Two of these statuses carry two different outcomes each, and each outcome requires its own handling:
503 RISK_SCORE_NOT_READYis a score still being computed — wait and re-send, and the run in progress normally continues.503 GATEWAY_ACCOUNT_UNAVAILABLEis us failing to evaluate the request at all.502 RISK_SCORE_TASK_FAILEDis final for that task — a retry requires a new task.502 GATEWAY_PROVIDER_UNAVAILABLErequires waiting until the source is back in service before retrying.
Branch on reason to distinguish a routine in-progress task from a gateway evaluation failure, and a terminal task failure from source unavailability.
Asynchronous risk scores
Risk scoring runs as a task upstream. We poll it for a few seconds and return the score if it lands in that window. If it does not, you get 503 RISK_SCORE_NOT_READY with a retry_after hint. Re-sending the same request usually attaches to the task that is already running rather than starting another — that is the common case, not a guarantee. Deep transaction screening reaches this state routinely; treat it as a normal step, not as an error to alert on.
Terminal outcomes include the score itself, 502 RISK_SCORE_TASK_FAILED, and — on the transaction custom-score endpoint — 400 PROVIDER_UNSUPPORTED_TRANSACTION, which can surface only once polling has started. A RISK_SCORE_TASK_FAILED outcome means that task is gone: send the request again to start a new one, and stop polling the old one.