# EU VIES

> Confirm that an EU VAT number is genuinely registered, straight from the European Commission's VIES service - the official source, which passes every check live to the tax administration of the country that issued the number. Validate one number or a whole customer list, get the registered business name and address back where the country publishes them, compare a company's name and address with the register, and check the number's format offline before you ever contact VIES. Add your own VAT number once and every check comes back with the consultation number tax authorities accept as proof you verified a customer. A check that could not be made is never reported as an invalid number. No account or API key required.

App · Accounting & Finance · 7 actions. Web page: https://docs.lodol.com/docs/integrations/eu-vies

## Actions

### Check a company's name and address

Check a VAT number and, at the same time, ask the country whether the company name and address you hold match the ones on its register - the check that catches a number that is real but belongs to somebody else. Only some countries compare details; the rest confirm the number and compare nothing, which the answer says plainly rather than reporting as a mismatch. List the countries VIES covers to see which ones do. No account or API key required.

**Inputs**

- VAT number (`vat_number`, text, required): The VAT number to check, with its country code, like IE6388047V.
- Company name (`company_name`, text): Optional. The company name you hold, to compare with the register.
- Street (`street`, text): Optional. The street of the registered address, house number and all.
- Postal code (`postal_code`, text): Optional. The postal code of the registered address.
- City (`city`, text): Optional. The city of the registered address.
- Country (`country`, text): Optional. Only needed when the VAT number arrives without its country code in front - a spreadsheet column that keeps the two apart, say. Leave blank and the country the number starts with is used. One of: `AT` (Austria (AT)), `BE` (Belgium (BE)), `BG` (Bulgaria (BG)), `HR` (Croatia (HR)), `CY` (Cyprus (CY)), `CZ` (Czechia (CZ)), `DK` (Denmark (DK)), `EE` (Estonia (EE)), `FI` (Finland (FI)), `FR` (France (FR)), and 18 more.

**Outputs**

- `address` (text): The registered address, as the country publishes it. Empty for countries that do not publish addresses.
- `address_lines` (list): The same address split into its lines, for writing into address fields rather than into one box.
- `all_details_match` (true/false): True when every detail you gave matches the register, false when one does not, and empty when the country compared nothing. Branch on this rather than on the fields below.
- `checked_at` (text): When the check was made, e.g. 2026-09-03T19:34:45.496Z.
- `city_match` (text): The city: "matches", "does not match", or "not checked" when the country does not compare this detail.
- `company_name_match` (text): The company name: "matches", "does not match", or "not checked" when the country does not compare this detail.
- `consultation_number` (text): The consultation number VIES issues as proof of the check - what a tax authority asks for. Present only when your own VAT number is saved with this connection; empty otherwise.
- `country` (text): The country in full, e.g. Ireland.
- `country_code` (text): The country's VAT prefix, e.g. IE. Greece's is EL, not GR.
- `details_checked` (true/false): Whether the country compared anything at all. Most do not, and that is not a mismatch - check this before acting on the match fields.
- `name` (text): The business the number is registered to, as the country publishes it. Empty for countries that do not publish names, and for a number that is not registered.
- `number` (text): The number without its country code, e.g. 6388047V.
- `postal_code_match` (text): The postal code: "matches", "does not match", or "not checked" when the country does not compare this detail.
- `registered_city` (text): The city held on the register, when returned.
- `registered_name` (text): The company name held on the register, when the country returns it alongside the comparison.
- `registered_postal_code` (text): The postal code held on the register, when returned.
- `registered_street` (text): The street held on the register, when returned.
- `street_match` (text): The street: "matches", "does not match", or "not checked" when the country does not compare this detail.
- `summary` (text): The answer in one sentence, ready to put in an email or a log, e.g. "IE6388047V is registered to GOOGLE IRELAND LIMITED."
- `valid` (true/false): Whether the country's tax administration confirmed the number is registered. This is only ever the country's own answer: if VIES or the country could not be reached, the step stops with an error instead of reporting false.
- `vat_number` (text): The number in its one canonical spelling - country code, then number, no spaces, upper case (IE6388047V) - whatever was typed. Safe to save back to a customer record.

