Errors

Every non-2xx answer is an application/problem+json document (RFC 9457). Branch on code, show detail to a human, keep instance for support. The type of each problem is this page’s address plus # and the code: it links to the row of that code below.

The catalogue

Generated from the same list the code uses: a code cannot exist in the API without appearing here.

CodeHTTPTitleWhat to do
invalid_parameter400A parameter is missing or malformedRead detail and errors[]: each entry names the parameter and the rule it broke. Nothing was counted against your quota.
unauthorized401The API key is missing, unknown or revokedSend Authorization: Bearer vp_live_…. Keys are shown once at sign-up; a revoked key cannot be restored, create a new one.
forbidden_for_tier403This option is not included in your tierThe requester option (consultation number) and the record option (a stored validation record) need prepaid credits or the monthly plan; the bulk endpoints need the monthly plan. See /pricing.
not_found404No such resourceCheck the path against /openapi.json. Country codes are ISO 3166-1 alpha-2 (Greece is EL for VAT, GR for IBAN).
quota_exceeded402Monthly allowance and credits are used upThe free allowance resets on the first of the month (UTC). Buy a credit pack or the monthly plan at /pricing; the key stays the same.
rate_limited429Too many requests per secondHonour Retry-After and the RateLimit-* headers. Free keys may send 2 requests a second; the monthly plan 10. Use the bulk endpoint for lists.
vies_unavailable503VIES or the member state is unavailable and no cached answer existsThe Commission’s service or that country’s tax administration did not answer and we hold no previous answer for this number. Retry after Retry-After seconds; the call was not counted.
vies_blocked503VIES refused the request (concurrency or blocking)VIES answered MS_MAX_CONCURRENT_REQ, GLOBAL_MAX_CONCURRENT_REQ or a blocking code. Retry after Retry-After seconds; the call was not counted.
checkout_closed503Paid checkout is not open yetJoin the waitlist on /pricing; you will be e-mailed when the merchant of record approves the site. The free tier works now.
store_unavailable503The database is not configuredSign-ups and keys need a database; this deployment runs without one. Try again later.
upstream_unavailable503The public registry did not answer and no cached answer existsThe French company-registry APIs (recherche-entreprises.api.gouv.fr, INSEE Sirene) did not answer in time or refused the request. Retry after Retry-After seconds; the call was not counted.
unprocessable_file422The uploaded rows cannot be turned into a returnRead errors[]: each entry names the row (1-based, header excluded) and the rule it broke (unknown country, rate not in the table for the period, VAT does not equal net × rate, date outside the period). Fix the export and resend; nothing was counted.
payload_too_large413Too many rows or too many bytesA request body is limited to 4.5 MB (4,500,000 bytes, the hosting platform’s limit); one OSS return to 50,000 rows. Aggregate per country and rate before sending, or split the quarter by month; for an e-invoice, send the XML rather than a PDF carrying large attachments.
einvoice_unsupported422The invoice uses a feature the e-invoice writers do not produceNothing is ever dropped silently: a field the writers cannot put in the file is refused. Read feature and path (the first one) and unsupported[] (all of them), remove or change those fields, and resend. The list of what v1 does not write is on /einvoice-api. Nothing was counted.
einvoice_invalid422The invoice breaks the rules of its formatRead violations[]: each names the published rule (BR-*, BR-DE-*, PEPPOL-*, or VP-* for Veriport’s own checks of national practice), its path in your JSON (or the XPath in the produced file) and what it requires. No file was produced and nothing was counted.
einvoice_unreadable422The file is not an e-invoice the API can readSend a UBL 2.1 Invoice or CreditNote, a UN/CEFACT CII D16B CrossIndustryInvoice, or a ZUGFeRD / Factur-X PDF with its XML embedded; as the raw body (Content-Type application/xml or application/pdf) or as the file part of multipart/form-data. Nothing was counted.
idempotency_conflict409The Idempotency-Key is in useThe same Idempotency-Key was sent with a different body or query (a key is bound to one request), or a request with that key is still being processed. Send a new key for a new request; retry the same request after Retry-After seconds when it was still in progress. Nothing was counted.
internal500Unexpected errorNothing was counted. If it repeats, write to hello@veriport.io with the instance id.

Example

A free key asking for a consultation number:

403 Forbidden · application/problem+json
{
  "type": "https://veriport.io/docs/errors#forbidden_for_tier",
  "title": "This option is not included in your tier",
  "status": 403,
  "detail": "The `requester` option asks VIES for a consultation number, the evidence a tax audit accepts; it is included with prepaid credits and the monthly plan. See https://veriport.io/pricing.",
  "instance": "req_7Qx2mZk9Lp",
  "code": "forbidden_for_tier"
}

What is not an error

An invalid VAT number or IBAN is a normal answer: 200 with valid: false. A VAT number that cannot be one (wrong structure or check digit) answers 200 with valid: false, source.kind: "structure_only" and upstream.status: "not_called", and is not counted. A member state that is down with a cached answer available answers 200 with source.kind: "cache", source.stale: true and upstream.status: "member_state_unavailable". A GB prefix is not aliased to XI: it answers country_unknown; check UK numbers with HMRC’s free service (gov.uk/check-uk-vat-number); Northern Ireland goods traders send XI.

Questions

Why is a 503 not counted?
Because you received no answer. Only a 200 with a live, cached or table answer costs a call.