Documentation
RapidAPI base URL: https://vatpulse1.p.rapidapi.com · Direct base URL (direct customers): https://api.vatpulse.workers.dev · OpenAPI: 3.1 / 3.0 · Interactive: /docs/reference
Quick start
- Subscribe to the free plan (100 validations/month) on RapidAPI and copy your
X-RapidAPI-Key. - Validate:
curl -X POST https://vatpulse1.p.rapidapi.com/validate \
-H "X-RapidAPI-Key: $RAPIDAPI_KEY" \
-H "X-RapidAPI-Host: vatpulse1.p.rapidapi.com" \
-H "Content-Type: application/json" \
-d '{"vat": "IE6388047V", "iban": "DE89 3704 0044 0532 0130 00"}'
JavaScript
const res = await fetch("https://vatpulse1.p.rapidapi.com/validate", {
method: "POST",
headers: {
"X-RapidAPI-Key": process.env.RAPIDAPI_KEY,
"X-RapidAPI-Host": "vatpulse1.p.rapidapi.com",
"Content-Type": "application/json",
},
body: JSON.stringify({ vat: "NL004495445B01" }),
});
const { vat } = await res.json();
if (vat.valid === true) { /* registered */ }
else if (vat.valid === false) { /* not registered or malformed: vat.error.code */ }
else { /* unknown right now (upstream down): retry later */ }
Python
import requests
r = requests.post(
"https://vatpulse1.p.rapidapi.com/validate",
headers={"X-RapidAPI-Key": RAPIDAPI_KEY, "X-RapidAPI-Host": "vatpulse1.p.rapidapi.com"},
json={"iban": "FR1420041010050500013M02606"},
timeout=15,
)
print(r.json()["iban"])
Authentication
RapidAPI (default): call https://vatpulse1.p.rapidapi.com with your X-RapidAPI-Key and X-RapidAPI-Host: vatpulse1.p.rapidapi.com headers. RapidAPI handles keys, plans and billing.
Direct keys: direct customers receive a key (vk_live_…) from us and call https://api.vatpulse.workers.dev with it in the X-API-Key header (Authorization: Bearer <key> also works). Self-serve signup on this site is closed; use RapidAPI or ask via the RapidAPI listing.
POST /validate
JSON body with vat, iban, or both (strings). Spaces, dots and dashes are ignored. VAT numbers need their 2-letter prefix; Greece is EL (we also accept GR), Northern Ireland is XI (checked via VIES). UK GB numbers via HMRC are coming soon (built, not yet enabled); until then they return service_unavailable and are not billed.
HTTP 200 is returned whenever at least one component produced a definitive answer. If nothing could be answered, the status reflects the error (400 bad input, 503 upstream down with nothing cached).
Response fields
vat
| Field | Description |
|---|---|
valid | true registered, false not registered or malformed, null unknown (see error). |
vat_number | Normalized number with prefix. |
country_code / country_name | ISO 3166 code (GR for EL, GB for XI). |
name / address | Registered name/address when the member state discloses them (e.g. DE and ES do not via VIES); otherwise null. |
source | vies, hmrc, or syntax (rejected locally by format check). |
cached / stale | cached: served from cache. stale: last-known-good copy served because the upstream is down. |
checked_at | When VIES/HMRC confirmed this answer. |
consultation_number | VIES consultation reference when the deployment is configured with a requester VAT number. |
error / warning | {code, message} or null. warning is set when a stale result is served. |
iban
| Field | Description |
|---|---|
valid | Checksum, length and structure all pass. |
iban / iban_formatted | Electronic and print formats. |
country_code, check_digits, bban, bank_code, branch_code, account_number | Parsed components (per SWIFT IBAN registry positions). |
sepa | Country is in the SEPA scheme. |
bank | {name, bic} from the bundled registry, or null if the bank code is not covered. |
An IBAN check confirms the number is well-formed. It cannot confirm that the account exists or is open.
Error codes
| Code | HTTP | Meaning |
|---|---|---|
invalid_request | 400 | Body not JSON, or neither vat nor iban given. |
invalid_format | 400* | Doesn't match the country's VAT/IBAN structure. |
invalid_country | 400 | Unknown or unsupported country prefix. |
invalid_length | 400* | IBAN length wrong for its country. |
invalid_checksum | 200 | IBAN mod-97 check failed (valid:false). |
member_state_unavailable | 503 | That country's VAT system is down (VIES MS_UNAVAILABLE/TIMEOUT) and nothing is cached. |
service_unavailable | 503 | VIES/HMRC unreachable or erroring, nothing cached. |
upstream_rate_limited | 503 | VIES/HMRC is throttling. |
unauthorized / forbidden | 401 / 403 | Missing/invalid key, or revoked key. |
rate_limited | 429 | Per-minute limit exceeded; see Retry-After. |
quota_exceeded | 429 | Monthly quota used up. Cached answers are still served. |
* When the component is answered as valid:false the HTTP status is 200; 4xx is used when no component could be answered.
Caching & outages
- Valid VAT results are cached for 24h;
valid:falseresults for 1h (so newly registered numbers show up quickly). - Every successful answer is also kept as a last-known-good copy for 30 days. If VIES/HMRC or the member state is down, you get that copy with
stale:true, its originalchecked_at, and awarning. - If there is no copy, you get an explicit 503 (
member_state_unavailableorservice_unavailable) withRetry-After, never a falsevalid:false. - IBAN results are computed offline and always available; repeat checks within 24h are free cache hits. We never store the IBAN itself, only a keyed hash (HMAC-SHA256) used as a 24h cache marker. See Privacy.
Billing & quotas
| Plan | Price | Validations / month | Requests / minute |
|---|---|---|---|
| Free | $0 | 100 | 10 |
| Basic | $19 | 2,000 | 60 |
| Pro | $49 | 10,000 | 180 |
You pay only for successful validations: a request counts once if at least one component produced a fresh definitive result (VIES/HMRC answered, or the IBAN checksum ran). Free: cache hits, stale fallbacks, input rejected by format/length checks, upstream errors, auth and rate-limit errors. The response field billable tells you. On RapidAPI, usage is reported to RapidAPI as a custom Validations quota (header X-RapidAPI-Billing: Validations=1|0) and your balance is in the RapidAPI dashboard; direct keys get X-Quota-Limit, X-Quota-Remaining and X-Quota-Reset headers. Quotas reset on the 1st of each month (UTC). The per-minute limit applies to all requests.
GET /usage
curl https://vatpulse1.p.rapidapi.com/usage -H "X-RapidAPI-Key: $RAPIDAPI_KEY" -H "X-RapidAPI-Host: vatpulse1.p.rapidapi.com"
{
"plan": "free", "monthly_quota": 100, "used": 12, "remaining": 88,
"period_start": "2026-10-01T00:00:00.000Z", "reset_at": "2026-11-01T00:00:00.000Z",
"rate_limit_per_minute": 10, "requests_this_month": 31
}
GET /status
Public. Live VIES availability per member state (cached 60s). Handy before batch jobs.
Coverage
VAT
| Prefix | Country | Example | Source |
|---|---|---|---|
AT | Austria | ATU12345678 | VIES |
BE | Belgium | BE0123456789 | VIES |
BG | Bulgaria | BG123456789 | VIES |
CY | Cyprus | CY12345678X | VIES |
CZ | Czechia | CZ12345678 | VIES |
DE | Germany | DE123456789 | VIES |
DK | Denmark | DK12345678 | VIES |
EE | Estonia | EE123456789 | VIES |
EL | Greece | EL123456789 | VIES |
ES | Spain | ESX1234567X | VIES |
FI | Finland | FI12345678 | VIES |
FR | France | FRXX123456789 | VIES |
HR | Croatia | HR12345678901 | VIES |
HU | Hungary | HU12345678 | VIES |
IE | Ireland | IE1234567X | VIES |
IT | Italy | IT12345678901 | VIES |
LT | Lithuania | LT123456789 | VIES |
LU | Luxembourg | LU12345678 | VIES |
LV | Latvia | LV12345678901 | VIES |
MT | Malta | MT12345678 | VIES |
NL | Netherlands | NL123456789B01 | VIES |
PL | Poland | PL1234567890 | VIES |
PT | Portugal | PT123456789 | VIES |
RO | Romania | RO1234567890 | VIES |
SE | Sweden | SE123456789001 | VIES |
SI | Slovenia | SI12345678 | VIES |
SK | Slovakia | SK1234567890 | VIES |
XI | Northern Ireland | XI123456789 | VIES |
GB | United Kingdom | GB123456789 | HMRC (coming soon; currently returns service_unavailable) |
IBAN
Checksum, length and structure validation for all 127 countries in the SWIFT IBAN registry (plus a few partial adopters).
Bank name / BIC lookup
Derived from openly published national bank directories (Deutsche Bundesbank, OeNB, NBB, Betaalvereniging, Banco de España, Banca d'Italia, SIX, NBP and others) via the MIT-licensed schwifty registry. Countries marked "major banks only" have curated lists rather than full official directories. Lookups are by bank code (and for some countries bank+branch); bank is null when not covered.
| Country | Bank codes | Source type |
|---|---|---|
AD | 6 | curated list (major banks only) |
AE | 56 | curated list (major banks only) |
AT | 864 | official national directory |
BA | 25 | official national directory |
BE | 771 | official national directory |
BG | 24 | curated list (major banks only) |
CH | 1,065 | official national directory |
CR | 24 | curated list (major banks only) |
CY | 7 | curated list (major banks only) |
CZ | 34 | official national directory |
DE | 3,503 | official national directory |
DK | 6,479 | curated list (major banks only) |
EE | 16 | official national directory |
ES | 384 | official national directory |
FI | 643 | official national directory |
FR | 215 | curated list (major banks only) |
GB | 39 | curated list (major banks only) |
GE | 20 | official national directory |
GR | 22 | curated list (major banks only) |
HR | 21 | official national directory |
HU | 179 | official national directory |
IE | 28 | curated list (major banks only) |
IL | 1 | curated list (major banks only) |
IS | 4 | curated list (major banks only) |
IT | 453 | official national directory |
KZ | 49 | official national directory |
LI | 19 | official national directory |
LT | 287 | official national directory |
LU | 118 | curated list (major banks only) |
LV | 25 | official national directory |
MC | 1 | curated list (major banks only) |
MD | 18 | official national directory |
ME | 12 | curated list (major banks only) |
NL | 86 | official national directory |
NO | 2,297 | official national directory |
PL | 2,999 | official national directory |
PT | 77 | curated list (major banks only) |
RO | 47 | official national directory |
RS | 26 | official national directory |
SE | 36 | official national directory |
SI | 829 | official national directory |
SK | 37 | official national directory |
TR | 48 | curated list (major banks only) |