# Errors Every error response has the same shape: ```json { "success": false, "error": "human readable message" } ``` | Status | Meaning | Retry? | |---|---|---| | `400` | Malformed request | No, fix the request | | `401` | Missing or invalid API key | No | | `402` | Monthly quota exceeded | Not until the period resets | | `403` | Admin disabled, or embed origin not allowed | No | | `404` | Not found, or a link that was never issued | No | | `410` | Link expired or already used | No, issue a new link | | `429` | Rate limited | Yes, after `Retry-After` | | `500` | Our fault | Yes, with backoff | ## 402 is not 429 A quota is a commercial ceiling, not a speed limit. It clears when the billing period rolls or when the plan changes, so retrying sooner will not help. The body tells you where you stand: ```json { "success": false, "error": "Monthly verification quota exceeded", "details": { "used": 100, "quota": 100, "periodResetsAt": "2026-09-01T00:00:00.000Z" } } ``` Sandbox traffic is never blocked by a quota, so your developers keep working while live traffic is capped. ## Link errors `410` distinguishes "already used" from "expired", and both messages are written to be shown to the recipient as-is. Every other rejection returns the same generic `404`, deliberately: distinguishing "no such link" from "revoked link" would turn the endpoint into an oracle for probing token validity.