EU VAT & EORI Validation API Documentation

Developer documentation for the VIESAC REST API: validate VAT and EORI numbers, create VAT, EORI, or hybrid compliance audit trails, and retrieve PDF/XML certificates from VIES, EU EOS, and supported official national registries such as HMRC, Brreg, Swiss UID, and the Serbian Tax Administration VAT Register. All requests require Bearer authentication. Register for an API key.

OpenAPI 3 — https://viesac.eu/openapi.yaml

Official Postman collection

Try the VIESAC API in Postman

Fork our maintained collection to explore the API, configure Bearer authentication, and start testing requests right away.

View the public workspace

Authentication

Use your API key in the Authorization header with the Bearer scheme:

Authorization: Bearer viesac_your_api_key

Base URL

All endpoints are relative to:

https://viesac.eu/api/v1

OpenAPI specification

Machine-readable OpenAPI 3 description of this API (paths, schemas, Bearer security). Use it in Postman, code generators, or AI assistants.

https://viesac.eu/openapi.yaml

Quick start

A reliable integration usually follows this sequence. It also gives API agents a clear decision path.

  1. 1

    Authenticate

    Send your API key with every request in the Authorization header.

  2. 2

    Choose the outcome

    Use GET /validate for a fast status check, or POST /audits when you need evidence and a certificate.

  3. 3

    Store the reference

    Keep the audit reference_number; use it to retrieve the audit and its PDF or XML certificate.

VAT validation API endpoints

Start with this index, then use the field reference below when you need request or response detail.

Method Endpoint Use when you need to…
GET/validateCheck a VAT number without creating an audit.
GET/eori/validateCheck an EORI number without creating an audit.
GET/accountRead the active plan and available capacity.
POST/auditsCreate auditable verification evidence and certificates (VAT, EORI, or hybrid VAT+EORI).
PUT/audits/{reference_number}Update order, invoice, comment, or monitoring data.
GET/partners/checkFind saved partners by VAT or company name.
GET/auditsSearch the audit history (supports ?type=vat|eori|vat_eori|all).
GET/audits/{reference_number}Read one audit and its links.
GET/audits/{reference_number}/certificateDownload the PDF evidence (supports ?type=eori for hybrid).
GET/audits/{reference_number}/certificate/xmlDownload technical XML evidence (supports ?type=eori for hybrid).
GET/rates
/rates/{country}
Retrieve official VAT rates, reduced rates, and special territories (Free, no quota).
GET
/validate
New

Quick VAT status check — does not create an audit. Powered by VIESAC multi-source intelligence: VIES (European Commission), supported official national registries, VIESAC SmartRouter™, VIESAC SmartCache™, and VIESAC AI Engine work together to return the most accurate result.

⚠ For quick lookups only. This endpoint does not produce an official audit record. For legally reliable VAT verification, compliance documentation, and a timestamped certificate with full audit trail, use POST /audits instead.

Query params:

FieldRequirement and description
vat(obligatoriu) — Full VAT including country prefix (e.g. DE123456789, RS104052135, or CHE-123.456.789 MWST). Serbia uses RS followed by a 9-digit PIB with a valid check digit; SRB is accepted as an input alias and normalized to RS.

Response fields:

FieldDescription
vatFull VAT (country + number).
country_codeCountry code, for example DE.
vat_numberVAT number without the country prefix.
statusValidation result: valid, invalid, or audit_required.
sourceOfficial source or cache, including purs_pdv and purs_pdv_cache for Serbia.
company_name, company_addressOfficial register details when available. May be null for an invalid number.
checked_atISO 8601 timestamp.

A temporary Serbian registry error returns audit_required with source=purs_pdv. It does not mean the PIB is invalid. Create an audit to retain a pending record for automatic retry.

Rate limits

Live VAT validations per account

GET /validate
Plan Validations
Free10 / hour
Starter10 / minute
Pro20 / minute
Business30 / minute
EnterpriseUnlimited — by agreement

Enterprise capacity, support level, and commercial terms are tailored to your volume and agreed individually. If a limit is exceeded, the API returns HTTP 429 with retry_after (seconds) and upgrade_url.

