Skip to content

Error Handling

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

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}

Set a 5 second timeout. Guard responds in under 200ms on cache hit and under 1s on cold.

Do not retry synchronously in the request path. If you want retries:

  1. Accept the payment with verdict unknown
  2. Queue a background re-check
  3. If the recheck comes back disposable, flag the order in your admin panel

The user should never see a spinner because Guard is slow.

  • 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)

Log every verdict unknown response. If more than 1% of checks return unknown over a 5-minute window, alert.