**Example output**

```json
{
  "address": null,
  "address_lines": [],
  "all_details_match": true,
  "checked_at": "2026-09-03T19:34:45.496Z",
  "city_match": "not checked",
  "company_name_match": "matches",
  "consultation_number": "WAPIAAAAaBoxRVnF",
  "country": "Spain",
  "country_code": "ES",
  "details_checked": true,
  "name": null,
  "number": "A12345674",
  "postal_code_match": "matches",
  "registered_city": null,
  "registered_name": "EJEMPLO SL",
  "registered_postal_code": "28013",
  "registered_street": "CALLE MAYOR 1",
  "street_match": "matches",
  "summary": "ESA12345674 is registered and every detail matches.",
  "valid": true,
  "vat_number": "ESA12345674"
}
```

### Check a VAT number's format

Check whether a VAT number has the shape its country publishes - nine digits for Germany, U and eight for Austria - without contacting VIES at all. Instant, and free of the rate limits a real check runs into, so it is the right thing to put behind a signup form or in front of a long list. It is a guide, not a verdict: only Validate a VAT number can say whether a number is actually registered. No account or API key required.

**Inputs**

- VAT number (`vat_number`, text, required): The VAT number to look at, with its country code, like IE6388047V.
- Country (`country`, text): Optional. Only needed when the VAT number arrives without its country code in front - a spreadsheet column that keeps the two apart, say. Leave blank and the country the number starts with is used. One of: `AT` (Austria (AT)), `BE` (Belgium (BE)), `BG` (Bulgaria (BG)), `HR` (Croatia (HR)), `CY` (Cyprus (CY)), `CZ` (Czechia (CZ)), `DK` (Denmark (DK)), `EE` (Estonia (EE)), `FI` (Finland (FI)), `FR` (France (FR)), and 18 more.

**Outputs**

- `country` (text): The country in full, e.g. Ireland.
- `country_code` (text): The country's VAT prefix, e.g. IE. Greece's is EL, not GR.
- `example` (text): A correctly shaped number for that country.
- `expected_format` (text): The shape this country's VAT numbers take, in words, e.g. "DE, then 9 digits".
- `input` (text): The number exactly as it was given.
- `number` (text): The number without its country code.
- `problem` (text): What looks wrong, in a sentence you can show someone filling in a form. Empty when nothing does.
- `summary` (text): The answer in one sentence, ready to put in an email or a log, e.g. "IE6388047V is registered to GOOGLE IRELAND LIMITED."
- `vat_number` (text): The number in its one canonical spelling - country code, then number, no spaces, upper case (IE6388047V) - whatever was typed. Safe to save back to a customer record.
- `well_formed` (true/false): Whether the number matches the shape its country publishes. Nothing was checked with VIES.

**Example output**

```json
{
  "country": "Germany",
  "country_code": "DE",
  "example": "DE123456789",
  "expected_format": "DE, then 9 digits",
  "input": "DE 123 456 789",
  "number": "123456789",
  "problem": null,
  "summary": "DE123456789 has the shape of a VAT number from Germany. Nothing has been checked with VIES.",
  "vat_number": "DE123456789",
  "well_formed": true
}
```

### Check which countries are answering

See whether VIES is up and which countries' VAT systems are answering right now. Countries go offline for maintenance regularly, and a number from one of them cannot be checked while it is - so a nightly run can look here first and wait rather than fill a customer list with rows it could not check. This is the one step that reports trouble as a value instead of failing, so a workflow can branch on it. No account or API key required.

**Inputs**