GET
/eori/validate
New

Quick EORI status check — does not create an audit. Validates EU EORI numbers via the European Commission EOS system and UK EORI numbers via HMRC. Shares the same validation rate limit as GET /validate.

⚠ For quick lookups only. This endpoint does not produce an official audit record. For an auditable EORI compliance certificate with cryptographic evidence, use POST /audits with type="eori" or hybrid type="vat_eori".

Query params:

FieldRequirement and description
eori(obligatoriu) — Full EORI number including country code (e.g. GB123456789000 or DE123456789012345).

Response fields:

FieldDescription
eoriFull normalized EORI number.
country_code2-letter ISO country code (e.g. GB, FR, DE).
eori_numberEORI number without country prefix.
statusValidation result: valid, invalid, or audit_required.
nameTrader / company name returned by EOS or HMRC (if public).
addressTrader address returned by EOS or HMRC (if public).
checked_atISO 8601 timestamp.
GET
/account

Get account stats and the current audit and VAT-validation quotas.

Response:

FieldDescription
plan, plan_labelCurrent plan.
audit_limit, audit_limit_periodStored audit-proof limit and its month or lifetime period; null means unlimited.
audit_requests_used, audit_requests_remainingStored audit-proof usage and remaining capacity for the active period.
monthly_limit, requests_remainingBackward-compatible aliases for audit limit and remaining capacity.
requests_totalTotal audits across all time.
requests_this_monthOn-demand audits counted toward this month's quota. Scheduled monitoring refreshes are included with monitoring and do not consume this quota.
requests_remainingAudits still available in the plan's audit period.
validation_monthly_limit, validation_remaining_this_monthVAT-validation capacity for the current month.
validation_rate_limit, validation_rate_windowLive-validation rate limit (e.g. 10/min, 20/min, 30/min, or 10/hr) and active window (minute or hour).
validation_requests_this_window, validation_remaining_this_windowLive-validation count and remaining capacity in the active window.
validation_hourly_limit, validation_remaining_this_hourBackward-compatible live-validation capacity for the current hour.
upgrade_urlLink to change plan.
POST
/audits

Create a new compliance verification audit. Supports VAT (default, 1 credit), EORI (1 credit), and hybrid VAT+EORI (2 credits). Validates via VIES, EU EOS, HMRC, or supported national registries. Serbian VAT audits use the Serbian Tax Administration VAT Register, record its company name and address, and generate a separate Serbian PDF certificate for confirmed active registrations. If an official source is unavailable, the audit is queued for retry.

Body (JSON):

FieldRequirement and description
type(opțional) — vat (default, 1 credit), eori (1 credit), or vat_eori (hybrid audit, 2 credits). Legacy alias audit_type is also supported.
vat_numberRequired for vat and vat_eori — VAT number with or without country prefix. Serbia accepts a 9-digit PIB with the RS prefix, the SRB input alias, or country_code=RS. Swiss MWST, TVA, and IVA suffixes are normalized.
eori_numberRequired for eori, optional for vat_eori — Full EORI number (e.g. GB123456789000 or DE123456789012345).
country_code(opțional) — 2-letter ISO code when vat_number or eori_number has no prefix.
requester_vat(opțional) — Requester VAT. If omitted, the primary profile VAT is used.
company_name(opțional) — Company name; VIESAC AI can fill it when empty.
company_address(opțional) — Company address; VIESAC AI can fill it when empty.
order_number(opțional) — Your order reference.
invoice_number(opțional) — Your invoice reference.
comment(opțional) — Free-form note.
monitoring(opțional) — false, day, week, month, quarter, or year.
audit_details(opțional) — Client-owned structured metadata. It is stored separately from VIESAC processing diagnostics and echoed unchanged in audit responses.
method(opțional) — api, woocommerce, magento, or make.
PUT
/audits/{reference_number}

Update an audit by reference number. You can update order_number, invoice_number, comment, and monitoring. Changes are recorded in the audit log. If the reference is not found for your account, returns 404 with an error message.

