# vatcheckapi documentation > vatcheckapi validates VAT numbers and looks up their registration details over a simple JSON REST API. Authenticate every request with your API key via the `apikey` query parameter or request header. Base URL: https://api.vatcheckapi.com OpenAPI specification: https://vatcheckapi.com/docs/openapi.yaml --- Source: https://vatcheckapi.com/docs # Introduction vatcheckapi.com is a JSON REST API that validates VAT numbers — format and checksum — and looks up their registration details from the official registries, for all [supported countries](https://vatcheckapi.com/docs/check#supported-countries). All endpoints are served over HTTPS from `https://api.vatcheckapi.com` and return JSON. ## Your first request Register a free API key at the [developer portal](https://app.vatcheckapi.com/register), then check a VAT number: ```bash curl "https://api.vatcheckapi.com/v2/check?vat_number=LU26375245" \ -H "apikey: YOUR-APIKEY" ``` The [Validate VAT Number](https://vatcheckapi.com/docs/check) page describes the parameters and the response format in detail. ## Official libraries Building with an AI assistant? The full API is available as a machine-readable [OpenAPI 3.1 specification](https://vatcheckapi.com/docs/openapi.yaml), and the documentation is published as [llms.txt](https://vatcheckapi.com/docs/llms.txt) / [llms-full.txt](https://vatcheckapi.com/docs/llms-full.txt). There is also a hosted [MCP server](https://vatcheckapi.com/docs/mcp) at `https://api.vatcheckapi.com/mcp` that AI agents can connect to directly. | Language | Code | Repository | |-----------------------|----------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------| | Python | — | [https://pypi.org/project/vatcheckapi/](https://pypi.org/project/vatcheckapi/) | | PHP | [https://github.com/everapihq/vatcheckapi-php](https://github.com/everapihq/vatcheckapi-php) | [https://packagist.org/packages/vatcheckapi/vatcheckapi-php](https://packagist.org/packages/vatcheckapi/vatcheckapi-php) | | JavaScript ES6 module | — | [https://www.npmjs.com/package/vatcheckapi-js](https://www.npmjs.com/package/vatcheckapi-js) | | Ruby | — | [https://rubygems.org/gems/vatcheckapi](https://rubygems.org/gems/vatcheckapi) | | C# | — | [https://www.nuget.org/packages/VatCheckApi/](https://www.nuget.org/packages/VatCheckApi/) | | Rust | — | [https://crates.io/crates/vatcheckapi](https://crates.io/crates/vatcheckapi) | | Go | [https://github.com/everapihq/vatcheckapi-go](https://github.com/everapihq/vatcheckapi-go) | [https://pkg.go.dev/github.com/everapihq/vatcheckapi-go](https://pkg.go.dev/github.com/everapihq/vatcheckapi-go) | | R | [https://github.com/everapihq/vatcheckapi-r](https://github.com/everapihq/vatcheckapi-r) | [https://cran.r-project.org/web/packages/vatcheckapi/index.html](https://cran.r-project.org/web/packages/vatcheckapi/index.html) | ## Authentication & API key Information vatcheckapi.com uses API keys to allow access to the API. You can register a new API key at our [developer portal](https://app.vatcheckapi.com/register). While our free plan only allows one API key at a time, our paid plans offer multiple API keys. By using separate keys for different use cases you can track individual usage and make key rotations affect only certain parts of your application. ## Authentication methods To authorize, you can use the following ways: ### GET query parameter You can pass your API key along with every request by adding it as a query parameter `apikey` This method could expose your API key in access logs and such. Sending the API key via a header parameter as specified below circumvents this problem. ```bash curl "https://api.vatcheckapi.com/v2/check?vat_number=LU26375245&apikey=YOUR-APIKEY" ``` ```javascript var oReq = new XMLHttpRequest(); oReq.addEventListener("load", function () { console.log(this.responseText); }); oReq.open("GET", "https://api.vatcheckapi.com/v2/check?vat_number=LU26375245&apikey=YOUR-APIKEY"); oReq.send(); ``` ```php $url = "https://api.vatcheckapi.com/v2/check?vat_number=LU26375245&apikey=YOUR-APIKEY"; $curl = curl_init($url); $resp = curl_exec($curl); var_dump($resp); ```` ```python import requests from requests.structures import CaseInsensitiveDict url = "https://api.vatcheckapi.com/v2/check?vat_number=LU26375245&apikey=YOUR-APIKEY" resp = requests.get(url) print(resp.status_code) ```` ### HTTP Header You can set a request header with the name `apikey` ```bash curl "https://api.vatcheckapi.com/v2/check?vat_number=LU26375245" \ -H "apikey: YOUR-APIKEY" ``` ```javascript var oReq = new XMLHttpRequest(); oReq.addEventListener("load", function () { console.log(this.responseText); }); oReq.open("GET", "https://api.vatcheckapi.com/v2/check?vat_number=LU26375245"); oReq.setRequestHeader("apikey", "YOUR-APIKEY"); oReq.send(); ``` ```php $url = "https://api.vatcheckapi.com/v2/check?vat_number=LU26375245"; $curl = curl_init($url); $headers = array( "apikey: YOUR-APIKEY", ); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $resp = curl_exec($curl); var_dump($resp); ```` ```python import requests from requests.structures import CaseInsensitiveDict url = "https://api.vatcheckapi.com/v2/check?vat_number=LU26375245" headers = CaseInsensitiveDict() headers["apikey"] = "YOUR-APIKEY" resp = requests.get(url, headers=headers) print(resp.status_code) ```` ## Rate limit and quotas You can use a certain number of requests per month, defined by your plan. Once you go over this quota, the API returns a `429` HTTP status code, and you either need to upgrade your plan or wait until the end of the month. We enforce a minute rate limit for specific plans. If you exceed this, the API returns a `429` HTTP status code. You then have to wait until the end of the minute to make more requests. Only successful calls count against your quota. Any error on our side or validation errors (e.g., wrong parameter) will NOT count against your quota or rate limit. ### Response Headers We attach specific headers to tell you your current monthly/minute quota and how much you have remaining in the period. ```HTTP X-RateLimit-Limit-Quota-Minute: 10 X-RateLimit-Limit-Quota-Month: 300 X-RateLimit-Remaining-Quota-Minute: 5 X-RateLimit-Remaining-Quota-Month: 199 ``` The monthly headers (`X-RateLimit-Limit-Quota-Month` / `X-RateLimit-Remaining-Quota-Month`) are attached on every plan. The minute headers (`X-RateLimit-Limit-Quota-Minute` / `X-RateLimit-Remaining-Quota-Minute`) are only sent on plans with a minute rate limit (e.g. the free plan); paid plans do not receive them. You can always monitor your remaining quota with the [Status endpoint](https://vatcheckapi.com/docs/status) — it works on every plan and does not count against your quota. ## Sandbox API keys Sandbox API keys let you develop and test your integration without consuming your quota. On plans that allow more than one API key, you can create a sandbox key on the API-keys page of the [dashboard](https://app.vatcheckapi.com/). Sandbox keys start with `vat_dev_`, live keys with `vat_live_`. Requests made with a sandbox key behave as follows: - Calls to `/v2/check` do not query the official registries. They return fixed fake data: every VAT number with a valid format and checksum comes back as registered to `GOOGLE IRELAND LIMITED`, `3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4`. - The Austrian VAT number `ATU00000006` is the designated negative test case: it comes back as not registered (`is_registered: false`, with `name` and `address` set to `null`). - Sandbox calls cost nothing — the `X-Cost` response header is always `0` and nothing counts against your quota. ## API versions The current API version is v2, which all endpoints in this documentation belong to. The legacy endpoint `GET /v1/validate/{vatId}` remains available for existing integrations but returns a different response format; new integrations should use [`/v2/check`](https://vatcheckapi.com/docs/check) instead. --- Source: https://vatcheckapi.com/docs/check # Validate VAT Number Validates a VAT number from any of the [supported countries](#supported-countries) and returns its validity and company information **Request Method:** `GET` **Request URL:** `https://api.vatcheckapi.com/v2/check?vat_number=[[ vat_number ]]` ## Request Parameters | Parameter | Type | Mandatory | Description | | -------------- | -------- | ---------- | ---------------------------------------------------------------------------------------------------------------------- | | `apikey` | _string_ | ️ | Your API Key | | `vat_number` | _string_ | ️ | The VAT number to check. Include the two-letter country prefix (e.g. `LU26375245`), or omit it and pass `country_code` separately | | `country_code` | _string_ | | An ISO Alpha 2 Country Code for the VAT number (e.g. `LU`). Required if the `vat_number` has no country prefix | ## Sample Request ```bash curl "https://api.vatcheckapi.com/v2/check?vat_number=LU26375245" \ -H "apikey: YOUR-APIKEY" ``` ## Sample Response ```json { "country_code": "LU", "vat_number": "26375245", "format_valid": true, "checksum_valid": true, "registration_info": { "is_registered": true, "name": "AMAZON EUROPE CORE S.A R.L.", "address": "38, AVENUE JOHN F. KENNEDY\nL-1855 LUXEMBOURG", "address_parts": null, "checked_at": "2023-01-11T12:30:28.000000Z" }, "registration_info_history": [] } ``` ## Supported Countries The API validates VAT numbers from the following 29 countries: the 27 EU member states, the United Kingdom, and Northern Ireland (which uses the `XI` prefix for goods trade with the EU). Note that Greece uses the VAT-specific country code `EL`. | Code | Country | Code | Country | | ---- | -------------- | ---- | ---------------- | | `AT` | Austria | `IT` | Italy | | `BE` | Belgium | `LT` | Lithuania | | `BG` | Bulgaria | `LU` | Luxembourg | | `CY` | Cyprus | `LV` | Latvia | | `CZ` | Czechia | `MT` | Malta | | `DE` | Germany | `NL` | Netherlands | | `DK` | Denmark | `PL` | Poland | | `EE` | Estonia | `PT` | Portugal | | `EL` | Greece | `RO` | Romania | | `ES` | Spain | `SE` | Sweden | | `FI` | Finland | `SI` | Slovenia | | `FR` | France | `SK` | Slovakia | | `GB` | United Kingdom | `XI` | Northern Ireland | | `HR` | Croatia | | | | `HU` | Hungary | | | | `IE` | Ireland | | | Requests with any other country code fail with a `422` [validation error](https://vatcheckapi.com/docs/status-codes#validation-errors). --- Source: https://vatcheckapi.com/docs/mcp # MCP Server vatcheckapi ships a hosted [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server, so AI agents and assistants can call the API as native tools — no SDK or glue code required. ``` https://api.vatcheckapi.com/mcp ``` The endpoint speaks the streamable HTTP transport. Listing the available tools works without authentication; executing a tool requires your API key, sent as the `apikey` header. You can [get a free API key here](https://app.vatcheckapi.com/register). ## Connect Using Claude Code: ```bash claude mcp add --transport http vatcheckapi https://api.vatcheckapi.com/mcp --header "apikey: YOUR_API_KEY" ``` Or add the server to any MCP-capable client (Claude Desktop, Cursor, VS Code, ...): ```json { "mcpServers": { "vatcheckapi": { "url": "https://api.vatcheckapi.com/mcp", "headers": { "apikey": "YOUR_API_KEY" } } } } ``` ## Available tools The tools are generated from the same [OpenAPI specification](https://vatcheckapi.com/docs/openapi.yaml) that describes the REST API, so they always match the documented endpoints, parameters and responses. | Tool | Endpoint | Description | |---|---|---| | `check` | `GET /v2/check` | Check a VAT number | | `getStatus` | `GET /v2/status` | Account quota status | ## Quotas and errors Tool calls are metered exactly like REST requests: they consume your plan quota and return the same status codes and error responses (`401`, `422`, `429`, ...). If a call fails, the tool result contains the API's error message including hints on how to proceed. --- Source: https://vatcheckapi.com/docs/status # Status Endpoint Returns your current quota Requests to this endpoint do not count against your quota or rate limit **Request Method:** `GET` **Request URL:** `https://api.vatcheckapi.com/v2/status` ## Request Parameters | Parameter | Type | Mandatory | Description | | -------------- | ---------- | ---------- | --------------------------------------------------------------- | | `apikey` | *string* | ️ | Your API Key | ## Sample Request ```bash curl "https://api.vatcheckapi.com/v2/status" \ -H "apikey: YOUR-APIKEY" ``` ## Sample Response ```json { "account_id": 313373133731337, "quotas": { "month": { "total": 300, "used": 71, "remaining": 229 }, "grace": { "total": 0, "used": 0, "remaining": 0 } } } ``` The `month` bucket reflects your plan's monthly request quota. The `grace` bucket is a temporary allowance we may grant your account (for example while a payment is being completed) so your integration keeps working; it is normally `0`, and while a grace quota is active your requests count against it instead of the monthly quota. --- Source: https://vatcheckapi.com/docs/status-codes # Request Status Codes For all requests, we will return an HTTP status code that indicates a success or the problem that has led to the failure. A successful request will be returned with status code `200` ## Error Response Body Error responses are JSON objects with the following fields: | Field | Presence | Description | | --------- | ---------- | -------------------------------------------------------------------------------------------- | | `message` | always | A human-readable description of the error | | `errors` | 422 only | An object mapping each invalid parameter to an array of validation messages | | `info` | 422 only | A sentence containing a deep link to the matching section of this page, e.g. `For more information, see documentation: https://vatcheckapi.com/docs/status-codes#_422`. Sent alongside `errors` on `422` responses raised by request validation (e.g. a missing `vat_number`); other errors omit it | | `error` | 401, 403, 404, 429 | An object with a stable machine-readable `code` (e.g. `invalid_api_key`, `quota_exceeded`) and the same human-readable `message` | | `actions` | 401, 403, 404, 429 | An object of suggested next steps as URLs, e.g. `upgrade` and `docs` | | `quota` | quota `429` only | The current quota state: `limit`, `used`, `remaining` and `resets_at` | ```json { "message": "Validation error", "errors": { "vat_number": [ "The vat number field is required." ] }, "info": "For more information, see documentation: https://vatcheckapi.com/docs/status-codes#_422" } ``` ## API Error Codes ### 401 Invalid authentication credentials ### 403 You are not allowed to use this endpoint, please [upgrade your plan](https://app.vatcheckapi.com/subscription). ### 404 A requested endpoint does not exist ### 422 Validation error, please check the list of validation errors: [here](#validation-errors) ### 429 You have hit your rate limit or your monthly limit. For more requests please [upgrade your plan](https://app.vatcheckapi.com/subscription). ### 500 Internal Server Error - let us know: support@vatcheckapi.com ### 503 The countries VAT validation service is currently not available. You can retry the request at any point to check again. ## Validation errors #### Missing vat_number The `vat_number` parameter is required #### Missing country_code The `country_code` parameter is required, if the given `vat_number` has no country code. #### Unsupported country_code The given `country_code` (or the country prefix of the `vat_number`) is not one of the [supported countries](https://vatcheckapi.com/docs/check#supported-countries). #### Invalid VAT number The given `vat_number` could not be validated. Unlike the parameter errors above, this response contains only a `message` ("Invalid VAT number.") and no `errors` object.