Errors
Every error response has the same shape:
{ "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:
{
"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.
Reading this as an agent? The raw Markdown is at /docs/errors.md.