Body (JSON):

FieldDescription
order_number(opțional) — Order reference.
invoice_number(opțional) — Invoice reference.
comment(opțional) — Free-form note.
monitoring(opțional) — false to disable, or day, week, month, quarter, year to set frequency.

404 if reference not found: {"error":"No audit found for this reference number."}

GET
/partners/check

Check partner(s) by VAT number or company name. Returns one row per company (latest audit per country+VAT) with name, VAT, address, last status, last check date, and if monitoring is enabled: frequency and next check date.

Query params:

FieldRequirement and description
q(obligatoriu) — VAT (e.g. DE123456789) or a partial company name.

Response:

FieldDescription
dataPartner objects with company, VAT, address, latest status, last check, and optional monitoring details.
countNumber of partners found.
GET
/audits

List audits with filters. Default limit 100, max 500. By default returns VAT audits only.

Query params:

FieldDescription
type(opțional) — Filter by type: vat (default), eori, vat_eori, or all.
limitNumber of results, default 100, maximum 500.
date_fromStart date in YYYY-MM-DD format.
date_toEnd date in YYYY-MM-DD format.
vat_numberPartial search by VAT number.
eori_numberPartial search by EORI number.
order_numberPartial search.
invoice_numberPartial search.
country_codeExact match, for example DE.
GET
/audits/{reference_number}

Get client-safe details of a single audit, including certificate links, client metadata and normalized verification_evidence. Internal routing and diagnostics are never returned by the client API.

Path params:

FieldRequirement and description
reference_number(obligatoriu) — Unique audit reference code (e.g. VAC-20260216-ABC123).

Response fields:

FieldDescription
reference_numberUnique immutable audit reference string.
typeAudit type: vat, eori, or vat_eori (hybrid). Also mirrored in legacy audit_type.
country_code2-letter ISO country code of the verified entity.
vat_numberVerified VAT number without prefix (null for pure EORI audits).
formatted_vat_numberFormatted VAT number with standard national spacing.
statusOverall audit result: valid, invalid, limited_valid, pending, or error.
validBoolean indicating if the audit is confirmed valid (true / false).
vat_status, vat_validSpecific VAT verification status and boolean validity.
eori_country_code, eori_numberEORI country and number (for eori and vat_eori audits).
eori_status, eori_validSpecific EORI verification status and boolean validity.
viesOfficial registry flag: 1 = valid certificate; 0 = negative/error; 2 = VIES unavailable (retry pending).
official_sourceAuthoritative validation registry (e.g. VIES, EU_EOS, HMRC, SWISS_UID, BRREG).
company_nameTrader / company name registered with the authority.
company_addressTrader / company registered legal address.
consultation_numberOfficial consultation / confirmation code issued by the authority (if supported).
consultation_number_statusStatus of consultation number: confirmed, pending_retry, or not_available.
requester_vatVAT number of the requesting business profile.
order_number, invoice_numberYour internal order and invoice references.
customs_declaration_numberCustoms declaration reference (e.g. ATLAS, CHIEF, CDS).
commentCustom free-form note stored with the audit.
audit_detailsClient-owned structured metadata echoed back unchanged.
verification_evidenceStructured client-safe verification evidence containing raw official response signatures and timestamps.
methodSubmission channel: api, woocommerce, magento, make, or microsoft.
requested_atISO 8601 timestamp when the verification was executed.
certificate_urlDirect public verification link for the PDF certificate (for valid status).
certificate_xml_urlDirect link for normalized XML evidence (for valid status).
eori_certificate_url, eori_certificate_xml_urlDirect EORI PDF and XML certificate links (for hybrid vat_eori audits).
certificatesStructured map with separate vat and eori certificate objects containing status, pdf_url, and xml_url.

404 if reference not found: {"error":"No audit found for this reference number."}

GET
/audits/{reference_number}/certificate

Download the official compliance verification certificate as a binary PDF. Protected with Bearer authentication. Only available for audits with valid status.

Path params:

FieldRequirement and description
reference_number(obligatoriu) — Unique audit reference code (e.g. VAC-20260216-ABC123).