- Countries (`countries`, list): Optional. Report on only these countries. Leave blank for all 28. One or more of: `AT` (Austria (AT)), `BE` (Belgium (BE)), `BG` (Bulgaria (BG)), `HR` (Croatia (HR)), `CY` (Cyprus (CY)), `CZ` (Czechia (CZ)), `DK` (Denmark (DK)), `EE` (Estonia (EE)), `FI` (Finland (FI)), `FR` (France (FR)), and 18 more.

**Outputs**

- `all_available` (true/false): True when VIES is up and every country asked about is answering. The one field to branch on before a batch run.
- `available_count` (number): How many of them are answering.
- `countries` (list): One line per country.
- `summary` (text): The answer in one sentence, ready to put in an email or a log, e.g. "IE6388047V is registered to GOOGLE IRELAND LIMITED."
- `unavailable` (list): The countries that are not, named in full, ready to put in a message.
- `vies_online` (true/false): Whether VIES itself is answering.

**Example output**

```json
{
  "all_available": false,
  "available_count": 1,
  "countries": [
    {
      "availability": "Available",
      "available": true,
      "country": "Germany",
      "country_code": "DE"
    },
    {
      "availability": "Unavailable",
      "available": false,
      "country": "Italy",
      "country_code": "IT"
    }
  ],
  "summary": "VIES is up, but Italy is not answering. Numbers from that country cannot be checked right now.",
  "unavailable": [
    "Italy"
  ],
  "vies_online": true
}
```

### List the countries VIES covers

List every country whose VAT numbers can be checked - the 27 EU member states plus Northern Ireland - and which of them will also compare a company's name and address. Useful for filling a country picker in a form, and for knowing before you ask whether Check a company's name and address will actually compare anything. No account or API key required.

**Inputs**: None.

**Outputs**

- `company_detail_countries` (list): The countries that compare a company's name and address, named in full.
- `count` (number): How many countries VIES covers.
- `countries` (list): One line per country.
- `summary` (text): The answer in one sentence, ready to put in an email or a log, e.g. "IE6388047V is registered to GOOGLE IRELAND LIMITED."

**Example output**

```json
{
  "company_detail_countries": [
    "Spain"
  ],
  "count": 2,
  "countries": [
    {
      "checks_company_details": false,
      "country": "Germany",
      "country_code": "DE"
    },
    {
      "checks_company_details": true,
      "country": "Spain",
      "country_code": "ES"
    }
  ],
  "summary": "VIES covers 2 countries, of which Spain also compares a company's name and address."
}
```

### Simulate a validation result

Ask VIES's own test service for a chosen outcome - registered, not registered, the country's system down, VIES too busy - and see exactly what your workflow would get, including the message it would show. The way to build and prove the branch that handles a bad VAT number or an outage without waiting for one to happen. Nothing real is checked, and unlike every other step here this one hands a failure back as data instead of stopping. No account or API key required.

**Inputs**

- Outcome (`outcome`, text): Which answer VIES should come back with. A valid number by default. One of: `valid` (Valid - the number is registered), `not_registered` (Not registered - no such VAT number), `unusable_number` (Unusable number - VIES will not accept it), `requester_rejected` (Your own VAT number is rejected), `vies_unavailable` (VIES itself is unavailable), `country_unavailable` (The country's VAT system is unavailable), `country_timeout` (The country's VAT system times out), `number_blocked` (The country will not answer checks of this number), `workspace_blocked` (VIES has blocked this workspace), `too_busy` (VIES is too busy to check anything). Default: `valid`.
- Country (`country`, text): Optional. Which country the simulated answer should come from. It changes nothing but the country in the answer, which is useful when the branch you are testing reads it. One of: `AT` (Austria (AT)), `BE` (Belgium (BE)), `BG` (Bulgaria (BG)), `HR` (Croatia (HR)), `CY` (Cyprus (CY)), `CZ` (Czechia (CZ)), `DK` (Denmark (DK)), `EE` (Estonia (EE)), `FI` (Finland (FI)), `FR` (France (FR)), and 18 more.

**Outputs**

