Error handling
VerifyVAT uses a clear and predictable error model.
All errors follow the Response envelope common structure and are made up of:
| Property | Description |
|---|---|
success | false when an error occurs |
code | Machine-readable error code |
message | Human-readable explanation (not for programmatic use) |
timestamp | When the response was generated, in milliseconds |
Errors always originate at one of three layers:
-
Request validation
Malformed JSON, missing fields, invalid parameters, etc. -
Authentication & subscription
Missing/invalid API key, inactive plan, quota exhaustion. -
Internal execution errors
Rare, usually related to external registry failures or unexpected exceptions.
Regardless of the origin, the response format remains identical.
Only code and message will differ.
A typical error response looks like this:
POST https://api.verifyvat.com/v1/verifyContent-Type: application/jsonx-api-key: invalid_key{ "success": false, "timestamp": {current-time-ms}, "code": "invalid-api-key", "message": "Invalid API key", "data": null}This page describes how to interpret these errors and how to respond to them in your integration.
Canonical error codes
These result codes are stable and safe for programmatic use.
They appear in the top-level code property and reflect the final outcome of the request.
| Code | Status | Meaning |
|---|---|---|
bad-request | 400 | The request is invalid. Check parameters and the request format. |
missing-api-key | 401 | No API key was provided. Include it in the x-api-key header or api-key parameter. See Authentication. |
invalid-api-key | 401 | The API key is invalid or has been revoked. |
no-active-subscription | 403 | You do not have an active subscription. Manage your plan in Profile › Billing. |
incomplete-subscription | 403 | Your subscription purchase is pending. Complete it via the billing portal. |
past-due-subscription | 403 | Your subscription is past due. Billing requires attention. |
monthly-quota-exceeded | 429 | You exceeded your monthly included quota and cannot be billed for more. Upgrade or wait until the next cycle. |
daily-limit-exceeded | 429 | You exceeded your daily request limit. Upgrade your plan or wait until the next day. |
burst-limit-exceeded | 429 | You exceeded the per-second rate limit for your plan. Reduce request frequency. |
unexpected-error | 500 | An internal error occurred. Try again later or contact support. |
The message field always contains a human-readable explanation of the error, should you need it for debugging or support.
Registry-level failures
Registry failures do not produce top-level API errors.
Instead, they appear inside process.sources[] and process.output of the Verify an ID endpoint payload. As documented in Response envelope, these failures are considered part of normal operation. The top-level request will still succeed. For fallback related behaviour in case of error, see Caching and stale data.
Unexpected errors
Unexpected internal errors are rare, but they can happen.
Internal errors do not leak stack traces or implementation details.
If available, contact support with the request trace ID for further investigation. You can find it in the CW-Trace-Id response header.
Best practices
- Handle errors using
code, notmessage - Treat HTTP
statusas a hint,codeis authoritative - Inspect
process.sources[]to understand registry-level behaviour forVerify an IDrequests - Retry only when HTTP
statusis500or registry failures indicate temporary unavailability - Do not retry on
429without backoff, these limits are enforced intentionally
Our official SDKs include built-in support for handling rate limits and retries with exponential backoff. If your language is not supported, you can implement similar logic based on the guidelines above. See SDK overview for reference implementations.