Query params:

FieldRequirement and description
locale(opțional) — Certificate language. Default is en. Supported: en, de, fr, it, es, pl, nl, ro, gr, cz, sv, hu, pt, bg, da, no, fi, sk, hr, lt, sl, lv, et.
type(opțional) — For hybrid audits (vat_eori), specify type=eori to download the EORI certificate (defaults to VAT). You can also use the dedicated route /audits/{reference_number}/certificate/eori.

Response:

Field / HeaderDescription
Content-Typeapplication/pdf
Content-Dispositionattachment; filename="viesac_certificate_{reference_number}.pdf"
BodyBinary PDF file stream containing the cryptographic timestamp, QR code, and official evidence.

404 if not found or not valid: {"error":"Certificate is not available for this audit. Only audits with VALID status have certificates."}

GET
/audits/{reference_number}/certificate/xml

Download a normalized, client-safe XML verification record for ERP ingestion, archiving, and tax authority audits. Contains official response timestamps, signature hashes, and consultation data while excluding internal routing diagnostics. Available for valid status only.

Path params:

FieldRequirement and description
reference_number(obligatoriu) — Unique audit reference code (e.g. VAC-20260216-ABC123).

Query params:

FieldRequirement and description
type(opțional) — For hybrid audits (vat_eori), specify type=eori to download the EORI XML evidence (defaults to VAT). You can also use the dedicated route /audits/{reference_number}/certificate/eori/xml.

Response:

Field / HeaderDescription
Content-Typeapplication/xml
Content-Dispositionattachment; filename="viesac_verification_evidence_{country}_{number}_{timestamp}.xml"
BodyNormalized XML document including <audit>, <requester>, <trader>, and <official_evidence> elements.

404 if not found or not valid: {"error":"Certificate is not available for this audit. Only audits with VALID status have certificates."}

Audit responses include type, verification_evidence, client-owned audit_details, certificate_url, certificate_xml_url, and certificate_urls. For hybrid audits (vat_eori), responses include dual certificate links (eori_certificate_url, eori_certificate_xml_url, and a structured certificates object with separate vat and eori blocks).

Interpret audit results

FieldMeaning
statusvalid (VIES confirmed), limited_valid (fallback), pending, invalid, or error.
vies1 = valid certificate; 0 = negative/error; 2 = VIES unavailable and the audit will update later.
GET
/rates  and  /rates/{country}
⚡ Free & Unlimited (requires API key, 0 quota)

Retrieve official standard, reduced, super-reduced, parking, regional, and special VAT rates across supported countries. Supports aliases (/vat-rates, /vat-rates/{country}), autonomous territories (Canary Islands, Azores, Madeira, Corsica), and conditional HTTP caching (ETag / 304 Not Modified). Requires a free API key (Authorization: Bearer <your_api_key>); does not consume plan quota on any plan (unlimited).

Headers:

HeaderRequirement and description
AuthorizationRequired — Bearer <your_api_key>. Available on all plans for free without quota deduction.

Path params (optional):

FieldRequirement and description
country(opțional) — ISO 3166-1 alpha-2 country code (e.g. DE, FR, ES). Case-insensitive and supports aliases (EL → GR, UK → GB).

Query params:

FieldRequirement and description
country(opțional) — Filter by one or more comma-separated country codes (e.g. ?country=DE or ?country=DE,FR,ES).
eu_only(opțional) — Set to true or 1 to return only the 27 EU Member States (excludes GB, NO, CH).

404 when every requested country code is unknown: {"status":"error","code":"country_not_found"}. A mix such as DE,ZZ returns the known countries. The same 404 applies to /rates/{country}.

Response headers & caching:

HeaderDescription
Cache-Controlpublic, max-age=86400, stale-while-revalidate=3600
ETagUnique entity tag for conditional caching. Send via If-None-Match to receive a lightweight 304 Not Modified.

Response fields:

FieldDescription
country_codeISO 3166-1 alpha-2 code (e.g. DE).
country_nameOfficial English country name (e.g. Germany).
tax_name / tax_abbrOfficial local name and abbreviation (e.g. Mehrwertsteuer / Umsatzsteuer / MwSt, TVA, IVA).
is_eu_memberBoolean flag (true for 27 EU countries, false for GB, NO, CH). Useful for OSS and reverse-charge rules.
currencyNational currency code (e.g. EUR, GBP, CHF, PLN, CZK, NOK).
standard_rateStandard VAT rate (e.g. 19.0, 20.0, 21.0).
reduced_rate / reduced_ratesPrimary reduced rate and full array of reduced rates.
super_reduced_rateSuper-reduced rate where applicable (e.g. France 2.1, Spain 4.0, Luxembourg/Cyprus 3.0) or null.
parking_rateTransitional parking rate (e.g. Luxembourg 14.0, Malta 12.0) or null.
ratesItemized array of rates with type, category (food, books, accommodation, transport), and human-readable description.
special_territoriesAutonomous or overseas territories (Canary Islands IGIC, Ceuta/Melilla IPSI, Azores, Madeira, Corsica, DOM, Aegean border islands).
verified_at / source_urlVerification timestamp and link to official EU / national tax authority source.

API request and response examples

Each example pairs a complete request with the response shape your code or agent should expect.

Dark blocks are requests. Select the language you use, then copy the full example.

Light blocks are JSON responses. Treat values shown as examples, not fixed production data.

1. Quick VAT Validate — GET /validate

Instantly check if a VAT number is valid without creating an audit. Powered by VIESAC multi-source intelligence combining VIES, supported national registries, VIESAC SmartRouter™, VIESAC SmartCache™, and VIESAC AI Engine.

For quick lookups only — no audit record is stored. For a full, legally reliable verification with a timestamped certificate, use POST /audits.

curl -X GET "https://viesac.eu/api/v1/validate?vat=DE123456789" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200) — VAT is valid:

{
  "vat": "DE123456789",
  "country_code": "DE",
  "vat_number": "123456789",
  "status": "valid",
  "checked_at": "2026-03-16T12:00:00+00:00"
}

Response (200) — VAT is not valid:

{
  "vat": "DE000000000",
  "country_code": "DE",
  "vat_number": "000000000",
  "status": "invalid",
  "checked_at": "2026-03-16T12:00:00+00:00"
}

Response (200) — Audit required (VIES unavailable and no fallback result):

{
  "vat": "DE123456789",
  "country_code": "DE",
  "vat_number": "123456789",
  "status": "audit_required",
  "checked_at": "2026-03-16T12:00:00+00:00",
  "code": "audit_required",
  "next_step": "create_audit",
  "create_audit_url": "https://viesac.eu/app/vat-validation",
  "docs_url": "https://viesac.eu/api-docs"
}

Rate limit response (429):

{
  "error": "VAT validation limit exceeded. Your current plan allows 10 live VAT validations per hour.",
  "code": "rate_limit_exceeded",
  "limit": 10,
  "window": "1 hour",
  "retry_after": 1800,
  "upgrade_url": "https://viesac.eu/app/payment"
}

Monthly validation limit response (429):

{
  "error": "Monthly VAT validation limit exceeded. Your current plan allows 100 VAT validations per month.",
  "code": "monthly_validation_limit_exceeded",
  "limit": 100,
  "window": "1 month",
  "upgrade_url": "https://viesac.eu/app/payment"
}

2. Quick EORI Validate — GET /eori/validate

Instantly check if an EORI number is valid across the EU (via European Commission EOS) and UK (via HMRC) without creating an audit.

For quick lookups only — no audit record is stored. For a full, legally reliable verification with a timestamped certificate, use POST /audits with type="eori" or hybrid type="vat_eori".

curl -X GET "https://viesac.eu/api/v1/eori/validate?eori=GB123456789000" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200) — EORI is valid:

{
  "eori": "GB123456789000",
  "country_code": "GB",
  "eori_number": "123456789000",
  "status": "valid",
  "name": "Example Logistics Ltd",
  "address": "1 Customs Way, Dover",
  "checked_at": "2026-03-16T12:00:00+00:00"
}

