Response Format
Every Vatly response follows the same envelope pattern: eitherdata or error, always accompanied by meta. This means if (response.error) always works as a check.
Success response
data fields
| Field | Type | Description |
|---|---|---|
valid | boolean | Whether the VAT number is active and registered |
vat_number | string | The normalized VAT number |
country_code | string | Two-letter country code |
company | object | null | Company name and address (when valid and available) |
company.name | string | Registered company name |
company.address | string | null | Registered address |
consultation_number | string | VIES/HMRC consultation number. Only present when requester_vat_number is provided. Not available for CH, LI, NO, or AU validations |
requested_at | string | ISO 8601 timestamp of the validation |
Error response
error fields
| Field | Type | Description |
|---|---|---|
code | string | Machine-readable error code |
message | string | Human-readable explanation |
docs_url | string | Link to the error documentation page |
meta fields
Present on every response, success or error.
| Field | Type | Description |
|---|---|---|
request_id | string | Unique request identifier (UUID) |
request_duration_ms | number | Total request processing time in milliseconds (success responses only) |
cached | boolean | Whether the result came from cache. Omitted when not applicable |
cached_at | string | ISO 8601 timestamp of the cached result. Omitted when not cached |
stale | boolean | true when serving an expired cached result due to upstream failure. Omitted when not stale |
source_status | string | Upstream data source reliability: "live" (fresh result), "unavailable" (upstream down, stale cache served), or "degraded" (possible silent false negative). Applies to all upstream sources (VIES, HMRC, BFS, Bronnysund, or ABR). Only present on fresh upstream lookups and stale fallbacks |
mode | string | "test" when using a test key. Omitted for live keys |
Batch items
Each item in a batch validation response uses the same envelope:- Success:
{ data: VatValidationData, meta }. Thedataobject is the exact same shape as the single validate endpoint - Error:
{ error, meta }. Themetacontains thevat_numberthat failed
meta contains cache fields (cached, cached_at, stale) and source_status when applicable. Request-level fields like request_id and request_duration_ms live on the top-level meta.
Response headers
| Header | When present | Description |
|---|---|---|
X-Request-Id | Always | Unique request identifier matching meta.request_id |
X-RateLimit-Limit | Authenticated requests | Total requests allowed this period |
X-RateLimit-Remaining | Authenticated requests | Requests remaining this period |
X-RateLimit-Reset | Authenticated requests | When the quota resets (ISO 8601) |
X-Burst-Limit | Authenticated requests | Per-minute burst limit for your tier |
X-Burst-Remaining | Authenticated requests | Burst requests remaining this minute |
Retry-After | 429 and 503 responses | Seconds to wait before retrying |
Request ID header
Every response includes anX-Request-Id header matching meta.request_id.
You can pass your own X-Request-Id header and it will be echoed back - useful for correlating requests in your own logging.