- `address` (text): The registered address, as the country publishes it. Empty for countries that do not publish addresses.
- `address_lines` (list): The same address split into its lines, for writing into address fields rather than into one box.
- `checked_at` (text): When the check was made, e.g. 2026-09-03T19:34:45.496Z.
- `consultation_number` (text): The consultation number VIES issues as proof of the check - what a tax authority asks for. Present only when your own VAT number is saved with this connection; empty otherwise.
- `country` (text): The country in full, e.g. Ireland.
- `country_code` (text): The country's VAT prefix, e.g. IE. Greece's is EL, not GR.
- `name` (text): The business the number is registered to, as the country publishes it. Empty for countries that do not publish names, and for a number that is not registered.
- `number` (text): The number without its country code, e.g. 6388047V.
- `outcome` (text): The outcome that was asked for.
- `outcome_label` (text): That outcome in words.
- `succeeded` (true/false): Whether VIES produced an answer. False for every outcome that stands for a problem.
- `summary` (text): The answer in one sentence, ready to put in an email or a log, e.g. "IE6388047V is registered to GOOGLE IRELAND LIMITED."
- `valid` (true/false): Whether the country's tax administration confirmed the number is registered. This is only ever the country's own answer: if VIES or the country could not be reached, the step stops with an error instead of reporting false.
- `vat_number` (text): The number in its one canonical spelling - country code, then number, no spaces, upper case (IE6388047V) - whatever was typed. Safe to save back to a customer record.
- `would_stop_the_step` (true/false): Whether a real check meeting this outcome would stop the workflow with an error rather than return a result.

**Example output**

```json
{
  "address": null,
  "address_lines": [],
  "checked_at": null,
  "consultation_number": null,
  "country": "Germany",
  "country_code": "DE",
  "name": null,
  "number": "301",
  "outcome": "country_unavailable",
  "outcome_label": "The country's VAT system is unavailable",
  "succeeded": false,
  "summary": "Germany: the VAT system is not responding. This says nothing about the VAT number - it was never checked. Try again shortly, or check which countries are answering first.",
  "valid": null,
  "vat_number": "DE301",
  "would_stop_the_step": true
}
```

### Validate a VAT number

Check an EU VAT number against the official register of the country that issued it, and get back whether it is registered, along with the business's name and address where that country publishes them. This is the check that lets you zero-rate a cross-border sale, so it never guesses: if VIES or the country cannot be reached, the step stops and says so rather than reporting the number as invalid. Paste the number as it is written on the invoice - IE6388047V, spaces and all. No account or API key required.

**Inputs**

- VAT number (`vat_number`, text, required): The VAT number to check, written the way it appears on an invoice: country code and all, like IE6388047V. Spaces, dots and dashes are ignored, and GR is understood for Greece.
- Country (`country`, text): Optional. Only needed when the VAT number arrives without its country code in front - a spreadsheet column that keeps the two apart, say. Leave blank and the country the number starts with is used. One of: `AT` (Austria (AT)), `BE` (Belgium (BE)), `BG` (Bulgaria (BG)), `HR` (Croatia (HR)), `CY` (Cyprus (CY)), `CZ` (Czechia (CZ)), `DK` (Denmark (DK)), `EE` (Estonia (EE)), `FI` (Finland (FI)), `FR` (France (FR)), and 18 more.

**Outputs**

- `address` (text): The registered address, as the country publishes it. Empty for countries that do not publish addresses.
- `address_lines` (list): The same address split into its lines, for writing into address fields rather than into one box.
- `checked_at` (text): When the check was made, e.g. 2026-09-03T19:34:45.496Z.
- `consultation_number` (text): The consultation number VIES issues as proof of the check - what a tax authority asks for. Present only when your own VAT number is saved with this connection; empty otherwise.
- `country` (text): The country in full, e.g. Ireland.
- `country_code` (text): The country's VAT prefix, e.g. IE. Greece's is EL, not GR.
- `name` (text): The business the number is registered to, as the country publishes it. Empty for countries that do not publish names, and for a number that is not registered.
- `number` (text): The number without its country code, e.g. 6388047V.
- `summary` (text): The answer in one sentence, ready to put in an email or a log, e.g. "IE6388047V is registered to GOOGLE IRELAND LIMITED."
- `valid` (true/false): Whether the country's tax administration confirmed the number is registered. This is only ever the country's own answer: if VIES or the country could not be reached, the step stops with an error instead of reporting false.
- `vat_number` (text): The number in its one canonical spelling - country code, then number, no spaces, upper case (IE6388047V) - whatever was typed. Safe to save back to a customer record.