Response (200) — EORI is invalid:

{
  "eori": "GB000000000000",
  "country_code": "GB",
  "eori_number": "000000000000",
  "status": "invalid",
  "name": null,
  "address": null,
  "checked_at": "2026-03-16T12:00:00+00:00"
}

3. Get account — GET /account

Get plan and audit statistics.

curl -X GET "https://viesac.eu/api/v1/account" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200):

{
  "plan": "FREE",
  "plan_label": "Free",
  "audit_limit": 5,
  "audit_limit_period": "lifetime",
  "audit_requests_used": 1,
  "audit_requests_remaining": 4,
  "monthly_limit": 5,
  "requests_total": 4,
  "requests_this_month": 1,
  "requests_remaining": 4,
  "validation_monthly_limit": 100,
  "validation_requests_this_month": 24,
  "validation_remaining_this_month": 76,
  "validation_rate_limit": 10,
  "validation_rate_window": "hour",
  "validation_requests_this_window": 4,
  "validation_remaining_this_window": 6,
  "validation_hourly_limit": 10,
  "validation_requests_this_hour": 4,
  "validation_remaining_this_hour": 6,
  "upgrade_url": "https://viesac.eu/app/payment"
}

4. Create audit — POST /audits

Create a new compliance verification audit. Set type to "vat" (default, 1 credit), "eori" (1 credit), or "vat_eori" (hybrid audit, 2 credits). Returns the audit object (201).

curl -X POST "https://viesac.eu/api/v1/audits" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"vat_eori","country_code":"DE","vat_number":"123456789","eori_number":"DE123456789012345","order_number":"ORD-001"}'

Response (201) — Hybrid VAT+EORI audit with dual certificates:

{
  "reference_number": "VAC-20260216-ABC123",
  "type": "vat_eori",
  "country_code": "DE",
  "vat_number": "123456789",
  "eori_number": "DE123456789012345",
  "status": "valid",
  "vies": 1,
  "eori_status": "valid",
  "company_name": "Example GmbH",
  "company_address": "Example Str. 1\n10115 Berlin",
  "consultation_number": "12345678901234",
  "order_number": "ORD-001",
  "certificate_url": "https://viesac.eu/cert/...?locale=en",
  "certificate_xml_url": "https://viesac.eu/cert/.../xml",
  "eori_certificate_url": "https://viesac.eu/cert/eori/...",
  "eori_certificate_xml_url": "https://viesac.eu/cert/eori/.../xml",
  "certificates": {
    "vat": {
      "pdf_url": "https://viesac.eu/cert/...?locale=en",
      "xml_url": "https://viesac.eu/cert/.../xml"
    },
    "eori": {
      "pdf_url": "https://viesac.eu/cert/eori/...",
      "xml_url": "https://viesac.eu/cert/eori/.../xml"
    }
  },
  "requested_at": "2026-02-13T12:00:00.000000Z"
}

5. List audits — GET /audits

List audits with filters. Query params: type (vat default, eori, vat_eori, all), vat_number, eori_number, country_code, date_from, date_to, limit.

curl -X GET "https://viesac.eu/api/v1/audits?limit=50&country_code=DE&date_from=2026-02-01" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200):

{
  "data": [
    {
      "reference_number": "VAC-20260216-ABC123",
      "country_code": "DE",
      "vat_number": "123456789",
      "status": "valid",
      "company_name": "Example GmbH",
      "requested_at": "2026-02-13T12:00:00.000000Z",
      ...
    }
  ],
  "count": 1
}

6. Get audit — GET /audits/{reference_number}

Get full details of a single audit by its reference number.

curl -X GET "https://viesac.eu/api/v1/audits/VAC-20260216-ABC123" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200):

