Errors
Every status and error code the Audrie API returns, and what to do about each.
Audrie uses conventional HTTP status codes. Codes in the 2xx range indicate success. Codes in
the 4xx range indicate a request that failed as sent — a malformed hash, a credential problem,
or a rate limit. Codes in the 5xx range indicate a problem on our side, and are rare.
A determinate verification outcome is not an error. A hash with no record returns 200 with
a verdict of no_record. Reserve error handling for 4xx and 5xx.
Status codes
| Status | Name | Meaning |
|---|---|---|
| 200 | OK | The request succeeded. On a verification, read verdict. |
| 201 | Created | A record was created. |
| 400 | Bad Request | The request is malformed — most often a hash that is not sha256: followed by 64 lowercase hex characters. |
| 401 | Unauthorized | The credential you sent is not usable, or the operation requires one and you sent none. Omitting the header on POST /v1/verifications is not an error; it serves the public tier. |
| 402 | Payment Required | API access, or document authentication, is not enabled for the organisation. |
| 403 | Forbidden | The credential is valid but not permitted to perform this call. |
| 404 | Not Found | The resource does not exist for this organisation and environment. |
| 409 | Conflict | The record cannot be revoked in its current state. |
| 413 | Payload Too Large | The request body is too large. |
| 429 | Too Many Requests | Rate limit exceeded. Back off using Retry-After. |
| 500 | Internal Server Error | Something failed on our side. Retry with backoff. |
| 503 | Service Unavailable | Audrie could not answer the request. Retry with backoff. |
Error codes
Branch on error.code. error.message is written for a human and changes without notice.
| Code | Status | What to do |
|---|---|---|
VALIDATION_FAILED | 400 | Read error.details for the offending field and fix the request. |
UNAUTHENTICATED | 401 | Check the credential, and send exactly one Authorization header. Which of several causes made a supplied credential unusable is not distinguished. |
PAYMENT_REQUIRED | 402 | Enable API access, or document authentication, for the organisation. Neither is a problem with the key, so do not rotate it. On POST /v1/verifications you can drop the Authorization header and keep verifying at the public tier. |
FORBIDDEN | 403 | Read error.message for the cause. If the key lacks a scope the call needs, create a key with that scope. Either way, call from your server, never from a browser, and expect 403 while your organisation's state does not allow the call. |
ORG_NOT_VALIDATED | 403 | Wait. Your organisation is still being validated, and document authentication opens once it completes. Your key is fine, and verification keeps working. |
NOT_FOUND | 404 | Check the id. See the operation's own Errors note for what it does and does not distinguish. |
CONFLICT | 409 | The record is already revoked, or its anchor has not settled yet. Retrying helps only in the second case: check its verdict first. |
PAYLOAD_TOO_LARGE | 413 | Shorten the request to the documented fields. Requests are a few hashes and short identifiers, never a document. |
RATE_LIMITED | 429 | Wait Retry-After seconds. X-RateLimit-Remaining tells you how much budget is left. |
INTERNAL_ERROR | 500 | Retry with backoff. See Retries below. |
SERVICE_UNAVAILABLE | 503 | Retry with backoff. Your credential is still valid — do not rotate it in response to this. |
The envelope
Every error shares one shape, across every Audrie API.
{
"error": {
"code": "VALIDATION_FAILED",
"message": "Validation failed",
"details": { "originalDocHash": "must match sha256:<64 hex chars>" }
}
}details is present on validation failures and carries one message per offending field.
Rate limits
Anonymous requests are limited per client IP. Credentialed requests are limited per credential and per organisation, so one integration cannot starve another and a shared corporate egress IP is not a shared budget.
A credential raises your limit once your organisation is validated. Until then a key is served at
the anonymous limit, like any other public-tier request — see Disclosure tiers.
X-RateLimit-Limit and X-RateLimit-Remaining report the tightest limit that applies, and are
present on normal and rate-limited responses alike. Read them when present rather than requiring
them. X-RateLimit-Remaining is a budget rather than a guarantee: a 429 is still possible under
load. A 429 also carries Retry-After.
Retries
Every operation is safe to retry.
Authenticating a document is idempotent. Your organisation holds one active record per
document hash, so repeating the call returns the record you already have rather than creating a
second. The exception is a record whose anchor failed: a repeat call creates a new one. A retry
after a timeout or a 503 is therefore safe.
Revoking is permanent. On CONFLICT, verify the hash. revoked means you are done. Otherwise
retry once it reports verified_org, or sandbox for a test key.
A credentialed POST /v1/verifications is recorded each time it succeeds, under a new
verificationId. So a retry after a timeout can produce two rows for one document. Reconcile on
verificationId, not on a count of attempts.
A 503 is never a reason to rotate a key
A 401 means stop and fix your credential. A 503 means retry — the credential is still valid
and nothing about your organisation has changed. Rotating a key in response to a 503 turns a
transient failure into an outage of your own.