Skip to main content
Enforcement sits in front of a send. When a check can’t complete, your code has to choose between delivering unchecked content and holding it. This guide covers what can fail, which failures to retry, and how to make that choice deliberately.

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

A 429 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:
Your limits depend on your plan. See Rate limits, and contact support@zerodrift.ai to raise them.

Retry with backoff

Both samples follow the same rules:
  • Retry 429, any 5xx, network errors, and timeouts. Never retry another 4xx.
  • 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-After means a daily quota, so stop and apply your fail policy.
  • A 4xx raises ClientError, 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_id if 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 ClientError as a bug. A 401 or 403 after a key change is a misconfiguration, not an outage. Neither policy should absorb it.

Do not

  • Do not retry a 4xx without 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-After of 3600 inside 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.