{
  "reference_number": "VAC-20260216-ABC123",
  "type": "vat",
  "country_code": "DE",
  "vat_number": "123456789",
  "status": "valid",
  "vies": 1,
  "company_name": "Example GmbH",
  "company_address": "Example Str. 1\n10115 Berlin",
  "consultation_number": "12345678901234",
  "certificate_url": "https://viesac.eu/cert/...?locale=en",
  "certificate_xml_url": "https://viesac.eu/cert/.../xml",
  "certificate_urls": {"pdf_en":"...","pdf_locale":"...","xml":"..."},
  "requested_at": "2026-02-13T12:00:00.000000Z"
}

404 if reference not found: {"error":"No audit found for this reference number."}

7. Update audit — PUT /audits/{reference_number}

Update order number, invoice number, comment, or monitoring for an existing audit. Changes are logged.

curl -X PUT "https://viesac.eu/api/v1/audits/VAC-20260216-ABC123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"order_number":"ORD-002","comment":"Updated via API"}'

Response (200): same shape as GET /audits/{reference_number}. 404 if reference not found.

8. Check partner — GET /partners/check?q=

Search by VAT (e.g. DE123456789) or company name. Returns full list per company with last status, last check date, and monitoring info if set.

curl -X GET "https://viesac.eu/api/v1/partners/check?q=DE123456789" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200):

{
  "data": [
    {
      "company_name": "Example GmbH",
      "vat": "DE123456789",
      "country_code": "DE",
      "vat_number": "123456789",
      "address": "Example Str. 1\n10115 Berlin",
      "last_status": "valid",
      "last_check_date": "2026-02-13T12:00:00.000000Z",
      "monitoring": { "frequency": "month", "next_check_at": "2026-03-13T12:00:00.000000Z" }
    }
  ],
  "count": 1
}

If no partners match: data is [], count is 0, and message is included.

9. Download PDF certificate — GET /audits/{reference_number}/certificate

Download PDF certificate. Query: ?locale=en|de|fr. For hybrid audits, pass ?type=eori (or use /certificate/eori) to download the EORI certificate. Available only when status is VALID.

curl -X GET "https://viesac.eu/api/v1/audits/VAC-20260216-ABC123/certificate?locale=en" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o certificate.pdf

Response (200):

Binary PDF file (Content-Type: application/pdf).

404 if reference not found or status not VALID: {"error":"Certificate is not available for this audit. Only audits with VALID status have certificates."}

10. Download XML certificate — GET /audits/{reference_number}/certificate/xml

Download technical certificate XML evidence. For hybrid audits, pass ?type=eori (or use /certificate/eori/xml) to download the EORI evidence. Available only when status is VALID.

curl -X GET "https://viesac.eu/api/v1/audits/VAC-20260216-ABC123/certificate/xml" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o certificate.xml

Response (200):

XML content (Content-Type: application/xml).

404 if reference not found or status not VALID: same error as PDF endpoint.

11. VAT Rates — GET /rates or /rates/{country}

⚡ Free & Unlimited (requires API key, 0 quota)

Query official VAT rates for all supported countries or a single country. Free and unlimited across all plans, requiring a free API key (0 quota deduction). Supports filtering by ?country=DE,FR or ?eu_only=true, as well as conditional HTTP caching (ETag / 304 Not Modified).

# 1. Fetch all rates
curl -X GET "https://viesac.eu/api/v1/rates" \
  -H "Authorization: Bearer YOUR_API_KEY"

# 2. Query a specific country (e.g. Germany)
curl -X GET "https://viesac.eu/api/v1/rates/DE" \
  -H "Authorization: Bearer YOUR_API_KEY"

# 3. Filter specific countries with EU-only flag
curl -X GET "https://viesac.eu/api/v1/rates?country=DE,FR,ES&eu_only=true" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200 OK):

