API Documentation
REST API for VAT validation audits. All requests require Bearer authentication. Register for API key.
Authentication
Use your API key in the Authorization header with the Bearer scheme:
Authorization: Bearer viesac_your_api_key
Never expose your API key in client-side code or public repositories.
Base URL
All endpoints are relative to:
https://viesac.eu/api/v1
Endpoints
/validate
Quick VAT status check — does not create an audit. Powered by VIESAC multi-source intelligence: VIES (European Commission), 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:
vat(privaloma) — Full VAT including country prefix (e.g.DE123456789)
Response fields:
vat— Full VAT (country + number)country_code— Country code (e.g.DE)vat_number— VAT number without country prefixstatus— Validation result:valid,invalid, oraudit_requiredchecked_at— ISO 8601 timestamp
Rate limits
Free plan: 10 requests / hour
Paid plans: rate limits depend on your plan tier.
Exceeded: HTTP 429 with retry_after (seconds) and upgrade_url.
/account
Get account stats: plan, total audits, audits this month, remaining this month.
Response:
plan,plan_label— Current planmonthly_limit— Monthly limit (null = unlimited)requests_total— Total audits (all time)requests_this_month— Audits this monthrequests_remaining— Available this monthupgrade_url— Link to upgrade plan
/audits
Create a new VAT validation audit. Validates via VIES. If VIES is down, VIESAC AI validates with proprietary data; the audit waits for VIES to return and retrieves full data plus the official certificate.
Body (JSON):
vat_number(privaloma) — VAT number (with or without country prefix; system normalizes automatically)country_code(neprivaloma) — 2-letter ISO (e.g. DE, FR). Enter ifvat_numberis without prefix.requester_vat(neprivaloma) — Requester VAT (e.g. DE123456789). If omitted, your primary VAT is used. If provided and already in your profile, that one is used; if new, it is created in your profile and used.company_name(neprivaloma) — Company name. If empty, VIESAC AI fills it in.company_address(neprivaloma) — Company address. If empty, VIESAC AI fills it in.order_number(neprivaloma) — Your order reference if this validation is linked to an order.invoice_number(neprivaloma) — Your invoice reference if this validation is linked to an invoice.comment(neprivaloma)monitoring(neprivaloma) — Enable re-check monitoring for this partner:false(no monitoring),day,week,month,quarter,year. When set, the partner is added or updated in monitoring with the next check date.audit_details(neprivaloma) — Your data in a convenient format (e.g. XML, JSON, CSV). We detect the format and display it in the audit details.method(neprivaloma) — Source:api(default),woocommerce,magento,make. Used for analytics. If omitted and the request User-Agent contains "Make" or "Integromat",makeis set automatically.
/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):
order_number(neprivaloma) — Order referenceinvoice_number(neprivaloma) — Invoice referencecomment(neprivaloma)monitoring(neprivaloma) —falseto disable monitoring for this partner, orday,week,month,quarter,yearto set frequency.
404 if reference not found: {"error":"No audit found for this reference number."}
/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:
q(privaloma) — VAT (e.g. DE123456789) or company name (partial match)
Response:
data— Array of objects:company_name,vat,country_code,vat_number,address,last_status,last_check_date,monitoring(null or{ "frequency": "month", "next_check_at": "..." })count— Number of partners found
/audits
List audits with filters. Default limit 100, max 500.
Query params:
limit— Number of results (default 100)date_from— YYYY-MM-DDdate_to— YYYY-MM-DDvat_number— Partial searchorder_number— Partial searchinvoice_number— Partial searchcountry_code— Exact match (e.g. DE)
/audits/{reference_number}
Get full details of a single audit, including certificate_url and details_url.
/audits/{reference_number}/certificate
Download PDF certificate. Returns binary PDF with Bearer auth.
?locale= (neprivaloma) — Certificate language: en (default), de, fr. Example: /audits/VAC-20260216-ABC123/certificate?locale=de
/audits/{reference_number}/certificate/xml
Download technical certificate (XML). Original VIES checkVatResponse. Available for VALID status only.
Audit response includes certificate_url, certificate_xml_url, and certificate_urls (public links, no auth): pdf_en, pdf_locale (from Accept-Language), xml — when status is VALID.
Status & vies
status: valid (VIES confirmed), limited_valid (VIESAC VALID — fallback when VIES unavailable), pending (no data yet), invalid (negative), error.
vies: 1 = VIES VALID (certificate), 0 = negative/error, 2 = VIES unavailable — audit awaits VIES response; when received, status updates automatically.
Examples
Each endpoint shows request and response together.
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, 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": "Rate limit exceeded. Free plan allows 10 VAT validations per hour. Upgrade your plan for higher limits.",
"code": "rate_limit_exceeded",
"limit": 10,
"window": "1 hour",
"retry_after": 1800,
"upgrade_url": "https://viesac.eu/app/payment"
}
2. 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",
"monthly_limit": 15,
"requests_total": 120,
"requests_this_month": 12,
"requests_remaining": 38,
"upgrade_url": "https://viesac.eu/app/payment"
}
3. Create audit — POST /audits
Create a new VAT validation. 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 '{"country_code":"DE","vat_number":"123456789","order_number":"ORD-001"}'Response (201):
{
"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",
"order_number": "ORD-001",
"certificate_url": "https://viesac.eu/cert/...?locale=en",
"certificate_xml_url": "https://viesac.eu/cert/.../xml",
"requested_at": "2026-02-13T12:00:00.000000Z",
...
}
4. List audits — GET /audits
List audits with filters. Query params: limit, date_from, date_to, country_code, vat_number, order_number, invoice_number.
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
}
5. 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",
"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."}
6. 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.
7. 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.
8. Download PDF certificate — GET /audits/{reference_number}/certificate
Download PDF certificate. Query: ?locale=en|de|fr. 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.pdfResponse (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."}
9. Download XML certificate — GET /audits/{reference_number}/certificate/xml
Download technical certificate (VIES checkVatResponse). 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.xmlResponse (200):
XML content (Content-Type: application/xml).
404 if reference not found or status not VALID: same error as PDF endpoint.
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 afterPOST /auditscreates an audit.audit.pending— status becamependingorlimited_valid.audit.completed— status becamevalid,invalid, orerror.audit.failed— status becameerror.
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.
X-Viesac-Event: event name
X-Viesac-Delivery: delivery id
X-Viesac-Timestamp: unix timestamp
X-Viesac-Signature: sha256=<hex> of 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:
- 5 minutes
- 30 minutes
- 3 hours
- 6 hours
- 24 hours
Hard failures (most 4xx) disable webhooks temporarily to prevent queue buildup.