Error Handling
HTTP responses
Section titled “HTTP responses”| Status | Meaning | What to do |
|---|---|---|
| 200 | Success | Read verdict from response |
| 400 | Malformed request | Fix the request — do not retry |
| 401 | Missing or invalid X-API-Key | Check env var, alert on-call, fail open |
| 429 | Monthly quota exceeded | Fail open + upgrade prompt |
| 500 | Server error | Fail open — do not retry synchronously |
| 503 | Service unavailable | Fail open, back off, retry in 60s |
Fail-open policy
Section titled “Fail-open policy”Guard is a risk signal, not a payment dependency. If it is down, checkout must still work.
def safe_check(email, client_ip): try: r = requests.post( "https://email.ayzalai.com/v1/check/email", headers={"X-API-Key": os.environ["AYZAL_GUARD_KEY"]}, json={"email": email, "client_ip": client_ip}, timeout=5, ) if r.status_code != 200: return {"verdict": "unknown", "allowed": True} result = r.json() return { "verdict": result["verdict"], "allowed": result["verdict"] not in ("disposable", "invalid"), } except requests.RequestException: return {"verdict": "unknown", "allowed": True}Timeout guidance
Section titled “Timeout guidance”Set a 5 second timeout. Guard responds in under 200ms on cache hit and under 1s on cold.
Retry policy
Section titled “Retry policy”Do not retry synchronously in the request path. If you want retries:
- Accept the payment with verdict unknown
- Queue a background re-check
- If the recheck comes back disposable, flag the order in your admin panel
The user should never see a spinner because Guard is slow.
What NOT to do
Section titled “What NOT to do”- Block the user because Guard returned 500
- Retry 3 times with exponential backoff in the request path
- Cache the verdict for more than a few hours
- Ignore 401 (means your key is misconfigured)
Monitoring
Section titled “Monitoring”Log every verdict unknown response. If more than 1% of checks return unknown over a 5-minute window, alert.
