# W System – full reference for LLMs > W System (W System Hungary Kft., Budapest, EU VAT HU33119856) makes an API, a remote MCP server and Apify Actors for EU business data: EU VAT number validation via VIES, EORI validation via EC EOS, official company-registry lookup, sanctions screening (EU, UN, OFAC SDN, UK), one-call KYB, EU e-invoicing (validate EN 16931/XRechnung invoices incl. ZUGFeRD PDFs, create UBL invoices from JSON, 'can I e-invoice this company?' lookup), a counterparty due-diligence report, and EU public tenders from TED. When VIES is down for a member state, VAT checks fall back to the official national source (PL Biała lista, CZ ARES, FI YTJ, FR SIRENE) or the last successful VIES result, always flagged fallback=true with source and legal_status and no consultation number. GB VAT: accepted and check-digit validated; live HMRC validation is built but needs HMRC Developer Hub credentials (not configured yet, results say not_configured). XI is checked in VIES. Free tier: 20 calls/day per IP, no API key or signup. Beyond that: x402 pay-per-call in USDC on Base ($0.01 per single check, $0.10 per batch, $0.045 per KYB, e-invoice validate $0.03 / create $0.08 / route $0.02, due-diligence report $0.49) or Apify pay-per-event. Monthly plans with an API key (X-API-Key header): Starter EUR 19/month for 5,000 units, Pro EUR 49/month for 25,000 units. Units per call: POST /ddreport 50, POST /einvoice/create 8, POST /kyb/check 5, POST /einvoice/validate 3, everything else 1 (VAT, EORI, company, sanctions incl. batches, GET /einvoice/route). Responses carry X-Units-Used and X-Units-Remaining; a call whose units exceed the remaining allowance gets HTTP 429 monthly_quota_exhausted (with units_required and units_remaining) and nothing is deducted; units reset on the 1st of each month (UTC). Plans are sold via Stripe Managed Payments (Stripe is merchant of record; tax at checkout). Subscribe at https://wsystem.dev/#pricing, or POST https://api.wsystem.dev/billing/checkout {"plan":"starter"|"pro"} to get a Stripe Checkout URL; plan list: https://api.wsystem.dev/billing/plans. Contact: hello@wsystem.dev ## EU VAT number validation API (VIES) URL: https://wsystem.dev/eu-vat-number-validation-api To validate an EU VAT number programmatically, call GET https://api.wsystem.dev/verify?vat=IE6388047V. It queries the European Commission's VIES service and returns status (valid, invalid, invalid_format, member_state_unavailable or error), the registered name and address where the member state discloses them, and a VIES consultation number as audit proof. No signup or API key is needed for 20 calls per day per IP. Facts: - Covers all 27 EU member states plus Northern Ireland (XI). Greece uses the prefix EL, not GR. - Source: VIES, run by the European Commission. W System is an independent wrapper and is not affiliated with the Commission. - Input is normalised: spaces, dots and dashes are removed, so DE 811 193 231 works. - Batch: POST /verify/batch takes up to 100 numbers per request. - When a national database is offline, the API retries with backoff, then falls back to an official national source (PL, CZ, FI, FR) or the last successful VIES result, flagged fallback: true with source and legal_status and no consultation number. Otherwise it returns member_state_unavailable with valid: null, never a false invalid. Details: VIES down fallback. - UK: GB numbers are accepted and check-digit validated; live validation through the HMRC Check a UK VAT number API v2 is built but needs HMRC Developer Hub OAuth credentials, which are not configured yet, so GB results currently return status: not_configured. Northern Ireland (XI) numbers are checked in VIES. - Free tools: bulk VAT checker for CSV files and live VIES status. - Consultation number: pass your own EU VAT number as requester (default is ours) to get a dated VIES reference you can keep for audits. - Germany and Spain usually do not disclose name/address through VIES; validity is still returned. Examples: Validate one VAT number: ``` curl "https://api.wsystem.dev/verify?vat=IE6388047V" ``` German number (no name/address disclosed by DE): ``` curl "https://api.wsystem.dev/verify?vat=DE811193231" ``` Batch of up to 100: ``` curl -X POST https://api.wsystem.dev/verify/batch -H 'Content-Type: application/json' \ -d '{"vats":["IE6388047V","FR40303265045"],"requester":"YOUR_EU_VAT"}' ``` Pricing: - Website checker, REST and MCP free tier: Free, 20 calls/day per IP, no key - x402 REST: GET /verify: $0.01 USDC per call - x402 REST: POST /verify/batch (up to 100): $0.10 USDC per request - Apify Actor wsystem/eu-vat-checker: $0.005 per VAT checked + $0.005 per run Comparison (public pages, checked 2026-10-17): | W System API | VIES REST/SOAP (EC, direct) | vatlayer (apilayer) Free usage | 20 calls/day per IP, no key | Free, no key | 100 requests/month, non-commercial, signup + key Paid entry price | $0.01 per call (x402), no subscription | n/a (free) | $9.99/month for 1,000 requests Batch endpoint | Yes, 100 per request | No (one number per call) | Not listed on pricing page MCP server for AI agents | Yes, remote, 11 tools | No | Not listed Pay per call without account (x402) | Yes, USDC on Base | No | No (card subscription) Consultation number (audit proof) | Yes, with requester VAT | Yes, with requester VAT | Not listed EORI, registry, sanctions in same API | Yes | No | VAT rates and price calculation instead Q&A: Q: Is there a free EU VAT validation API without an API key? A: Yes. The VIES REST API itself is free, and W System's api.wsystem.dev gives 20 free calls per day per IP with no key and no signup, adding batch, retries, caching and an MCP endpoint. Q: How do I check a VAT number for reverse charge? A: Validate the customer's VAT number with GET /verify on the invoice date and keep the consultation_number from the response as evidence. A valid VIES result is one of the conditions for zero-rating intra-EU B2B supplies; it is not tax advice. Q: What does member_state_unavailable mean? A: The member state's national database behind VIES did not answer (MS_UNAVAILABLE). The number is not invalid. Retry later; the API already retries with backoff before returning this. Q: Why is name and address empty for a German VAT number? A: Germany (and often Spain) do not publish name/address through VIES. The validity result is still official. Q: Can I validate UK VAT numbers? A: GB numbers are not in VIES since Brexit. The API accepts GB numbers and checks the HMRC check digits, and has HMRC Check a UK VAT number API v2 support built in, but that needs OAuth app credentials from the HMRC Developer Hub which are not configured yet; until then GB results say not_configured. XI (Northern Ireland) numbers are fully checked in VIES. Q: Can AI agents use it? A: Yes. Connect any MCP client to https://api.wsystem.dev/mcp/ and use the verify_vat or verify_batch tools. ## VIES is down: how to handle MS_UNAVAILABLE and timeouts URL: https://wsystem.dev/vies-down-fallback When VIES or a member state's database is down, VIES returns errors such as MS_UNAVAILABLE, MS_MAX_CONCURRENT_REQ, SERVICE_UNAVAILABLE or TIMEOUT. These mean unknown, not invalid. The W System API retries with backoff; if the country is still down it answers from that country's free official source (Poland Biała lista, Czech ARES, Finnish YTJ VAT register, French SIRENE) or from the last successful VIES result with its date. Every fallback answer has fallback: true, names its source and legal_status, and has no VIES consultation number. If neither exists you get member_state_unavailable with valid: null. Live status: VIES status page. Facts: - VIES is a gateway: every check is forwarded to the national tax administration of the number's country, so one country can be down while others work. See the live VIES status page. - Fallback order: 1) retry VIES with exponential backoff, 2) official national source, 3) last successful VIES answer for that number (labelled with its date), 4) member_state_unavailable. - National sources used: 🇵🇱 PL Biała lista podatników VAT (Ministry of Finance, wl-api.mf.gov.pl; about 100 searches/day per IP), 🇨🇿 CZ ARES (VAT register record status), 🇫🇮 FI YTJ open data (VAT register entry), 🇫🇷 FR Recherche d'entreprises / SIRENE (company active + VAT key check; France has no free VAT-registration API). - No free automated national fallback exists for DE (BZSt eVatR only accepts German requester VAT IDs), ES (needs an electronic certificate), IT (captcha web form), NL, BE (web UI / registered open-data dump), HU (NAV technical user) or DK (credentials). For these, only the cached last VIES result can be used. - National registers confirm the domestic VAT or company status. That usually matches EU (intra-community) VAT status but not always, so a fallback is not audit proof for zero-rating. Re-check in VIES when it is back. - Fallbacks never include a consultation number. A cached result keeps the earlier number in original_consultation_number, and that number belongs to the earlier check. - Disable fallbacks with fallback=false (REST) or useFallback: false (Apify Actor). On the Apify Actor, fallback rows are not charged. Examples: Check, then branch on status and fallback: ``` curl "https://api.wsystem.dev/verify?vat=PL5260250995" # status: valid | invalid | invalid_format | member_state_unavailable | error # if fallback == true: read source, legal_status, fallback_type (national_source | last_vies_result) ``` Shape of a national-source fallback (PL, while VIES is down): ``` {"vat": "PL5260250995", "status": "valid", "valid": true, "fallback": true, "fallback_type": "national_source", "consultation_number": null, "source": "Biała lista podatników VAT (Ministry of Finance / KAS), wl-api.mf.gov.pl", "legal_status": "Polish VAT status: Czynny (Czynny = active VAT payer, Zwolniony = exempt)", "name": "ORANGE POLSKA SPÓŁKA AKCYJNA", "vies_error": "MS_UNAVAILABLE"} ``` VIES availability per country (free, cached 5 min): ``` curl "https://api.wsystem.dev/vies/status" ``` Pricing: - Free tier: 20 calls/day per IP, no key - x402 per call: $0.01 USDC - Batch (100 numbers): $0.10 USDC per request - VIES status endpoint: Free, not counted Comparison (public pages, checked 2026-10-17): Behaviour when a member state is down | W System API | Calling VIES directly Automatic retries with backoff | Yes | You implement it Official national-source fallback | PL, CZ, FI, FR | No Last successful result, dated | Yes (any age, labelled) | No Result when nothing else works | member_state_unavailable, valid=null | SOAP fault / error JSON Batch with per-item status | Yes, 100 per request | No batch Q&A: Q: Is VIES down right now? A: See https://wsystem.dev/vies-status, which reads the European Commission's own VIES check-status endpoint, or call GET https://api.wsystem.dev/vies/status. Q: Should I reject a customer if VIES is unavailable? A: No. Treat it as unknown or use the flagged fallback answer, and re-check in VIES later before relying on it for zero-rating. Q: Is a national-register fallback legally equivalent to VIES? A: No. It shows the domestic status from an official national source. VIES (with a consultation number) remains the evidence most tax authorities expect for intra-EU B2B supplies. This is not tax advice. Q: Why is there no fallback for Germany? A: The BZSt eVatR service is free but only accepts requests where the requester is a German VAT ID holder, so a general API cannot use it. German numbers fall back to the last VIES result only. Q: How long do VIES outages last? A: Usually minutes to a few hours, often around national maintenance windows (evenings and weekends). ## EORI number check API (EU, official EOS) URL: https://wsystem.dev/eori-number-check-api Call GET https://api.wsystem.dev/eori?eori=SE5560360793. The API queries the European Commission's EOS EORI validation service (which is SOAP-only) and returns JSON: valid, status and the trader's name and address when the trader agreed to publication. Batch up to 100 numbers with POST /eori/batch. Facts: - EORI = Economic Operators Registration and Identification number, required for customs declarations in the EU. - Format: country code + national identifier, up to 17 characters (e.g. SE5560360793, DE plus up to 15 digits). - Source: EC EOS service (ec.europa.eu/taxation_customs/dds2/eos). The official endpoint is SOAP; this API turns it into JSON. - GB EORIs are validated by HMRC, not EOS. XI (Northern Ireland) EORIs are in EOS. - Name and address are only returned when the trader consented to publication. Examples: Validate one EORI: ``` curl "https://api.wsystem.dev/eori?eori=SE5560360793" ``` Batch: ``` curl -X POST https://api.wsystem.dev/eori/batch -H 'Content-Type: application/json' \ -d '{"eoris":["SE5560360793","IE6388047V"]}' ``` Pricing: - Free tier: 20 calls/day per IP, no key - x402 GET /eori: $0.01 USDC per call - x402 POST /eori/batch (up to 100): $0.10 USDC per request - Apify Actor wsystem/eu-eori-checker: $0.005 per EORI checked + $0.005 per run Comparison (public pages, checked 2026-10-17): | W System API | EC EOS web form | EC EOS SOAP service Format | JSON REST + MCP | HTML form | SOAP/XML Batch | 100 per request | Manual | Up to 10 per SOAP call (per EC docs) API key | None for free tier | None | None Usable by AI agents directly | Yes (MCP tool verify_eori) | No | Needs a SOAP client Q&A: Q: How do I check if an EORI number is valid? A: Use the EC EOS form manually, or call GET https://api.wsystem.dev/eori?eori=... for JSON. Both use the same official EOS data. Q: Is my VAT number my EORI number? A: Often the EORI is the country code plus the VAT or tax number (e.g. many Irish and Swedish EORIs), but not always; Germany issues separate EORIs. Always validate the EORI itself. Q: Can I check UK EORI numbers? A: GB EORIs are checked on HMRC's service, not EOS. XI numbers are in EOS. Q: Why is name/address missing? A: The trader did not consent to publication in EOS. ## Sanctions screening API (EU, UN, OFAC SDN, UK) URL: https://wsystem.dev/eu-sanctions-screening-api Call GET https://api.wsystem.dev/sanctions/screen?name=Sberbank. The name is fuzzy-matched (with transliteration, e.g. Cyrillic) against the official EU Consolidated Financial Sanctions List, the UN Security Council Consolidated List, the US OFAC SDN list and the UK sanctions list, downloaded from the official publishers. You get potential_match or no_match, scored candidates (0–100), the list, programme and listing date. Facts: - Lists: EU Consolidated Financial Sanctions List, UN Security Council Consolidated List, OFAC SDN, UK sanctions list. Restrict with lists=EU,UN. - Optional birth_year and country reduce false positives for people. - Default threshold 85 (range 50–100). - Not covered: PEP lists, adverse media, national lists outside those four. For those, use a full compliance provider. - Screening aid only: a potential match needs human review. This is not legal advice. Examples: Screen one name: ``` curl "https://api.wsystem.dev/sanctions/screen?name=Sberbank" ``` Batch of up to 50: ``` curl -X POST https://api.wsystem.dev/sanctions/screen/batch -H 'Content-Type: application/json' \ -d '{"names":["Sberbank","Example Trading Ltd"],"threshold":85}' ``` Pricing: - Free tier: 20 calls/day per IP, no key - x402 GET /sanctions/screen: $0.01 USDC per name - x402 batch (up to 50 names): $0.10 USDC per request - Apify Actor wsystem/sanctions-screening: $0.005 per name + $0.005 per run Comparison (public pages, checked 2026-10-17): | W System API | OpenSanctions API | Official list downloads Lists | EU, UN, OFAC SDN, UK | Sanctions, PEPs and more (hundreds of sources) | One list per publisher Entry price | $0.01 per name, no account (x402); 20/day free | €50 for 500 credits (€0.10/query) | Free, you build matching Fuzzy / transliteration matching | Yes | Yes | No PEPs | No | Yes | No MCP tool for agents | Yes (screen_sanctions) | Not listed on API page | No Q&A: Q: Is there a free sanctions screening API? A: W System gives 20 free screens per day per IP without a key; beyond that $0.01 per name. The official lists are free to download if you build matching yourself. Q: Which lists should an EU company screen against? A: At minimum the EU consolidated list; most also screen UN, OFAC SDN (if any US nexus) and UK lists. Ask your compliance adviser. Q: How often are lists refreshed? A: Daily from the official publishers. The response includes lists_date. Q: Does a match mean the person is sanctioned? A: No. It is a candidate for human review; compare dates of birth, nationality and identifiers. ## European company registry API URL: https://wsystem.dev/eu-company-registry-api Call GET https://api.wsystem.dev/company?q=552032534&country=FR with a company name or registry number. The API queries the official register for that country and returns legal name, registry ID, active status, address, VAT ID, activity code and a source link. Supported directly: FR, NO, FI, CZ, PL (by KRS number), EE; other countries via the GLEIF LEI database. Facts: - France: INSEE Sirene via recherche-entreprises.api.gouv.fr (SIREN/SIRET or name). - Norway: Brønnøysund Register Centre (org.nr or name). Finland: PRH/YTJ (Y-tunnus). Czechia: ARES (IČO). Poland: KRS (by KRS number). Estonia: e-Business Register open data. - Other countries (DE, NL, IT, ES, …): GLEIF LEI records, which cover companies that have an LEI only. - Hungary, Germany and several others do not offer a free, reusable official registry API; we do not scrape them. - Batch: POST /company/batch, up to 25 queries. Examples: Lookup by SIREN: ``` curl "https://api.wsystem.dev/company?q=552032534&country=FR&limit=1" ``` By name in Norway: ``` curl "https://api.wsystem.dev/company?q=equinor&country=NO" ``` Pricing: - Free tier: 20 calls/day per IP, no key - x402 GET /company: $0.01 USDC per lookup - x402 POST /company/batch (up to 25): $0.10 USDC per request - Apify Actor wsystem/european-company-registry: $0.008 per lookup + $0.005 per run Comparison (public pages, checked 2026-10-17): | W System API | GLEIF API (direct) | National registry APIs (direct) Coverage | FR, NO, FI, CZ, PL, EE registers + LEI for the rest | Entities with an LEI, worldwide | One country each One JSON shape for all countries | Yes | Yes (LEI only) | No, each differs Price | 20/day free; $0.01/lookup | Free | Mostly free, some need keys MCP tool for agents | Yes (lookup_company) | No | No Q&A: Q: Is there one API for all EU business registers? A: No official one with free reusable data for every country. BRIS/e-Justice links registers for humans. W System covers six registers directly plus GLEIF LEI. Q: Can I get the VAT number from a company registry number? A: For France, yes (vat_id is derived from the SIREN). For others it depends on what the register publishes. Q: Can I look up German or Hungarian companies? A: Only via GLEIF if they have an LEI. The German and Hungarian registers do not offer a free reusable API. ## EU tenders (TED) search API and alerts URL: https://wsystem.dev/ted-tenders-api Use the Apify Actor wsystem/eu-tenders-search. It calls the official TED v3 Search API of the EU Publications Office and returns flat JSON notices (title, buyer, country, CPV, deadline, estimated value, URL, PDF). Filter by keywords, CPV codes, countries, notice type and value; Monitor mode returns only notices you have not seen, for daily alerts. AI agents can call it via the Apify MCP server. Facts: - Source: TED – Tenders Electronic Daily, the EU's official journal for public procurement (EU Publications Office), via its v3 Search API. No scraping. - Filters: keywords, CPV codes (e.g. 72000000 IT services, 45000000 construction), countries, notice type (tenders or awards), only open, minimum estimated value. - Monitor mode (onlyNew): schedule daily on Apify and get only new notices. - Not yet in the api.wsystem.dev REST API; available as an Apify Actor (REST, webhooks, Zapier/Make/n8n) and through mcp.apify.com. - The TED Search API itself is free; this Actor adds a flat schema, filtering, deduplication and monitoring. Examples: Actor input: ``` { "keywords": ["cybersecurity", "SIEM"], "cpvCodes": ["72000000"], "countries": ["DE", "AT", "PL"], "noticeTypes": "tenders", "onlyOpen": true, "maxNotices": 100, "onlyNew": true } ``` Output record: ``` { "notice_id": "714026-2026", "title": "Hungary – Sound equipment – Hangtár eszközbeszerzése", "buyer": "Erkel Színház Nonprofit Kft.", "cpv_codes": ["32342410"], "publication_date": "2026-10-15", "deadline": "2026-11-13", "url": "https://ted.europa.eu/en/notice/-/detail/714026-2026", "source": "TED – Tenders Electronic Daily (EU Publications Office)" } ``` AI agent (MCP): ``` https://mcp.apify.com?tools=wsystem/eu-tenders-search ``` Pricing: - Apify Actor wsystem/eu-tenders-search: $0.003 per notice + $0.005 per run (Apify billing) Comparison (public pages, checked 2026-10-17): | W System Actor | TED Search API (direct) | TED website Output | Flat JSON records | Nested eForms fields, you choose fields | HTML/PDF Monitoring of new notices | Built-in (onlyNew) | You build it | Saved searches with an EU Login account Price | $0.003 per notice | Free | Free AI agent access | Apify MCP server | No MCP | No Q&A: Q: Is there a free API for EU tenders? A: Yes, the TED v3 Search API from the EU Publications Office is free. The W System Actor adds filtering, flat JSON, monitoring and integrations for a small per-notice fee. Q: Which tenders are on TED? A: Notices above the EU thresholds from all EU member states plus EEA and some other countries; below-threshold national tenders are often only on national portals. Q: How do I get daily tender alerts? A: Schedule the Actor daily with onlyNew=true and connect a webhook, email or Slack integration in Apify. ## One-call KYB check for EU companies URL: https://wsystem.dev/kyb-api Call POST https://api.wsystem.dev/kyb/check with {"company": "FR40303265045"} (a VAT ID, CC:name, or an object with name, vatNumber, country, registryId). The API validates the VAT number in VIES, finds the company in the official register, screens the name against four sanctions lists and returns verdict: pass, review or fail, with reasons. Facts: - Verdict rules: fail on an invalid VAT number, a company marked inactive in the register, or a strong sanctions match (score ≥ 90); review on a possible match, VIES/register name mismatch, company not found or a source being unavailable; pass otherwise. - Each section (vat, registry, sanctions) is returned in full so you can show evidence. - MCP tool: kyb_check. Apify Actor: wsystem/kyb-company-check. - Not a full AML/KYC solution: no UBO, PEP, document or ID verification. Examples: KYB by VAT ID: ``` curl -X POST https://api.wsystem.dev/kyb/check -H 'Content-Type: application/json' \ -d '{"company":"FR40303265045"}' ``` Pricing: - Free tier: 20 calls/day per IP, no key - x402 POST /kyb/check: $0.045 USDC per company - Apify Actor wsystem/kyb-company-check: $0.045 per company + $0.005 per run Q&A: Q: What is a KYB check? A: Know Your Business: confirming a company exists, is active, has a valid tax ID and is not sanctioned before you trade with it. Q: Does this cover beneficial owners (UBO)? A: No. UBO registers in the EU mostly require legitimate-interest access since the 2022 CJEU ruling. Q: Can an AI agent run KYB? A: Yes, via the MCP tool kyb_check at https://api.wsystem.dev/mcp/. ## EU e-invoice API: validate, create and route EN 16931 invoices URL: https://wsystem.dev/eu-e-invoice-validation-api Send the invoice to POST https://api.wsystem.dev/einvoice/validate as the raw body (XML or a ZUGFeRD/Factur-X PDF). You get valid plus every error with its official rule ID (e.g. BR-CO-10), a plain-English message, the XPath and a fix hint. To produce an invoice, post simple JSON to /einvoice/create; to find out whether a customer is on Peppol and what their country requires, call GET /einvoice/route?id=BE0403170701. Facts: - Rule sets: CEN EN 16931 validation artefacts (UBL and CII) and the KoSIT XRechnung 3.0.2 configuration (release 2026-08-31), run unmodified, plus the UBL 2.1 / CII D16B XML schemas. - Inputs: UBL Invoice and CreditNote, UN/CEFACT CII, and PDFs with an embedded factur-x.xml / zugferd-invoice.xml / xrechnung.xml. Profile detected automatically (EN 16931, XRechnung, Peppol BIS, Factur-X). - Not checked yet: Peppol BIS 3 specific rules (PEPPOL-EN16931-*). Every response says exactly which rule sets ran (checked). - Create: formats en16931, xrechnung and peppol-bis3 (UBL 2.1 structure); line totals, VAT breakdown per category and rate, exemption codes (VATEX) for reverse charge, intra-EU and export are computed, and the result is validated before it is returned. Example body: /einvoice/sample. - Route lookup: VIES VAT status, Peppol Directory registration and BIS 3 invoice support, the B2B mandate for the country (BE, FR, DE, PL, IT, RO, HR, GR, ES, HU; dated and linked to the official source) and a recommended format. The French PPF directory is not included yet. - Due-diligence report: POST /ddreport bundles VAT, business register, sanctions, EORI, GLEIF LEI and Peppol into one JSON report with risk flags, a score and a UTC timestamp ($0.49). - MCP tools: validate_einvoice, create_einvoice, einvoice_route, due_diligence_report at https://api.wsystem.dev/mcp/. - Licences and sources: CEN EN 16931 validation artefacts, EUPL-1.2, github.com/ConnectingEurope/eInvoicing-EN16931; KoSIT XRechnung configuration, Apache-2.0, github.com/itplr-kosit/validator-configuration-xrechnung. Both are used unmodified. - A technically valid file is not tax advice. We are a validator, not a Peppol Access Point: we do not send invoices. Examples: Validate a ZUGFeRD / Factur-X PDF: ``` curl -X POST https://api.wsystem.dev/einvoice/validate \ -H 'Content-Type: application/pdf' --data-binary @invoice.pdf ``` Validate an XRechnung XML (force XRechnung rules): ``` curl -X POST 'https://api.wsystem.dev/einvoice/validate?rules=xrechnung' \ -H 'Content-Type: application/xml' --data-binary @xrechnung.xml ``` Create an XRechnung from JSON: ``` curl -s https://api.wsystem.dev/einvoice/sample > invoice.json curl -X POST https://api.wsystem.dev/einvoice/create \ -H 'Content-Type: application/json' --data @invoice.json ``` Can I e-invoice this company?: ``` curl 'https://api.wsystem.dev/einvoice/route?id=BE0403170701' ``` Pricing: - Free tier: 20 calls/day per IP across all endpoints, no key - x402 POST /einvoice/validate: $0.03 USDC per invoice - x402 POST /einvoice/create: $0.08 USDC per invoice - x402 GET /einvoice/route: $0.02 USDC per lookup - x402 POST /ddreport: $0.49 USDC per report Q&A: Q: Which errors do I get back? A: Each failed rule with its official ID (BR-xx, BR-CO-xx, BR-DE-xx, XSD), severity, a plain-English message, the XPath location, the business terms (BT-xx) involved and, for common rules, how to fix it. Q: Does it check Peppol BIS 3? A: Not yet. Peppol BIS 3 invoices are checked against EN 16931 (the core every Peppol invoice must meet), and the response marks PeppolBIS3 as not checked. Peppol-specific rules will be added once licensing is confirmed with OpenPeppol. Q: Is ZUGFeRD MINIMUM or BASIC WL accepted? A: They are parsed, but the response notes that these profiles are not EN 16931 compliant invoices on their own for German or French B2B. Q: Do you store my invoices? A: No. Invoices are processed in memory and not stored; only per-IP call counters are kept for the free tier. Q: Which rule versions do you use? A: CEN EN 16931 artefacts as shipped in the KoSIT XRechnung configuration 3.0.2 (release 2026-08-31). We update when KoSIT and CEN publish new releases. ## MCP server for EU VAT, EORI, company registry and sanctions URL: https://wsystem.dev/eu-business-data-mcp-server Add https://api.wsystem.dev/mcp/ as a streamable-HTTP MCP server in Claude, Cursor, VS Code, Windsurf or any MCP client. No API key or OAuth. The server exposes 11 tools for EU VAT (VIES), EORI (EOS), company registry, sanctions screening, KYB, EN 16931 e-invoice validation and creation, Peppol/e-invoicing routing and a counterparty due-diligence report. It is published in the official MCP Registry as io.github.zifengw/eu-business-data-mcp; source is MIT on GitHub. Facts: - Tools: verify_vat, verify_batch, verify_eori, verify_eori_batch, lookup_company, screen_sanctions, kyb_check, validate_einvoice, create_einvoice, einvoice_route, due_diligence_report. - Transport: streamable HTTP at https://api.wsystem.dev/mcp/. Stdio-only clients: npx mcp-remote https://api.wsystem.dev/mcp/. - Server card: https://api.wsystem.dev/server-card (also /.well-known/mcp/server-card). - Free: 20 tool calls per day per IP. For volume, use the x402 REST API or the Apify Actors via mcp.apify.com. - Source code: github.com/zifengw/eu-business-data-mcp (run locally over stdio without limits). Examples: Claude Desktop / Cursor config: ``` { "mcpServers": { "eu-business-data": { "type": "http", "url": "https://api.wsystem.dev/mcp/" } } } ``` Claude Code: ``` claude mcp add --transport http eu-business-data https://api.wsystem.dev/mcp/ ``` Prompt: ``` "Check whether DE811193231 and IE6388047V are valid VAT numbers and screen both companies for sanctions." ``` Prompt (e-invoicing): ``` "Validate this XRechnung invoice and tell me which EN 16931 rules it breaks, then check whether BE0403170701 can receive Peppol invoices." ``` Pricing: - MCP free tier: 20 calls/day per IP - Self-hosted (stdio, MIT): Free, unlimited Q&A: Q: Is there an MCP server for VIES VAT validation? A: Yes. W System's remote MCP server at https://api.wsystem.dev/mcp/ exposes verify_vat and verify_batch backed by VIES. Q: Does it need an API key? A: No. Q: Is there an MCP server for e-invoice validation? A: Yes. The same server has validate_einvoice (UBL, CII or ZUGFeRD/Factur-X PDF against the official EN 16931 and XRechnung rules), create_einvoice (valid UBL invoice from JSON) and einvoice_route (VIES + Peppol Directory + country mandate). Peppol BIS 3 specific rules are not checked yet. Q: Where is it listed? A: Official MCP Registry (io.github.zifengw/eu-business-data-mcp), Glama, mcpservers.org. ## x402: pay per call for VAT, EORI, company and sanctions checks URL: https://wsystem.dev/x402 After the free tier (20 calls/day per IP), paid routes on api.wsystem.dev answer HTTP 402 with an x402 v2 challenge in the PAYMENT-REQUIRED header (scheme exact, USDC on Base, network eip155:8453). An x402 client signs the payment and retries with PAYMENT-SIGNATURE (or X-PAYMENT); the facilitator (PayAI) settles it. Routes are declared for x402 Bazaar discovery and listed at https://api.wsystem.dev/.well-known/x402. Facts: - Network: Base mainnet (eip155:8453), asset USDC. Facilitator: facilitator.payai.network. - Discovery: /.well-known/x402 manifest, OpenAPI x-payment-info, Bazaar extension on each route. - Clients: x402 SDKs (TypeScript/Python), x402-fetch, x402-axios, and agent wallets that support x402. Examples: Python (x402 SDK) – full example in the GitHub x402 guide: ``` # pip install "x402[requests,evm]" eth-account from eth_account import Account from x402 import x402ClientSync from x402.mechanisms.evm import EthAccountSigner from x402.mechanisms.evm.exact.register import register_exact_evm_client from x402.http.clients import x402_requests client = x402ClientSync() register_exact_evm_client(client, EthAccountSigner(Account.from_key(KEY))) # see github.com/zifengw/eu-business-data-mcp/blob/main/docs/x402-agents.md ``` Discovery: ``` curl https://api.wsystem.dev/.well-known/x402 ``` Pricing: - GET /verify, /eori, /company, /sanctions/screen: $0.01 - POST /verify/batch, /company/batch, /eori/batch, /sanctions/screen/batch: $0.10 per request - POST /kyb/check: $0.045 Q&A: Q: What is x402? A: An open protocol that uses HTTP 402 Payment Required so clients, including AI agents, can pay per request with stablecoins without accounts. Q: Do I need x402 for small volumes? A: No; 20 calls per day per IP are free. ## EU VAT validation guide A practical, source-linked guide to validating EU VAT numbers for invoicing, onboarding and checkout. Written by W System, maker of the api.wsystem.dev VAT validation API (disclosure: we sell the API described in section 7). Last checked 2026-10-17. 1. What an EU VAT number is Every VAT-registered business in the EU has a VAT identification number: a two-letter country prefix followed by 2–13 characters. Greece uses EL (not GR). Northern Ireland traders use XI for goods since 2021. Great Britain (GB) numbers left the EU system on 1 January 2021 and are checked with HMRC. CountryPrefixFormat (after prefix)Example AustriaATU + 8 digitsATU12345678 BelgiumBE10 digits (0 or 1 first)BE0123456789 BulgariaBG9–10 digitsBG123456789 CroatiaHR11 digitsHR12345678901 CyprusCY8 digits + letterCY12345678L CzechiaCZ8–10 digitsCZ12345678 DenmarkDK8 digitsDK12345678 EstoniaEE9 digitsEE123456789 FinlandFI8 digitsFI12345678 FranceFR2 check chars + 9-digit SIRENFR40303265045 GermanyDE9 digitsDE811193231 GreeceEL9 digitsEL123456789 HungaryHU8 digits (first 8 of the adószám)HU33119856 IrelandIE7 digits + 1–2 lettersIE6388047V ItalyIT11 digitsIT12345678901 LatviaLV11 digitsLV12345678901 LithuaniaLT9 or 12 digitsLT123456789 LuxembourgLU8 digitsLU12345678 MaltaMT8 digitsMT12345678 NetherlandsNL9 digits + B + 2 digitsNL123456789B01 PolandPL10 digitsPL1234567890 PortugalPT9 digitsPT123456789 RomaniaRO2–10 digitsRO1234567 SlovakiaSK10 digitsSK1234567890 SloveniaSI8 digitsSI12345678 SpainES9 characters (letter/digit first and last)ESX1234567X SwedenSE12 digits (ends in 01)SE123456789701 Northern IrelandXI9 or 12 digits, or GD/HA + 3XI123456789 A correct format does not mean the number is registered. Only VIES confirms that. 2. VIES: the official source VIES (VAT Information Exchange System) is run by the European Commission. It does not hold its own database: each request is forwarded live to the national tax administration of the number's country, which answers valid/invalid and, depending on national rules, the registered name and address. Access options: Web form: ec.europa.eu/taxation_customs/vies SOAP service checkVatService and checkVatApproxService (the latter returns a consultation number) REST endpoint check-vat-number used by the web form All are free and need no key. Limitations: one number per call, national backends go offline (often evenings and weekends), concurrency limits (MS_MAX_CONCURRENT_REQ), and the EC states that VIES is for confirming validity, not for building databases. 3. When you must (or should) validate Intra-EU B2B supplies of goods: since the 2020 "quick fixes" (Directive 2018/1910), a valid VAT number of the customer, recorded in VIES, is a substantive condition for the 0% exemption. Reverse-charge B2B services: the customer's VAT number is how you show it is a taxable person; validate and keep evidence. Checkout VAT exemption in SaaS / e-commerce: validate before removing VAT, otherwise OSS rules for B2C apply. Supplier onboarding / KYB: invalid VAT IDs are a fraud signal (missing-trader fraud). This is general information, not tax advice. 4. Keeping proof: the consultation number If you include your own EU VAT number as the requester, VIES returns a consultation number (e.g. WAPIAAAAaFIeQCDg), a reference that the check happened on that date. Many tax authorities accept it as evidence of due diligence. Store it with the invoice. Germany's BZSt runs its own "qualifizierte Bestätigungsabfrage" for German businesses. 5. Results and error codes VIES answerMeaningWhat to do valid = trueRegistered for intra-EU transactionsStore date + consultation number valid = falseNot registered (or not enabled for intra-EU trade)Ask the customer; charge VAT INVALID_INPUTMalformed numberFix prefix/format MS_UNAVAILABLE / TIMEOUT / SERVICE_UNAVAILABLENational backend or VIES downUnknown, not invalid: retry later (guide) MS_MAX_CONCURRENT_REQ / GLOBAL_MAX_CONCURRENT_REQRate limitedBack off and retry 6. Code: calling VIES directly curl -s -X POST https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number \ -H 'Content-Type: application/json' -d '{"countryCode":"IE","vatNumber":"6388047V"}' You then handle retries, caching, batch loops and the error codes above yourself. 7. Code: using a wrapper API (ours) curl "https://api.wsystem.dev/verify?vat=IE6388047V" curl -X POST https://api.wsystem.dev/verify/batch -H 'Content-Type: application/json' -d '{"vats":["IE6388047V","DE811193231"]}' Free for 20 calls/day per IP without a key; $0.01 per call via x402 after that; also as an MCP tool for AI agents. Details: EU VAT validation API. 8. Checklist Normalise input (strip spaces/dots, uppercase, EL for Greece).Check the format locally.Validate in VIES with your requester VAT.Treat unavailable as unknown and retry.Store date, result and consultation number with the transaction.Re-validate recurring customers periodically (e.g. quarterly). ## REST endpoints (from OpenAPI) - GET /billing/plans: Monthly API-key plans. - POST /billing/checkout: Start Stripe Checkout for a monthly plan. - GET /health: Liveness check. - GET /vies/status: VIES availability per member state (free, cached 5 min). Proxy of the European Commission VIES check-status endpoint, cached for 5 minutes. Free; does not use the free-tier quota. `national_fallback` = this API can answer from an official national source while that member state is down. - GET /verify: Validate one EU VAT number (VIES). Check whether an EU VAT number (with country prefix, e.g. IE6388047V, DE811193231, HU33119856) is valid in the official VIES system (GB numbers: HMRC). Returns `status` (valid | invalid | invalid_format | member_state_unavailable | error | not_configured), `valid`, registered `name` and `address` where the member state discloses them, and a `consultation_number` (audit proof) when `requester` is a valid EU VAT. If VIES is down for that member state, `fallback: true` answers come from an official national source (PL Biała lista, CZ ARES, FI YTJ, FR SIRENE) or the last successful VIES result with its date; fallbacks never carry a consultation number. Use for reverse-charge invoicing, customer/supplier onboarding and checkout VAT exemption. Free 20/day per IP, then x402 $0.01. - POST /verify/batch: Validate up to 100 EU VAT numbers. Batch VIES validation. Body: {"vats": [...], "requester": "optional own VAT"}. Same per-item result shape as GET /verify. x402 $0.10 per batch request after the free tier. - GET /company: Look up a company in official EU business registers. Search by company name or registry number. `country`: FR (SIREN/SIRET), NO (org.nr), FI (Y-tunnus), CZ (IČO), PL (KRS number), EE (registry code); any other ISO code or LEI uses GLEIF. Returns legal name, registry ID, active status, address, VAT ID, activity code and an official source link. x402 $0.01. - POST /company/batch: Batch company-registry lookup (max 25 queries). Body: {"queries":[{"query":"552032534","country":"FR"}], "limit":3}. x402 $0.10 per batch request. - GET /sanctions/screen: Screen a name against EU, UN, OFAC and UK sanctions lists. Fuzzy, transliteration-aware matching of a person or company name against the official EU consolidated list, UN Security Council list, US OFAC SDN and UK sanctions list (downloaded daily). Returns status (potential_match | no_match), scored candidates (0-100), list, programme and DOB. Screening aid only; potential matches need human review. x402 $0.01. - POST /sanctions/screen/batch: Batch sanctions screening (max 50 names). Body: {"names":[...], "threshold":85}. x402 $0.10. - POST /kyb/check: One-call KYB: VAT + registry + sanctions -> verdict. Know-your-business check of an EU company in one request: VIES VAT validation, official business-register lookup and EU/UN/OFAC/UK sanctions screening, combined into a pass / review / fail verdict with reasons. x402 $0.045. - GET /eori: Validate one EU EORI number (EC EOS). Check an EU EORI (Economic Operators Registration and Identification) number such as SE5560360793 against the official European Commission EOS service. Returns valid/invalid and name/address when the trader consented to publication. Note: GB EORIs are validated by HMRC, not EOS. x402 $0.01. - POST /eori/batch: Validate up to 100 EU EORI numbers. Body: {"eoris":[...]}. x402 $0.10. - POST /einvoice/validate: Validate an EU e-invoice (EN 16931, XRechnung; UBL, CII, ZUGFeRD/Factur-X PDF). Send the invoice as the raw request body (Content-Type application/xml or application/pdf), or JSON {"xml": "..."} / {"base64": ""}. Detects UBL Invoice/CreditNote or UN/CEFACT CII (also the XML embedded in a ZUGFeRD/Factur-X PDF), checks the XML schema and the official CEN EN 16931 Schematron rules, plus the KoSIT XRechnung 3.0 rules when the invoice is an XRechnung (or rules=xrechnung). Returns valid true/false and every error with its official rule ID (e.g. BR-CO-10), plain-English message, XPath location, business terms and a fix hint where known. Peppol BIS 3 specific rules are not checked yet. Technical check, not tax advice. Free tier shared with other endpoints, then x402 $0.03. - POST /einvoice/create: Create a valid EU e-invoice (UBL 2.1) from simple JSON. Turns JSON (seller, buyer, lines with VAT category/rate, payment) into a UBL 2.1 invoice or credit note in format en16931 (plain EN 16931), xrechnung (German XRechnung 3.0) or peppol-bis3 (Peppol BIS Billing 3.0 structure; Peppol-specific rules not checked yet). Totals and the VAT breakdown are computed for you; the result is validated before it is returned (valid, errors, xml). Example body: GET /einvoice/sample. Free tier shared, then x402 $0.08. - GET /einvoice/route: "Can I e-invoice this company?" VAT + Peppol + country mandate lookup. id: an EU VAT number (e.g. BE0403170701) or a Peppol participant id (e.g. 0208:0403170701). Returns the VIES VAT result, whether the company is in the Peppol Directory (participant id, BIS 3 invoice/credit note support), the country's B2B e-invoice mandate (dates, format, channel, source link) and the recommended format for POST /einvoice/create. French PPF directory not included yet. Free tier shared, then x402 $0.02. - POST /ddreport: Counterparty due-diligence report (VAT, register, sanctions, EORI, LEI, Peppol) with risk flags. One call bundles VIES VAT validation, official business-register lookup, EU/UN/OFAC/UK sanctions screening, EC EORI check, GLEIF LEI record and the Peppol / e-invoice route into a JSON report with deterministic risk flags, a 0-100 risk score, a pass/review/fail verdict, sources and a UTC timestamp for your audit file. Public company data only; not a regulated AML/KYC decision. x402 $0.49. - GET /einvoice/sample: Example JSON body for POST /einvoice/create (free).