**Example output**

```json
{
  "address": "3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4",
  "address_lines": [
    "3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4"
  ],
  "checked_at": "2026-09-03T19:34:45.496Z",
  "consultation_number": "WAPIAAAAaBoxRVnF",
  "country": "Ireland",
  "country_code": "IE",
  "name": "GOOGLE IRELAND LIMITED",
  "number": "6388047V",
  "summary": "IE6388047V is registered to GOOGLE IRELAND LIMITED.",
  "valid": true,
  "vat_number": "IE6388047V"
}
```

### Validate several VAT numbers

Check a whole list of VAT numbers in one step - a customer export, a signup batch, a quarterly re-check of everyone you invoice - and get one row per number saying valid, not registered, or not checked. A country going quiet halfway through costs that one row and not the run, and a row that could not be checked says so plainly rather than being counted as invalid. Up to 50 numbers at a time, checked at a pace VIES is happy to serve. No account or API key required.

**Inputs**

- VAT numbers (`vat_numbers`, list, required): The numbers to check, each written with its country code (IE6388047V). Point this at a list from an earlier step, or type one per line. Up to 50.
- Country (`country`, text): Optional. Only needed when the VAT number arrives without its country code in front - a spreadsheet column that keeps the two apart, say. Leave blank and the country the number starts with is used. One of: `AT` (Austria (AT)), `BE` (Belgium (BE)), `BG` (Bulgaria (BG)), `HR` (Croatia (HR)), `CY` (Cyprus (CY)), `CZ` (Czechia (CZ)), `DK` (Denmark (DK)), `EE` (Estonia (EE)), `FI` (Finland (FI)), `FR` (France (FR)), and 18 more.

**Outputs**

- `all_valid` (true/false): True only when every number came back registered.
- `count` (number): How many numbers were in the list.
- `not_checked_count` (number): How many could not be checked at all. Worth branching on: these are unknown, not invalid.
- `not_registered_count` (number): How many the country said are not registered.
- `results` (list): One row per number, in the order given.
- `summary` (text): The answer in one sentence, ready to put in an email or a log, e.g. "IE6388047V is registered to GOOGLE IRELAND LIMITED."
- `valid_count` (number): How many are registered.

**Example output**

```json
{
  "all_valid": false,
  "count": 2,
  "not_checked_count": 0,
  "not_registered_count": 1,
  "results": [
    {
      "address": "3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4",
      "address_lines": [
        "3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4"
      ],
      "checked_at": "2026-09-03T19:34:45.496Z",
      "consultation_number": "WAPIAAAAaBoxRVnF",
      "country": "Ireland",
      "country_code": "IE",
      "input": "IE 6388047V",
      "name": "GOOGLE IRELAND LIMITED",
      "note": null,
      "number": "6388047V",
      "status": "valid",
      "valid": true,
      "vat_number": "IE6388047V"
    },
    {
      "address": null,
      "address_lines": [],
      "checked_at": "2026-09-03T19:34:46.102Z",
      "consultation_number": "WAPIAAAAaBoxRVnG",
      "country": "Germany",
      "country_code": "DE",
      "input": "DE999999999",
      "name": null,
      "note": null,
      "number": "999999999",
      "status": "not_registered",
      "valid": false,
      "vat_number": "DE999999999"
    }
  ],
  "summary": "1 of 2 valid, 1 not registered.",
  "valid_count": 1
}
```
