# EU VAT Number Validator (VIES) - Bulk Check, No Login (`cliqtomedia/vat-number-validator`) Actor

Bulk-validate EU VAT numbers against the official EU VIES service: valid or invalid, company name and address, consultation number. Member-state outages are reported as unavailable, never as invalid.

- **URL**: https://apify.com/cliqtomedia/vat-number-validator.md
- **Developed by:** [Cliqto Media](https://apify.com/cliqtomedia) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 vat number checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

Check a list of EU VAT numbers against the European Commission's VIES service and get one row per number: `valid` or `invalid`, the registered company name and address when the country shares them, and an honest status when a country's database is down. No login, no API key.

Paste up to 1,000 VAT numbers with their country prefix (for example `IE6388047V`) and click **Start**. A run of 6 numbers takes a few seconds and costs about $0.01.

![EU VAT Number Validator: a VAT list goes to VIES and comes back as valid, invalid or format_error per number, with company names](https://api.apify.com/v2/key-value-stores/hD24CAQnYH7Pokv0O/records/README-HERO-20261013.png)

### Table of contents

- [What it does](#what-it-does)
- [Quick start](#quick-start)
- [Input](#input)
- [Output](#output)
- [Pricing and limits](#pricing-and-limits)
- [Use cases](#use-cases)
- [API, export and integrations](#api-export-and-integrations)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Support](#support)

### What it does

[VIES](https://ec.europa.eu/taxation_customs/vies/) (VAT Information Exchange System) is the European Commission service that asks each EU country's tax database whether a VAT number is registered for cross-border trade. This Actor sends your numbers to the public [VIES REST API](https://ec.europa.eu/taxation_customs/vies/#/technical-information) one by one and saves the answer for each number in a dataset.

Before a number goes to VIES, the Actor cleans it (spaces, dots and dashes are removed, `GR` becomes `EL`) and checks the country's number format. Numbers with a wrong format are reported as `format_error` and are never sent.

The main difference from a simple VIES call: a VIES "no answer" is not turned into "invalid". When a country is busy or down (VIES codes `MS_MAX_CONCURRENT_REQ` and `MS_UNAVAILABLE`), the Actor waits and asks again. If the country still does not answer, the row gets `status: "service_unavailable"` and `valid: null`, not `valid: false`.

#### Good fit

- Check customer VAT numbers before you send an invoice without VAT (EU reverse charge).
- Clean a CRM or lead list: mark invalid numbers and fill in the registered company name.
- Re-check a supplier list and keep the VIES consultation number as proof of the check.

#### Not a fit / limits

- **UK (GB) numbers are not checked.** They left VIES in 2021, and the UK HMRC API needs registered API credentials. They get `status: "unsupported_country"`. Northern Ireland traders (`XI` prefix) are checked through VIES.
- Non-EU numbers (Norway, Switzerland, US and others) get `unsupported_country`.
- You cannot search by company name. VIES only checks a number.
- Some countries (for example Germany and Spain) do not share the name and address. Then `name` and `address` are `null` even when the number is valid.
- This is a one-time check of a list. There is no monitoring mode and no history.

### Quick start

1. Open the **Input** tab.
2. Add your numbers to **VAT numbers** (`vatNumbers`), one per line, with the two-letter country prefix. The form is prefilled with 5 public company numbers and one number with a wrong format (`DE12`).
3. Optional: add your own EU VAT number in `requesterVat` to get a consultation number for each valid check.
4. Click **Start**.
5. Open the **Output** tab. The **Results** view shows `status`, `valid`, `name` and `address` for each number.

Expected result for the prefill: 5 rows with `status: "valid"` (with company names, except the German number: Germany does not share names in VIES), and 1 row with `status: "format_error"` for `DE12`.

### Input

#### Input fields

| Field | Plain name | Type | Required | Default / prefill | Allowed values | Effect | Example | Recommendation |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `vatNumbers` | VAT numbers | array of strings | yes | no default; prefill of 6 numbers | 1–1,000 items, each with an EU country prefix | Numbers to check | `["IE6388047V", "de 143.454.214"]` | Keep the country prefix. Spaces, dots and dashes are fine. |
| `requesterVat` | Your own EU VAT number | string | no | empty | one EU VAT number with prefix | VIES returns a `consultationNumber` for each valid check | `"IE6388047V"` | Use it when you need proof that you checked a customer. |
| `retryUnavailable` | Retry unavailable countries | boolean | no | `true` | `true` / `false` | When a country is down, retry it up to 3 more times (waits of 15, 30 and 60 seconds) | `true` | Turn off only if you need the fastest possible answer. |

How the input is read:

- Each number is cleaned: upper case, spaces, dots, dashes and similar marks removed, full-width digits changed to normal digits. `GR` is changed to `EL` (the VIES code for Greece).
- Duplicates (after cleaning) are checked once. The result row shows how many extra copies there were in `duplicateInputs`.
- Empty input or more than 1,000 numbers: the run fails at once with a clear message and nothing is charged except the start fee.
- An invalid `requesterVat` format fails the run with a clear message. If VIES rejects a well-formed `requesterVat`, the Actor logs a warning and checks your numbers without it.

#### Interacting settings

| When | Input A | Input B | Effective behavior | Cost/result effect |
| --- | --- | --- | --- | --- |
| A country is down | `vatNumbers` | `retryUnavailable: true` | Numbers of that country are retried in up to 3 rounds (about 2 minutes extra) | Longer run; `service_unavailable` rows have no check fee |
| A country is down | `vatNumbers` | `retryUnavailable: false` | No retry rounds: numbers of that country are reported as `service_unavailable` right away (short busy retries of 2 and 5 seconds still happen) | Faster run |
| You need proof | `vatNumbers` | `requesterVat` | Each valid row gets a `consultationNumber` from VIES | Same price |

#### Input example

```json
{
  "vatNumbers": ["IE6388047V", "LU20260743", "NL810433941B01", "DE143454214", "ATU33803701", "DE12"],
  "retryUnavailable": true
}
```

Expected behavior: 5 numbers are sent to VIES, `DE12` is stopped by the format check.
Expected output: 6 rows; 5 `valid` with names where the country shares them, 1 `format_error`.
Cost: about $0.0103 (5 checks + 6 rows + start fee, see [Pricing](#pricing-and-limits)).

### Output

Each unique input number gives one dataset row. A run summary is saved in the key-value store as `RUN_SUMMARY`.

#### Output example

One `valid` row and one `format_error` row from a real run:

```json
[
  {
    "input": "IE6388047V",
    "countryCode": "IE",
    "vatNumber": "6388047V",
    "fullVatNumber": "IE6388047V",
    "status": "valid",
    "valid": true,
    "name": "GOOGLE IRELAND LIMITED",
    "address": "3RD FLOOR, GORDON HOUSE, BARROW STREET, DUBLIN 4",
    "requestDate": "2026-10-13T16:13:43.268Z",
    "consultationNumber": null,
    "errorCode": null,
    "errorMessage": null,
    "attempts": 1,
    "duplicateInputs": 0,
    "source": "EU VIES (European Commission)",
    "sourceUrl": "https://ec.europa.eu/taxation_customs/vies/",
    "checkedAt": "2026-10-13T16:13:43.314Z"
  },
  {
    "input": "DE12",
    "countryCode": "DE",
    "vatNumber": "12",
    "fullVatNumber": "DE12",
    "status": "format_error",
    "valid": null,
    "name": null,
    "address": null,
    "requestDate": null,
    "consultationNumber": null,
    "errorCode": "FORMAT_ERROR",
    "errorMessage": "Does not match the DE VAT number format.",
    "attempts": 0,
    "duplicateInputs": 0,
    "source": "EU VIES (European Commission)",
    "sourceUrl": "https://ec.europa.eu/taxation_customs/vies/",
    "checkedAt": "2026-10-13T16:13:42.494Z"
  }
]
```

`consultationNumber` is `null` here because the run had no `requesterVat`.

#### Output fields

| Field | Meaning | Type | Can be empty? | Example / enum |
| --- | --- | --- | --- | --- |
| `input` | The number exactly as you typed it | string | no | `de 143.454.214` |
| `countryCode` | VIES country code (`EL` = Greece, `XI` = Northern Ireland) | string | null when no prefix was found | `DE` |
| `vatNumber` | Number without prefix and separators | string | null when no prefix was found | `143454214` |
| `fullVatNumber` | Cleaned number with prefix | string | null when no prefix was found | `DE143454214` |
| `status` | Result of the check | string | no | `valid`, `invalid`, `service_unavailable`, `format_error`, `unsupported_country`, `not_checked`, `error` |
| `valid` | VIES verdict | boolean | null when VIES gave no verdict | `true` |
| `name` | Registered trader name | string | null when the country does not share it | `GOOGLE IRELAND LIMITED` |
| `address` | Registered address on one line | string | null when not shared | `3RD FLOOR, GORDON HOUSE, …` |
| `requestDate` | Time of the VIES answer | string (ISO 8601) | null when VIES was not asked or did not answer | `2026-10-13T16:13:43.268Z` |
| `consultationNumber` | Official VIES consultation number | string | null without `requesterVat` | `WAPI…` |
| `errorCode` | Why there is no verdict | string | null for `valid` / `invalid` | `MS_UNAVAILABLE`, `FORMAT_ERROR`, `UNSUPPORTED_COUNTRY`, `CHARGE_LIMIT` |
| `errorMessage` | The same in plain words | string | null for `valid` / `invalid` | `Does not match the DE VAT number format.` |
| `attempts` | Requests sent to VIES for this number | integer | no | `1` |
| `duplicateInputs` | Extra copies of this number in your input | integer | no | `0` |
| `source` / `sourceUrl` | Where the answer came from | string | no | `EU VIES (European Commission)` |
| `checkedAt` | When this row was made | string (ISO 8601) | no | `2026-10-13T16:13:43.314Z` |

What each `status` means:

| `status` | `valid` | Meaning | What to do |
| --- | --- | --- | --- |
| `valid` | `true` | VIES says the number is active for cross-border trade | Use it |
| `invalid` | `false` | VIES says the number is not registered or not active | Ask the customer to check the number |
| `service_unavailable` | `null` | The country's database did not answer, even after retries. **This is not invalid.** | Run these numbers again later |
| `format_error` | `null` | The number does not match the country's format; it was not sent to VIES | Fix the number |
| `unsupported_country` | `null` | Prefix is not an EU VIES country (for example `GB`, `NO`, `CH`) | Check it with that country's own service |
| `not_checked` | `null` | The run stopped before this number (time limit, your charge limit, or VIES stopped answering) | Run these numbers again |
| `error` | `null` | VIES returned an unexpected error for this number | Run it again later |

#### Output views and run summary

| Situation | Where to look | What you see |
| --- | --- | --- |
| Normal run | Dataset view **Results** | All rows with status, name, address, consultation number |
| Status and error codes | Dataset view **Status and errors** (all rows; sort or filter by `status` when exporting) | Input, status, error code, note, attempts |
| Every input has a wrong format | Dataset | Only `format_error` rows; run is SUCCEEDED |
| A country was down | Dataset + `RUN_SUMMARY` | `service_unavailable` rows; `unavailableCountries` lists the countries; run is SUCCEEDED |
| Run stopped early | `RUN_SUMMARY` | `status: "PARTIAL"` with `reason`: `CHARGE_LIMIT` or `DEADLINE_REACHED` (remaining rows are `not_checked`), `VIES_NOT_RESPONDING` (VIES gave no verdict for 2 minutes; remaining rows are `service_unavailable` or `not_checked`), `MEMBER_STATE_UNAVAILABLE` (some rows are `service_unavailable`) |
| Bad input or VIES fails many times in a row | Run status + `RUN_SUMMARY` | Run FAILED with a clear message; rows saved before the stop stay in the dataset |

`RUN_SUMMARY` contains `status`, `reason`, `message`, counts per status, `charged`, `duplicatesMerged`, `unavailableCountries`, request statistics and timing.

### Pricing and limits

#### Pricing unit

This Actor uses pay-per-event pricing. You pay for:

| Event | When | Price |
| --- | --- | --- |
| Actor start | Once per run (at the default 256 MB memory) | $0.0007 |
| VAT check | Each number that gets a VIES verdict (`valid` or `invalid`) | $0.0019 (Free plan), $0.0018 (Bronze), $0.0017 (Silver), $0.0016 (Gold and higher) |
| Result row | Each row saved to the dataset, for any status | $0.00002 |

Numbers with `service_unavailable`, `format_error`, `unsupported_country`, `not_checked` or `error` have no VAT check fee. They only cost the $0.00002 row fee. Duplicates are checked and charged once.

Platform usage (compute, storage) is included in the event prices.

#### Cost examples (Free plan prices)

| Scenario | Input | Events | Total |
| ---: | --- | --- | ---: |
| Prefill | 6 numbers, 5 verdicts | 1 start + 5 checks + 6 rows | $0.0103 |
| Small | 10 numbers, all with verdicts | 1 start + 10 checks + 10 rows | $0.0199 |
| Normal | 100 numbers, all with verdicts | 1 start + 100 checks + 100 rows | $0.1927 |
| Maximum | 1,000 numbers, all with verdicts | 1 start + 1,000 checks + 1,000 rows | $1.9207 |
| Only wrong formats | 1,000 numbers, all `format_error` | 1 start + 1,000 rows | $0.0207 |

Your maximum total charge for a run (set in the run options) is respected. When the next check would go over it, the Actor stops sending numbers, marks the rest as `not_checked` (no check fee) and ends the run as SUCCEEDED with `reason: "CHARGE_LIMIT"`.

#### Limits and speed

- Up to **1,000 numbers per run**. Split bigger lists into several runs.
- Speed: about 100 numbers per minute when the list has many countries (1,000 numbers from 12 countries took about 4.5 minutes in our test). The Actor sends only one request at a time to each country, because VIES limits parallel requests per country. So a list from one country is slower: 194 German numbers took about 1.5 minutes in our test. A very long list from one slow country may not finish within the 900-second timeout; the rest is then marked `not_checked` (no check fee) — split such lists or raise the timeout.
- Default run options: 256 MB memory, 900-second timeout. More memory does not make the run faster.
- If the run time limit is close, the Actor stops sending numbers 20 seconds before it and marks the rest as `not_checked`.
- If VIES gives no verdict at all for 2 minutes (only "busy" or "unavailable" answers), the Actor stops early with `reason: "VIES_NOT_RESPONDING"` instead of waiting until the timeout. Run the list again later.

### Use cases

| Buyer job | Input | Key fields | Next step |
| --- | --- | --- | --- |
| Check a customer before a reverse-charge invoice | `vatNumbers` + `requesterVat` | `status`, `valid`, `consultationNumber`, `requestDate` | Save the consultation number with the invoice |
| Clean a CRM or lead list | `vatNumbers` (export from CRM) | `status`, `name`, `address` | Export CSV and update the CRM |
| Re-check suppliers every month | `vatNumbers` in a saved task | `status`, `errorCode` | Schedule the task; follow up on `invalid` rows |

### API, export and integrations

- **API:** start a run with `POST https://api.apify.com/v2/acts/cliqtomedia~vat-number-validator/runs` and the input JSON above. Read rows from the run's default dataset.
- **Export:** download the dataset as JSON, CSV, Excel or XML from the Output tab or the [dataset API](https://docs.apify.com/api/v2/dataset-items-get).
- **Scheduling:** save your input as a task and add an [Apify schedule](https://docs.apify.com/platform/schedules) to re-check the same list.
- **Webhooks / no-code:** use an [Apify integration](https://docs.apify.com/platform/integrations) (Make, Zapier, webhooks) to send the rows on when the run finishes. Filter on `status` in the next step.

#### Use with AI agents (MCP)

- MCP server URL with only this Actor: `https://mcp.apify.com?tools=cliqtomedia/vat-number-validator`
- Smallest useful input: `{"vatNumbers": ["IE6388047V"]}`
- Key output fields: `fullVatNumber` (cleaned number), `status` (see the status table), `valid` (true / false / null), `name` and `address` (null when the country does not share them).
- The 6-number prefill finished in 2–8 seconds in our tests and costs about $0.01; 100 numbers take about 1 minute and cost about $0.19. Maximum 1,000 numbers per run.
- `valid: null` never means invalid. Read `status` and `errorMessage` for the reason.

### Troubleshooting

#### Many numbers show `service_unavailable`

Symptom: rows from one country have `status: "service_unavailable"` and `errorCode: "MS_UNAVAILABLE"` or `"MS_MAX_CONCURRENT_REQ"`.
Likely reason: that country's tax database was down or busy. This happens on the VIES side, often for a short time.
Check: `RUN_SUMMARY` → `unavailableCountries`. The [VIES website](https://ec.europa.eu/taxation_customs/vies/) shows which countries are available now.
Action: run only these numbers again later. Keep `retryUnavailable: true`.

#### A number I know is real shows `format_error`

Symptom: `errorMessage` says the number does not match the country's format.
Likely reason: a missing or wrong country prefix, a missing digit, or extra text in the cell (for example a company name or HTML).
Check: compare `input` with the country's VAT format; the prefix must be the VIES code (`EL` or `GR` for Greece, `XI` for Northern Ireland).
Action: fix the number and run it again.

#### A valid number has no name or address

Symptom: `status: "valid"` but `name` and `address` are `null`.
Likely reason: some countries (for example Germany and Spain) do not share these details through VIES.
Action: nothing is wrong. The verdict is still valid.

#### The run ended with some `not_checked` rows

Symptom: `RUN_SUMMARY.status` is `PARTIAL` and some rows are `not_checked`.
Likely reason: your maximum total charge or the run timeout was reached.
Action: raise the maximum charge or the timeout, or run the `not_checked` numbers in a new run.

#### The run failed at once

Symptom: run status FAILED with "Invalid input".
Likely reason: `vatNumbers` is empty, has more than 1,000 items, or `requesterVat` has a wrong format.
Action: fix the input as the message says.

### FAQ

#### Do I need a login or an API key?

No. VIES is a public service of the European Commission. You only need an Apify account to run the Actor.

#### Can I check UK VAT numbers?

Not GB numbers: they left VIES in 2021, and the UK HMRC check needs registered API credentials. Northern Ireland numbers with the `XI` prefix are checked through VIES.

#### Is a `service_unavailable` number invalid?

No. It means the country did not answer. Run it again later. You do not pay the check fee for it.

#### How fresh is the data?

Each check is a live VIES request at run time. `requestDate` shows the time of the VIES answer. The Actor does not cache results.

#### Is the result legal proof?

When you add your own VAT number in `requesterVat`, VIES returns a consultation number. It is the VIES record that you checked this number on that date. Whether it is enough proof for your tax office is a question for your tax adviser.

### Support

For bugs, questions or feature requests, open an issue in the **Issues** tab of this Actor. Include the run ID and the numbers that gave an unexpected result. Do not send API tokens or private customer data.

# Changelog

This Actor's version history is a separate document: https://apify.com/cliqtomedia/vat-number-validator/changelog.md

# Actor input Schema

## `vatNumbers` (type: `array`):

EU VAT numbers with the two-letter country prefix, one per line, e.g. IE6388047V or DE 143 454 214. Spaces, dots and dashes are ignored; GR is accepted for Greece (EL). Northern Ireland uses XI. Up to 1,000 per run; duplicates are checked once.

## `requesterVat` (type: `string`):

Add your company's EU VAT number to receive an official VIES consultation number for each valid check (proof that you verified your customer). Leave empty if you only need valid/invalid.

## `retryUnavailable` (type: `boolean`):

When a member state's database is down or busy, wait and retry it up to 3 more times (about 2 minutes in total) before reporting 'service_unavailable'. Such numbers are never reported as invalid and have no check fee.

## Actor input object example

```json
{
  "vatNumbers": [
    "IE6388047V",
    "LU20260743",
    "NL810433941B01",
    "DE143454214",
    "ATU33803701",
    "DE12"
  ],
  "retryUnavailable": true
}
```

# Actor output Schema

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

One row per unique VAT number with status, name and address.

## `runSummary` (type: `string`):

Status, counts per result type, unavailable member states and request statistics.

# 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 = {
    "vatNumbers": [
        "IE6388047V",
        "LU20260743",
        "NL810433941B01",
        "DE143454214",
        "ATU33803701",
        "DE12"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/vat-number-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 = { "vatNumbers": [
        "IE6388047V",
        "LU20260743",
        "NL810433941B01",
        "DE143454214",
        "ATU33803701",
        "DE12",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/vat-number-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 '{
  "vatNumbers": [
    "IE6388047V",
    "LU20260743",
    "NL810433941B01",
    "DE143454214",
    "ATU33803701",
    "DE12"
  ]
}' |
apify call cliqtomedia/vat-number-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/vat-number-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/X7r4LaiYoG6OuCjwZ/builds/7jNamHZOS2cKqXOD7/openapi.json