{
  "status": "success",
  "count": 30,
  "verified_at": "2026-09-16",
  "data": {
    "DE": {
      "country_code": "DE",
      "country_name": "Germany",
      "tax_name": "Mehrwertsteuer / Umsatzsteuer",
      "tax_abbr": "MwSt",
      "is_eu_member": true,
      "currency": "EUR",
      "standard_rate": 19.0,
      "reduced_rate": 7.0,
      "reduced_rates": [7.0],
      "super_reduced_rate": null,
      "parking_rate": null,
      "rates": [
        {
          "rate": 19.0,
          "type": "standard",
          "category": null,
          "description": "Standard VAT rate applicable to most taxable goods and services"
        },
        {
          "rate": 7.0,
          "type": "reduced",
          "category": null,
          "description": "Reduced VAT rate applicable to qualifying supplies"
        }
      ],
      "special_territories": [
        {
          "region": "Heligoland and Büsingen",
          "tax_name": "Exempt",
          "standard_rate": 0.0,
          "is_eu_vat_territory": false,
          "note": "Excluded from EU VAT territory under Article 6 of Directive 2006/112/EC."
        }
      ],
      "valid_from": null,
      "verified_at": "2026-09-16",
      "source_url": "https://europa.eu/youreurope/business/finance-and-tax/vat/vat-rules-rates/index_en.htm"
    },
    "ES": {
      "country_code": "ES",
      "country_name": "Spain",
      "tax_name": "Impuesto sobre el Valor Añadido",
      "tax_abbr": "IVA",
      "is_eu_member": true,
      "currency": "EUR",
      "standard_rate": 21.0,
      "reduced_rate": 10.0,
      "reduced_rates": [10.0],
      "super_reduced_rate": 4.0,
      "parking_rate": null,
      "special_territories": [
        {
          "region": "Canary Islands (Islas Canarias)",
          "tax_name": "IGIC (Impuesto General Indirecto Canario)",
          "standard_rate": 7.0,
          "reduced_rates": [0.0, 3.0],
          "increased_rates": [9.5, 15.0],
          "is_eu_vat_territory": false,
          "note": "Excluded from EU VAT territory under Article 6 of Directive 2006/112/EC. Local IGIC applies."
        }
      ],
      "valid_from": null,
      "verified_at": "2026-09-16",
      "source_url": "https://europa.eu/youreurope/business/finance-and-tax/vat/vat-rules-rates/index_en.htm"
    }
  }
}

VIESAC API webhooks

Webhooks are optional. When enabled for an API key, VIESAC will send HTTP POST callbacks to your URL when an audit is created and when its status changes.

Events

  • audit.created — sent right after POST /audits creates an audit.
  • audit.pending — status became pending or limited_valid.
  • audit.completed — status became valid, invalid, or error.
  • audit.failed — status became error.

Payload

Each delivery includes an event envelope plus data shaped like GET /audits/{reference_number}.

{
  "id": 123,
  "event": "audit.completed",
  "attempt": 1,
  "created_at": "2026-03-31T12:00:00+00:00",
  "data": {
    "reference_number": "VAC-20260216-ABC123",
    "country_code": "DE",
    "vat_number": "123456789",
    "status": "valid",
    "vies": 1,
    "company_name": "Example GmbH",
    "company_address": "Example Str. 1\n10115 Berlin",
    "consultation_number": "12345678901234",
    "certificate_url": "https://viesac.eu/cert/...?locale=en",
    "certificate_xml_url": "https://viesac.eu/cert/.../xml",
    "certificate_urls": {"pdf_en":"...","pdf_locale":"...","xml":"..."},
    "requested_at": "2026-02-13T12:00:00+00:00"
  },
  "meta": { "from_status": "pending", "to_status": "valid" }
}

Security (HMAC signature)

Each request is signed. Verify the signature before processing.

HeaderDescription
X-Viesac-EventEvent name.
X-Viesac-DeliveryUnique delivery id.
X-Viesac-TimestampUnix timestamp used in the signature.
X-Viesac-Signaturesha256=<hex> from HMAC-SHA256(secret, timestamp + '.' + raw_body).
// Pseudocode
expected = HMAC_SHA256(secret, timestamp + "." + rawBody)
constantTimeEquals("sha256=" + expected, signatureHeader)

Retries

If delivery fails due to timeouts or 5xx/429, VIESAC retries with backoff:

  1. 15 minutes
  2. 230 minutes
  3. 33 hours
  4. 46 hours
  5. 524 hours

Hard failures (most 4xx) disable webhooks temporarily to prevent queue buildup.