# Tax ID & VAT Number Validator (65 countries, offline) (`viperthruster/global-tax-id-validator`) Actor

Validate business tax IDs and VAT numbers for 65 countries offline: EU VAT, UK VAT, US EIN, ABN, GSTIN, CNPJ, RFC and more. Checks format and check digits; personal numbers are masked.

- **URL**: https://apify.com/viperthruster/global-tax-id-validator.md
- **Developed by:** [David Rincon](https://apify.com/viperthruster) (community)
- **Categories:** Business, Developer tools, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 tax id checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Tax ID & VAT Number Validator (65 countries, offline)

Check whether business tax IDs and VAT numbers are well formed, in bulk, for 65 countries: EU VAT, UK VAT, Swiss UID, US EIN, Canadian BN, Australian ABN, Indian GSTIN, Brazilian CNPJ, Mexican RFC and many more. Everything runs locally, in seconds, without sending the numbers anywhere.

- **65 countries in one call:** the 27 EU member states and Northern Ireland (VAT), the UK, Switzerland, Norway, Iceland, the US, Canada, Australia, New Zealand, India, Japan, South Korea, Singapore, China, Turkey, Israel, Russia, Ukraine, South Africa, Egypt, Morocco, Thailand, Vietnam, Indonesia and 14 Latin American countries.
- **Format and check digits:** each number gets `valid` and, when it is not, the reason (`checksum`, `length`, `format` or `component`). A number that fits several countries' formats lists them all in `validIn`, so you know when to pass `country`.
- **Privacy by design:** numbers that can belong to a person (sole traders, personal tax numbers) are masked; only numbers that are certainly a company's come back in full. The input is never echoed or logged.

### Output example

```json
{
  "index": 0,
  "country": "BR",
  "idType": "CNPJ",
  "valid": true,
  "entityType": "company",
  "id": "16727230000197",
  "formatted": "16.727.230/0001-97",
  "masked": false,
  "checksumVerified": true,
  "validIn": ["BR"],
  "error": null
}
```

An EU VAT number such as `DE 143 454 214` comes back valid with `"country": "DE"`, `"idType": "VAT"` and a masked `"id": "********214"`, because in several countries a VAT number can be a sole trader's personal number. Use `index` to match each row with your input list.

A number without a prefix can fit several countries: `91-1144442` alone returns `"country": null` and `"validIn": ["CA", "EG", "US"]`; with `"country": "US"` it is checked as a US EIN only.

### Cost

You pay per ID checked: US$0.001 per ID, so **1,000 IDs = US$1.00**, plus US$0.00005 per run start. A typical run of 50 IDs costs about US$0.05.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `ids` | array of strings | required | Tax IDs or VAT numbers, with or without spaces, dots and dashes; up to 10000. |
| `country` | ISO 3166-1 alpha-2 code | not set | Checks every ID as that country's number. Leave it out to detect EU, UK and Swiss numbers from their prefix and try every other country. |
| `maxItems` | integer | 1000 | Stop after this many IDs, up to 10000. |

### Supported numbers

| Region | Countries and IDs |
|---|---|
| European Union | VAT number of all 27 member states (AT, BE, BG, CY, CZ, DE, DK, EE, ES, FI, FR, GR/EL, HR, HU, IE, IT, LT, LU, LV, MT, NL, PL, PT, RO, SE, SI, SK) and Northern Ireland (XI) |
| Rest of Europe | UK VAT, Swiss UID, Norwegian MVA, Icelandic VSK, Russian INN, Ukrainian EDRPOU, Turkish VKN |
| Americas | US EIN, Canadian BN, and in Latin America: NIT (CO, GT, SV), RUT (CL, UY), RFC (MX), CNPJ (BR), CUIT (AR), RUC (PE, EC, PY), RIF (VE), CPJ (CR), RNC (DO) |
| Asia and Oceania | Australian ABN, New Zealand IRD, Indian GSTIN, Japanese Corporate Number, Korean BRN, Singapore UEN, Chinese USCC, Israeli company number, Thai TIN, Vietnamese MST, Indonesian NPWP |
| Africa | South African TIN, Egyptian tax number, Moroccan ICE |

### When is a number shown in full?

Only when its structure says it belongs to a legal entity:

- **Always companies:**
  - Brazilian CNPJ;
  - Japanese Corporate Number;
  - Ukrainian EDRPOU;
  - Costa Rican CPJ;
  - Dominican RNC;
  - Israeli company number.
- **Companies by prefix or length:**
  - Peruvian RUC starting 20;
  - Ecuadorian RUC with third digit 6 or 9;
  - Venezuelan RIF starting J or G;
  - Russian INN of 10 digits;
  - Chinese USCC starting 91;
  - Indian GSTIN whose PAN type is C;
  - Colombian NIT from 800.000.000;
  - Chilean RUT from 50.000.000;
  - Mexican RFC of 12 characters;
  - Argentine CUIT starting 30, 33 or 34.

Everything else, including all VAT numbers, US EINs and Australian ABNs, is masked: those numbers can belong to sole traders.

### FAQ

**Does it check that the company exists or is VAT-registered?** No. It checks structure and check digits, which catches typos and made-up numbers. It does not query VIES or any tax authority, so it cannot tell whether a number is active.

**Why is `country` null for some valid numbers?** Plain digit strings can fit the format of several countries. `validIn` lists them; pass `country` to check the one you mean.

**Why is `checksumVerified` false for some Mexican RFCs?** Around 1.5% of RFCs in use carry homoclave digits that do not follow the published algorithm, so an RFC with a correct format and date is still reported as valid.

**Are my IDs stored?** The Actor stores only the results shown above, with personal numbers masked. It never logs IDs. Like every Apify run, your input is kept in your own run storage under your Apify data retention settings.

**Can AI agents use it?** Yes. Input is a plain list, limits are stated in the input descriptions, and a run takes a few seconds.

### Legal

Validation runs locally with public check-digit algorithms from the open-source python-stdnum library. No website, registry or government service is contacted, and no personal data is returned.

### Related Actors

- [LatAm Tax ID Validator](https://apify.com/viperthruster/latam-tax-id-validator): only need Colombia, Chile, Mexico, Brazil or Argentina? The same offline checks, focused on NIT, RUT, RFC, CNPJ and CUIT.

### En español

Valida identificadores tributarios y números de IVA de empresas de 65 países (IVA de la UE, VAT del Reino Unido, EIN, ABN, GSTIN, CNPJ, RFC y más) en lote, sin enviarlos a ningún servicio. Revisa formato y dígitos verificadores, no si el número está registrado. Los números que pueden ser de personas salen enmascarados.

### Changelog

- 0.1: first version.

# Actor input Schema

## `ids` (type: `array`):

Business tax IDs or VAT numbers, with or without spaces, dots and dashes; up to 10000. EU VAT numbers keep their country prefix (DE, FR, EL...). One result per ID, in the same order.

## `country` (type: `string`):

ISO 3166-1 alpha-2 code for all IDs, for example US, DE or IN. Recommended for numbers without a prefix, which can be valid in several countries. Omit it to detect from the VAT prefix or try every country. Supported: AR, AT, AU, BE, BG, BR, CA, CH, CL, CN, CO, CR, CY, CZ, DE, DK, DO, EC, EE, EG, ES, FI, FR, GB, GR, GT, HR, HU, ID, IE, IL, IN, IS, IT, JP, KR, LT, LU, LV, MA, MT, MX, NL, NO, NZ, PE, PL, PT, PY, RO, RU, SE, SG, SI, SK, SV, TH, TR, UA, US, UY, VE, VN, XI, ZA.

## `maxItems` (type: `integer`):

Stop after this many IDs, up to 10000. Keeps costs predictable.

## Actor input object example

```json
{
  "ids": [
    "DE 143 454 214",
    "GB 980 7806 84",
    "16.727.230/0001-97",
    "5-8356-7825-6246",
    "91110000600037341L"
  ],
  "maxItems": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "ids": [
        "DE 143 454 214",
        "GB 980 7806 84",
        "16.727.230/0001-97",
        "5-8356-7825-6246",
        "91110000600037341L"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("viperthruster/global-tax-id-validator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "ids": [
        "DE 143 454 214",
        "GB 980 7806 84",
        "16.727.230/0001-97",
        "5-8356-7825-6246",
        "91110000600037341L",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("viperthruster/global-tax-id-validator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "ids": [
    "DE 143 454 214",
    "GB 980 7806 84",
    "16.727.230/0001-97",
    "5-8356-7825-6246",
    "91110000600037341L"
  ]
}' |
apify call viperthruster/global-tax-id-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,viperthruster/global-tax-id-validator"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/kNjUGMXUUt50mbB1i/builds/Tlef3umdPQI4j3Nfx/openapi.json
