For developers · REST and MCP

VIES API (EU VAT)
validate a VAT number, no API key

Check an EU VAT number in the VIES system (European Commission) with a single GET that returns clean JSON. You get the validity flag, the trader's name and address (when the member state discloses them) and a timestamp of the check. No API key, no sign-up, no daily request limit. It is a convenience layer over the VIES service (SOAP) that handles the XML envelopes for you.

One GET, one JSON

The endpoint is public, the method is GET, and the ?format=json parameter returns machine-readable data (without it you get an HTML page for humans). The path is /vies/{country}/{number}country is a two-letter EU country code (e.g. PL, DE), number is the VAT number without the country prefix:

curl "https://skanfirmy.pl/vies/PL/5260250995?format=json"

You get the validity of the number, the trader's name and address as VIES returns them, and a timestamp of the request (proof of the check):

{
  "countryCode": "PL",
  "vatNumber": "5260250995",
  "valid": true,
  "name": "ORANGE POLSKA SPÓŁKA AKCYJNA",
  "address": "ALEJE JEROZOLIMSKIE 160\n02-326 WARSZAWA",
  "requestDate": "2026-08-25T12:57:10.319Z",
  "checkedAt": "2026-08-25"
}

The valid field is the only authoritative answer to "is this EU VAT number valid". VIES returns name and address only when the member state discloses them — some states do not, in which case they can be empty.

No API key, no sign-up, no limit

The endpoint works right away: no account to create, no API key to generate, no daily request limit to watch. That is a deliberate difference from commercial VIES wrappers: the goal is EU-VAT validation you can wire up in a minute, including from an AI agent. The service is maintained free of charge; for heavy automated traffic we only ask for common sense (single lookups triggered by users, not bulk scraping).

Instead of VIES SOAP

The official service is the European Commission's VIES — SOAP with a checkVat operation, XML envelopes and a response you have to parse yourself. It works, but wiring it up can take an afternoon. Our endpoint runs that whole call server-side and returns ready JSON, so on your side it stays a single GET.

What /vies/{country}/{number} returns:

FieldMeaning
validBoolean — the only authoritative answer to whether the EU VAT number is valid in VIES at the moment of the check
nameTrader name as VIES returns it (may be empty if the member state does not disclose it)
addressTrader address as VIES returns it (may be empty or withheld in some member states)
countryCodeTwo-letter EU country code from the request
vatNumberVAT number without the country prefix
requestDateVIES timestamp — proof of when the check was made
checkedAtDate of the check

A number from another member state works the same way — e.g. a German number is checked with GET /vies/DE/811128135?format=json. The country prefix (DE, PL) goes in the path as {country} and the number without the prefix as {number}.

In Python

With the requests library it is a few lines — check valid right away:

import requests

def validate_eu_vat(country: str, number: str) -> dict:
    r = requests.get(f"https://skanfirmy.pl/vies/{country}/{number}?format=json", timeout=10)
    r.raise_for_status()
    data = r.json()
    if not data["valid"]:
        raise ValueError(f"EU VAT number {country}{number} is not valid in VIES")
    return data

d = validate_eu_vat("PL", "5260250995")
print(d["name"])
# ORANGE POLSKA SPÓŁKA AKCYJNA

A malformed number or a non-EU country returns 400. It is worth handling both that error and the valid: false case instead of assuming every number is valid.

In JavaScript

const r = await fetch("https://skanfirmy.pl/vies/PL/5260250995?format=json");
if (r.ok) {
  const d = await r.json();
  console.log(d.valid, d.name);
}

In PHP

$ch = curl_init("https://skanfirmy.pl/vies/PL/5260250995?format=json");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$d = json_decode(curl_exec($ch), true);
echo $d["valid"] ? $d["name"] : "number not valid";

National VAT and register data, from one NIP

VIES answers the question about an EU VAT number. If you are checking a Polish company and need its national VAT status (VAT register / White List), a KRS entry and the REGON number, use /nip/{nip}?format=json — it combines those sources in one response. The other endpoints (all GET → JSON, no key):

  • /vies/{country}/{number} — EU VAT number validation (VIES, European Commission)
  • /nip/{nip} — VAT status + White List + KRS + REGON
  • /nips/{list} — several NIPs at once (comma-separated)
  • /regon/{nip} — data from the REGON register (GUS)

For AI agents, at https://skanfirmy.pl/mcp there is a Model Context Protocol (MCP) server with a tool for EU VAT validation (and several others for NIP, KRS and REGON), also with no key. A model-readable map of the endpoints is in llms.txt. For a lookup in the UI, use the VIES (EU VAT) tool.

The public endpoint vs a typical paid VIES API

Most commercial REST wrappers over VIES run on a freemium model — an account, an API key and a daily request limit on the free tier. This endpoint is public and free, and beyond valid alone it also returns the name, address and a dated proof of the check. The differences in short:

Typical paid VIES APIskanfirmy.pl /vies
API keyrequirednot needed
Registration / accountyesno
Free-tier limitusually yesno hard limit (please be reasonable)
Response formatREST/JSONREST/JSON
MCP server for AI agentsusually noneyes
Returnsusually valid alonevalid + name + address + date of the check
Modelfreemium / subscriptionfree

This is not the official VIES API — the data comes from the same source (the European Commission's VIES system), just exposed with a single GET request.

Where the data comes from, and what this is not

The data comes straight from the VIES system run by the European Commission. This is an independent tool; it is not the official VIES API and is not affiliated with it — it only exposes VIES data in a more convenient form. VIES returns the name and address only when the member state discloses them, and the valid flag reflects the state at the moment in the requestDate field — the status can change later.

Frequently asked questions

Do I need an API key or to sign up?

No. The /vies/{country}/{number} endpoint is public — it returns JSON once you add ?format=json, with no API key, no account and no daily request limit.

How do I validate an EU VAT number in JSON?

Send a GET to https://skanfirmy.pl/vies/{COUNTRY}/{NUMBER}?format=json, where COUNTRY is a two-letter EU country code (e.g. DE, PL) and NUMBER is the VAT number without the country prefix. The response contains the valid field and — when the member state discloses them — the trader's name and address.

How is this different from the VIES (SOAP) service?

The official VIES service is SOAP with a checkVat operation, XML envelopes and a response you have to parse yourself. Our endpoint runs that call server-side and returns ready JSON, so on your side it stays a single GET request.

Why are the name and address sometimes empty?

VIES returns the name and address only when the member state discloses them — some states do not, in which case the name and address fields are empty. That is a limitation on the VIES side, not in our layer; the authoritative answer about the number's validity remains the valid field.

Is it free to use?

Yes. The endpoint is free and requires no registration. The data comes straight from the VIES system run by the European Commission, and the valid flag reflects the state at the moment in the requestDate field.