Four ways a check can go wrong
A fifth case is not an error. A
sync request that doesn’t fit the inline budget returns mode: "async" with a poll.url. Check mode and poll. See Enforce Content.
The full list of status codes is on Errors.
Rate limits and the daily quota
A429 means the request was not processed, so it is safe to resend. There are two kinds, and they ask you to wait very different amounts of time:
Retry with backoff
Both samples follow the same rules:- Retry
429, any5xx, network errors, and timeouts. Never retry another4xx. - Honor
Retry-After. Otherwise back off 1, 2, 4, then 8 seconds, plus up to a second of jitter. - Never wait more than 30 seconds. A longer
Retry-Aftermeans a daily quota, so stop and apply your fail policy. - A
4xxraisesClientError, and the fail policy does not catch it. A wrong or revoked key must fail loudly, not quietly turn enforcement off.
Resending a submission after a
5xx or a timeout can create a second job, because the first may have been accepted before the failure. Set your own message id in metadata, which is merged into the job, so you can spot the duplicate in your own records. Polling is safe to repeat. Do not retry POST /api/policies/import/start with the same import_id. See Errors.Fail open or fail closed
When a check is unavailable, you choose one of two defaults. Make the choice per use case and write it down.
These are recommendations, not defaults the API applies. ZeroDrift never delivers or blocks anything for you. Your code does.
Whichever you choose:
- Count it. Log each unchecked item with the
job_idif you have one, the status code or error, the attempt count, and which policy applied. Do not log the content itself. Alert when the count rises. - Don’t hide it. Show reviewers that a message went out unchecked. A silent fail-open looks the same as a Pass.
- Treat
ClientErroras a bug. A401or403after a key change is a misconfiguration, not an outage. Neither policy should absorb it.
Do not
- Do not retry a
4xxwithout changing the request or the resource. - Do not re-send content that received a Block verdict. See Act on Each Verdict.
- Do not sleep through a
Retry-Afterof3600inside a request. Fail per your policy and retry from a queue. - Do not poll without a deadline. Use the 120-second deadline above, or one that fits your latency budget.
Next
Act on Each Verdict
Decide what the user sees for Pass, Fix, Block, and Escalate.
Errors
Every status code the API returns.

