{ "openapi": "3.0.0", "info": { "title": "VAT API v1", "description": "API for VAT UID validation, state retrieval, history, and search.", "contact": { "email": "support@theconcept-technologies.com" }, "version": "1.0.0" }, "servers": [ { "url": "https://api.taxora.io/v1", "description": "VAT API Server" } ], "paths": { "/v1/login": { "post": { "tags": [ "Authentication" ], "summary": "User Login", "description": "Authenticates the user and returns an access token.", "operationId": "8c0c5721bd4d6c49920dd516eaee6637", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "password" ], "properties": { "email": { "description": "User email address. Required when client_id is not provided.", "type": "string", "format": "email", "example": "user@example.com" }, "client_id": { "description": "API user identifier. Required when email is not provided.", "type": "string", "example": "client_abc123" }, "password": { "description": "User password or client secret", "type": "string", "format": "password", "example": "password123" } }, "type": "object" } } } }, "responses": { "200": { "description": "Successful login", "content": { "application/json": { "schema": { "properties": { "access_token": { "description": "Access token for authenticated requests", "type": "string", "example": "" }, "token_type": { "description": "Token type", "type": "string", "example": "Bearer" }, "expires_in": { "description": "Token expiration time in seconds", "type": "integer", "example": 3600 } }, "type": "object" } } } }, "400": { "description": "Validation error" }, "401": { "description": "Unauthorized - Invalid credentials" }, "500": { "description": "Internal Server Error" } } } }, "/v1/refresh": { "post": { "tags": [ "Authentication" ], "summary": "Refresh Access Token", "description": "Deletes the existing token and generates a new one.", "operationId": "994ecc43ada29d9ee73b66d721be1a5d", "responses": { "200": { "description": "Successful token refresh", "content": { "application/json": { "schema": { "properties": { "access_token": { "description": "New access token", "type": "string", "example": "" }, "token_type": { "description": "Token type", "type": "string", "example": "Bearer" }, "expires_in": { "description": "Token expiration time in seconds", "type": "integer", "example": 3600 } }, "type": "object" } } } }, "401": { "description": "Unauthorized" }, "500": { "description": "Internal Server Error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/billing/usage-summaries": { "get": { "tags": [ "Billing" ], "summary": "List billing usage summaries for the authenticated company", "operationId": "63940a1d555f3b8efac02886131c727c", "parameters": [ { "name": "per_page", "in": "query", "description": "Page size (1-100, default 25)", "required": false, "schema": { "type": "integer", "default": 25, "maximum": 100, "minimum": 1 } } ], "responses": { "200": { "description": "Paginated list of usage summaries (newest billing periods first)", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/UsageSummary" } }, "meta": { "properties": { "current_page": { "type": "integer", "example": 1 }, "per_page": { "type": "integer", "example": 25 }, "total": { "type": "integer", "example": 12 }, "last_page": { "type": "integer", "example": 1 } }, "type": "object" } }, "type": "object" } }, "type": "object" } } } } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/billing/usage-summaries/{period}": { "get": { "tags": [ "Billing" ], "summary": "Get the usage summary detail (with events) for a given billing period", "operationId": "61ac09345829140434602272f839d6da", "parameters": [ { "name": "period", "in": "path", "description": "Billing period in YYYY-MM (e.g. 2026-09)", "required": true, "schema": { "type": "string", "pattern": "^\\d{4}-(0[1-9]|1[0-2])$" } } ], "responses": { "200": { "description": "Summaries with nested events for the period" }, "400": { "description": "Invalid period format" }, "404": { "description": "No summaries found for this period" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/v1/company": { "get": { "tags": [ "Company" ], "summary": "Get the authenticated user's company", "description": "Returns the company information for the authenticated user", "operationId": "3d4a674ad6e3a7edcfb85a62eae8016c", "responses": { "200": { "description": "Company retrieved successfully", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/CompanyResource" } }, "type": "object" } } } }, "401": { "description": "Not authorized" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/company/current-api-group": { "get": { "tags": [ "Company" ], "summary": "Get current API request group", "operationId": "2ce5991ac2d2f1808176dd7d6f16621c", "parameters": [ { "name": "environment", "in": "query", "description": "Filter by environment (default: LIVE)", "required": false, "schema": { "type": "string", "enum": [ "LIVE", "SANDBOX" ], "example": "SANDBOX" } } ], "responses": { "200": { "description": "Current API request group retrieved" }, "401": { "description": "Not authorized" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/compliance/enrollments": { "get": { "tags": [ "Compliance" ], "summary": "List compliance enrollments for the authenticated company", "operationId": "da61a10cf950be1ac0c38da68c333f90", "parameters": [ { "name": "per_page", "in": "query", "description": "Page size (1-100, default 25)", "required": false, "schema": { "type": "integer", "default": 25, "maximum": 100, "minimum": 1 } } ], "responses": { "200": { "description": "Paginated list of enrollments", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/ComplianceEnrollment" } }, "meta": { "properties": { "current_page": { "type": "integer", "example": 1 }, "per_page": { "type": "integer", "example": 25 }, "total": { "type": "integer", "example": 3 }, "last_page": { "type": "integer", "example": 1 } }, "type": "object" } }, "type": "object" } }, "type": "object" } } } } }, "security": [ { "ApiKeyAuth": [] } ] }, "post": { "tags": [ "Compliance" ], "summary": "Enroll a country (e-reporting or e-invoicing) and provision the provider account", "description": "Books one service for one country. Creates the local enrollment, then the B2Brouter account, then (by default) activates the country regime: the DGFiP tax report setting for France, the Peppol registration for Norway (EHF). Required fields depend on `country`: France needs siret/siren + DGFiP data, Norway needs org_number, company_name, address, city, postalcode. The company must have the matching service unlocked (403 `service_not_active` otherwise). Countries with a setup fee are billed once when the regime is activated. On provider failure the local enrollment is persisted in `error_account`/`error_activation` state for retries.", "operationId": "30232ed599e4168744843cd3c6d6eef3", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "email" ], "properties": { "country": { "type": "string", "default": "FR", "enum": [ "FR", "NO" ] }, "service": { "description": "Defaults to e_reporting where available (FR), otherwise the country's only service (NO: e_invoicing)", "type": "string", "enum": [ "e_reporting", "e_invoicing" ] }, "org_number": { "description": "NO only: 9-digit Norwegian organisation number (also the Peppol id, scheme 0192)", "type": "string", "example": "923609016" }, "vat_registered": { "description": "NO only: registered in the Norwegian VAT register (MVA)", "type": "boolean", "default": true }, "enterprise_register": { "description": "NO only: registered in Foretaksregisteret — adds the mandatory 'Foretaksregisteret' note to invoices", "type": "boolean", "default": false }, "reception": { "description": "NO only: also register to RECEIVE e-invoices over Peppol", "type": "boolean", "default": false }, "siret": { "description": "14-digit SIRET — required if siren missing", "type": "string", "example": "12345678900012" }, "siren": { "description": "9-digit SIREN — required if siret missing", "type": "string", "example": "123456789" }, "vat_number": { "type": "string", "example": "FR32123456789" }, "company_name": { "type": "string", "example": "Acme SARL" }, "address": { "type": "string", "example": "10 Rue de la Paix" }, "city": { "type": "string", "example": "Paris" }, "postalcode": { "type": "string", "example": "75001" }, "province": { "type": "string", "example": "Île-de-France" }, "email": { "type": "string", "format": "email", "example": "tax@acme.fr" }, "naf_code": { "type": "string", "example": "47" }, "enterprise_size": { "type": "string", "enum": [ "micro", "pme", "eti", "ge" ] }, "type_operation": { "type": "string", "enum": [ "services", "goods", "mixed" ] }, "reporting_start_date": { "type": "string", "format": "date", "example": "2026-09-01" }, "auto_activate": { "description": "When false, only the account is created — DGFiP tax-report-setting is NOT activated.", "type": "boolean", "default": true } }, "type": "object" } } } }, "responses": { "201": { "description": "Enrollment created (and activated when auto_activate=true)", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/ComplianceEnrollment" } }, "type": "object" } } } }, "403": { "description": "The requested service is not booked for this country (code service_not_active)" }, "422": { "description": "Validation failed" }, "502": { "description": "Provider error — enrollment persisted in error state" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/enrollments/{id}": { "get": { "tags": [ "Compliance" ], "summary": "Get a single compliance enrollment", "operationId": "e6cd9d853047c1be7476973679756163", "responses": { "200": { "description": "OK" }, "404": { "description": "Not found" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/sirene-lookup": { "get": { "tags": [ "Compliance" ], "summary": "Look up French company data by SIRET, SIREN or FR VAT number (SIRENE registry)", "description": "Resolves the SIREN from the given identifier and returns official company data from the INSEE SIRENE registry. Rate-limited to 3 requests per minute per user.", "operationId": "84c31556ff52290a52a558a40c1594fd", "parameters": [ { "name": "q", "in": "query", "description": "SIRET (14 digits), SIREN (9 digits) or French VAT number (FR + 2 chars + 9 digits)", "required": true, "schema": { "type": "string", "example": "12345678900012" } } ], "responses": { "200": { "description": "Company data found", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "company_name": { "type": "string", "example": "Acme SARL", "nullable": true }, "siren": { "type": "string", "example": "123456789", "nullable": true }, "siret": { "type": "string", "example": "12345678900012", "nullable": true }, "naf_code": { "type": "string", "example": "47", "nullable": true }, "naf_full": { "type": "string", "example": "47.19Z", "nullable": true }, "enterprise_size": { "type": "string", "enum": [ "micro", "pme", "eti", "ge" ], "nullable": true }, "address": { "type": "string", "nullable": true }, "city": { "type": "string", "nullable": true }, "postalcode": { "type": "string", "nullable": true } }, "type": "object" } }, "type": "object" } } } }, "404": { "description": "No company found for the given SIREN" }, "422": { "description": "Missing or invalid query parameter q" }, "429": { "description": "Rate limit exceeded (3 requests/minute)" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/registry-lookup": { "get": { "tags": [ "Compliance" ], "summary": "Look up a company in the national register (Norway: Brønnøysund Enhetsregisteret)", "description": "Resolves a Norwegian organisation number (or 'NO…MVA' VAT number) — or searches by name — in the official register. Returns the company name, address, whether it is VAT-registered (MVA) and registered in Foretaksregisteret. Rate-limited to 30 requests per minute per user.", "operationId": "9dc5d9c50177e7f146b8e6c0f652a403", "parameters": [ { "name": "country", "in": "query", "required": true, "schema": { "type": "string", "enum": [ "NO" ] } }, { "name": "q", "in": "query", "description": "Organisation number, NO…MVA VAT number or company name", "required": true, "schema": { "type": "string", "example": "923609016" } } ], "responses": { "200": { "description": "Matching companies (exact number match → one result)", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "results": { "type": "array", "items": { "properties": { "org_number": { "type": "string", "example": "923609016" }, "company_name": { "type": "string", "example": "EQUINOR ASA" }, "organisation_form": { "type": "string", "example": "ASA", "nullable": true }, "vat_registered": { "type": "boolean", "example": true }, "vat_number": { "type": "string", "example": "NO923609016MVA", "nullable": true }, "enterprise_register": { "type": "boolean", "example": true }, "bankrupt": { "type": "boolean", "example": false }, "under_liquidation": { "type": "boolean", "example": false }, "address": { "type": "string", "nullable": true }, "postalcode": { "type": "string", "nullable": true }, "city": { "type": "string", "nullable": true }, "country": { "type": "string", "example": "NO" } }, "type": "object" } } }, "type": "object" } }, "type": "object" } } } }, "404": { "description": "No company found" }, "422": { "description": "Missing query or unsupported country" }, "429": { "description": "Rate limit exceeded" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/peppol-lookup": { "get": { "tags": [ "Compliance" ], "summary": "Check whether a buyer can receive e-invoices over Peppol", "description": "Looks the buyer up in the Peppol directory. For Norway pass the organisation number: `reachable=true` means the buyer is registered in ELMA and must receive an EHF e-invoice; `reachable=false` means it is not on Peppol. The directory resolves asynchronously — `status=pending` means ask again in a few seconds. Definite answers are cached for 24h. Free of charge.", "operationId": "3684b4402955691f892f80d141868c7a", "parameters": [ { "name": "country", "in": "query", "required": true, "schema": { "type": "string", "enum": [ "NO" ] } }, { "name": "id", "in": "query", "description": "Participant id — NO: organisation number", "required": true, "schema": { "type": "string", "example": "923609016" } }, { "name": "scheme", "in": "query", "description": "Peppol identifier scheme (NO default 0192)", "required": false, "schema": { "type": "string", "example": "0192" } } ], "responses": { "200": { "description": "Lookup result", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "status": { "type": "string", "enum": [ "reachable", "not_reachable", "pending" ] }, "reachable": { "type": "boolean", "nullable": true }, "country": { "type": "string", "example": "NO" }, "scheme": { "type": "string", "example": "0192" }, "id": { "type": "string", "example": "923609016" }, "document_types": { "type": "array", "items": { "type": "string", "example": "xml.ubl.invoice.bis3" } }, "transport_type_code": { "type": "string", "example": "peppol", "nullable": true }, "checked_at": { "type": "string", "format": "date-time" } }, "type": "object" } }, "type": "object" } } } }, "422": { "description": "Invalid id or unsupported country" }, "502": { "description": "Provider error" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/revenue-statistics": { "get": { "tags": [ "Compliance" ], "summary": "Aggregated revenue statistics for e-reporting transactions", "description": "Returns turnover totals, a time series and breakdowns (by transaction type, counterparty country and state) for the authenticated company. Read-only aggregation over the company's transactions. Amounts are computed in the most frequent currency in the range (`primary_currency`); a `by_currency` breakdown and `is_multi_currency` flag surface any other currencies. Defaults to the last 12 months and a monthly interval.", "operationId": "8a79555799629cacd21a55baccc545cb", "parameters": [ { "name": "date_from", "in": "query", "description": "Inclusive lower bound (Y-m-d). Defaults to 12 months ago.", "required": false, "schema": { "type": "string", "format": "date" } }, { "name": "date_to", "in": "query", "description": "Inclusive upper bound (Y-m-d). Defaults to today. Must be >= date_from.", "required": false, "schema": { "type": "string", "format": "date" } }, { "name": "interval", "in": "query", "description": "Time-series bucket size. Defaults to month.", "required": false, "schema": { "type": "string", "enum": [ "day", "week", "month" ] } }, { "name": "transaction_type", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "b2c_outbound", "b2b_domestic_outbound", "b2b_domestic_inbound", "crossborder_outbound", "crossborder_inbound" ] } }, { "name": "state", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "pending", "sending", "submitted", "error", "not_required" ] } }, { "name": "include_tax_rates", "in": "query", "description": "Also return `by_tax_rate` (net and VAT per tax rate).", "required": false, "schema": { "type": "boolean", "default": false } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "range": { "properties": { "date_from": { "type": "string", "format": "date" }, "date_to": { "type": "string", "format": "date" }, "interval": { "type": "string", "example": "month" } }, "type": "object" }, "primary_currency": { "type": "string", "example": "EUR" }, "is_multi_currency": { "type": "boolean", "example": false }, "totals": { "properties": { "count": { "type": "integer", "example": 1234 }, "subtotal": { "type": "string", "example": "100000.0000" }, "tax_amount": { "type": "string", "example": "20000.0000" }, "total": { "type": "string", "example": "120000.0000" } }, "type": "object" }, "time_series": { "type": "array", "items": { "properties": { "bucket": { "type": "string", "example": "2026-01" }, "count": { "type": "integer" }, "subtotal": { "type": "string" }, "tax_amount": { "type": "string" }, "total": { "type": "string" } }, "type": "object" } }, "by_type": { "type": "array", "items": { "properties": { "type": { "type": "string" }, "type_label": { "type": "string" }, "count": { "type": "integer" }, "total": { "type": "string" } }, "type": "object" } }, "by_country": { "type": "array", "items": { "properties": { "country": { "type": "string", "example": "de" }, "count": { "type": "integer" }, "total": { "type": "string" } }, "type": "object" } }, "by_state": { "type": "array", "items": { "properties": { "state": { "type": "string" }, "state_label": { "type": "string" }, "count": { "type": "integer" }, "total": { "type": "string" } }, "type": "object" } }, "by_tax_rate": { "description": "Net and VAT per tax rate from the invoice lines (primary currency) — for reconciling with the VAT return. Only with include_tax_rates=1, otherwise null.", "type": "array", "items": { "properties": { "category": { "type": "string", "example": "S" }, "percent": { "type": "string", "example": "20.00" }, "lines": { "type": "integer" }, "subtotal": { "type": "string" }, "tax_amount": { "type": "string" } }, "type": "object" }, "nullable": true }, "by_currency": { "type": "array", "items": { "properties": { "currency": { "type": "string" }, "count": { "type": "integer" }, "subtotal": { "type": "string" }, "tax_amount": { "type": "string" }, "total": { "type": "string" } }, "type": "object" } } }, "type": "object" } }, "type": "object" } } } }, "403": { "description": "E-Reporting access is not active" }, "422": { "description": "Validation failed" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/revenue-statistics/tax-rates.csv": { "get": { "tags": [ "Compliance" ], "summary": "Net and VAT per month and tax rate as CSV", "description": "Semicolon-separated CSV with one row per month, currency and tax rate (net, VAT, gross, number of invoice lines), computed from the invoice lines — for reconciling the reported figures with your VAT return. Same filters as /compliance/revenue-statistics.", "operationId": "617b412191e7053374f635c22f992ab9", "parameters": [ { "name": "date_from", "in": "query", "required": false, "schema": { "type": "string", "format": "date" } }, { "name": "date_to", "in": "query", "required": false, "schema": { "type": "string", "format": "date" } }, { "name": "transaction_type", "in": "query", "required": false, "schema": { "type": "string" } }, { "name": "state", "in": "query", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "CSV file", "content": { "text/csv": {} } }, "403": { "description": "E-Reporting access is not active" }, "422": { "description": "Validation failed" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/tax-reports": { "get": { "tags": [ "Compliance" ], "summary": "List compliance tax reports for the authenticated company", "operationId": "0a3cbc1b2e5c38987f17bfed5a9c96ea", "responses": { "200": { "description": "OK" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/tax-reports/{id}": { "get": { "tags": [ "Compliance" ], "summary": "Get a single tax report", "operationId": "20eb68a982670c1961b43dabee724235", "responses": { "200": { "description": "OK" }, "404": { "description": "Not found" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/transactions": { "get": { "tags": [ "Compliance" ], "summary": "List compliance transactions (filterable by date / state / type / country)", "operationId": "4fe79e545656f42c0dd6021a0478cd6a", "parameters": [ { "name": "compliance_enrollment_id", "in": "query", "required": false, "schema": { "type": "integer" } }, { "name": "country", "in": "query", "required": false, "schema": { "type": "string", "example": "NO" } } ], "responses": { "200": { "description": "OK" } }, "security": [ { "ApiKeyAuth": [] } ] }, "post": { "tags": [ "Compliance" ], "summary": "Record a transaction for an enrolled country (and submit it when the country is booked as e-invoicing)", "description": "Persists the transaction locally. When the enrollment's service is `e_invoicing` it is forwarded to the provider right away (France: Flux 1 as IssuedSimplifiedInvoice/IssuedInvoice/ReceivedInvoice; Norway: EHF 3.0 / Peppol BIS 3.0 delivered to the buyer's Peppol address). In `e_reporting` mode it is only stored and reported via the daily ledgers. Set `submit_now=false` to defer submission. Norway requires `counterparty_register_id` (the buyer's organisation number) and `counterparty_name`; transaction_type must be `b2b_domestic_outbound`; credit notes set `is_credit_note=true` + `amended_number`.", "operationId": "35d08bf213aa62e763155887fc57b5d0", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "compliance_enrollment_id", "transaction_type", "invoice_number", "invoice_date", "subtotal", "total", "invoice_lines_attributes" ], "properties": { "compliance_enrollment_id": { "type": "integer", "example": 12 }, "transaction_type": { "type": "string", "enum": [ "b2c_outbound", "crossborder_outbound", "crossborder_inbound", "b2b_domestic_outbound", "b2b_domestic_inbound" ] }, "invoice_number": { "type": "string", "example": "TKT-2026-00001" }, "invoice_date": { "type": "string", "format": "date" }, "due_date": { "type": "string", "format": "date", "nullable": true }, "currency": { "type": "string", "example": "EUR" }, "subtotal": { "type": "number", "format": "float" }, "tax_amount": { "type": "number", "format": "float" }, "total": { "type": "number", "format": "float" }, "counterparty_name": { "type": "string", "nullable": true }, "counterparty_country": { "type": "string", "example": "de", "nullable": true }, "counterparty_vat_number": { "type": "string", "nullable": true }, "provider_contact_id": { "type": "string", "nullable": true }, "invoice_lines_attributes": { "type": "array", "items": { "required": [ "description", "quantity", "price", "taxes_attributes" ], "properties": { "description": { "type": "string" }, "quantity": { "type": "number" }, "price": { "type": "number" }, "unit": { "type": "integer", "example": 9 }, "taxes_attributes": { "type": "array", "items": { "properties": { "name": { "type": "string", "example": "TVA" }, "percent": { "type": "number", "example": 20 }, "category": { "description": "S/AA/AAA/K/G/AE/E/Z — see TVA-Konfiguration", "type": "string", "example": "S" }, "comment": { "description": "Required when category=E (VATEX code)", "type": "string" } }, "type": "object" } } }, "type": "object" } }, "payment_method": { "description": "Required for cross-border outbound", "type": "integer", "nullable": true }, "remittance_information": { "type": "string", "nullable": true }, "payment_method_text": { "type": "string", "nullable": true }, "payment_terms": { "type": "string", "nullable": true }, "submit_now": { "type": "boolean", "default": true }, "invoice_pdf": { "description": "E-invoicing only: your own invoice PDF, base64-encoded (max 10 MB). Attached to the e-invoice as its visual representation. The structured e-invoice stays the legal document; whether the buyer's system shows the PDF depends on that system.", "type": "string", "format": "byte", "nullable": true }, "invoice_pdf_filename": { "type": "string", "example": "RE-2027-0001.pdf", "nullable": true }, "counterparty_register_id": { "description": "Buyer company register id — NO: 9-digit organisation number (Peppol 0192), required", "type": "string", "example": "923609016", "nullable": true }, "counterparty_address": { "type": "string", "nullable": true }, "counterparty_city": { "type": "string", "nullable": true }, "counterparty_postalcode": { "type": "string", "nullable": true }, "counterparty_email": { "type": "string", "format": "email", "nullable": true }, "buyer_reference": { "description": "Buyer reference (Peppol BuyerReference). NO: defaults to the buyer org. number", "type": "string", "nullable": true }, "is_credit_note": { "type": "boolean", "default": false }, "amended_number": { "description": "Credit notes: number of the invoice being corrected", "type": "string", "nullable": true }, "amended_date": { "type": "string", "format": "date", "nullable": true }, "extra_info": { "description": "Free-text invoice note. NO: mandatory legal notes (Foretaksregisteret, reverse charge) are added automatically", "type": "string", "nullable": true } }, "type": "object" } } } }, "responses": { "201": { "description": "Transaction created (and submitted when submit_now=true)" }, "404": { "description": "Enrollment not found / belongs to another company" }, "422": { "description": "Validation failed" }, "502": { "description": "Provider error" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/transactions/{id}": { "get": { "tags": [ "Compliance" ], "summary": "Get a single compliance transaction", "operationId": "67410b80e051c4ae2166f9ede1423024", "responses": { "200": { "description": "OK" }, "404": { "description": "Not found" } }, "security": [ { "ApiKeyAuth": [] } ] }, "put": { "tags": [ "Compliance" ], "summary": "Update a pending compliance transaction", "description": "Only transactions in 'pending' state can be edited. All body fields are optional; only provided fields are updated. Invoice lines and payment extras replace the stored draft payload.", "operationId": "a150f33e0fa72da34b98483b87ce4619", "parameters": [ { "name": "id", "in": "path", "description": "Transaction ID", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "properties": { "transaction_type": { "type": "string", "enum": [ "b2c_outbound", "crossborder_outbound", "crossborder_inbound", "b2b_domestic_outbound", "b2b_domestic_inbound" ] }, "invoice_number": { "type": "string", "example": "TKT-2026-00001" }, "invoice_date": { "type": "string", "format": "date" }, "due_date": { "type": "string", "format": "date", "nullable": true }, "currency": { "type": "string", "example": "EUR", "nullable": true }, "subtotal": { "type": "number", "format": "float" }, "tax_amount": { "type": "number", "format": "float", "nullable": true }, "total": { "type": "number", "format": "float" }, "counterparty_name": { "type": "string", "nullable": true }, "counterparty_country": { "type": "string", "example": "de", "nullable": true }, "counterparty_vat_number": { "type": "string", "nullable": true }, "provider_contact_id": { "type": "string", "nullable": true }, "invoice_lines_attributes": { "type": "array", "items": { "type": "object" } }, "payment_method": { "type": "integer", "nullable": true }, "remittance_information": { "type": "string", "nullable": true }, "payment_method_text": { "type": "string", "nullable": true }, "payment_terms": { "type": "string", "nullable": true }, "invoice_pdf": { "description": "E-invoicing only: replaces the attached invoice PDF (base64, max 10 MB).", "type": "string", "format": "byte", "nullable": true }, "invoice_pdf_filename": { "type": "string", "nullable": true } }, "type": "object" } } } }, "responses": { "200": { "description": "Updated transaction" }, "404": { "description": "Transaction not found" }, "422": { "description": "Only pending transactions can be edited / validation failed" } }, "security": [ { "ApiKeyAuth": [] } ] }, "delete": { "tags": [ "Compliance" ], "summary": "Delete a pending compliance transaction", "description": "Only transactions in 'pending' state can be deleted.", "operationId": "bb30c6ed9615d3775d27997d37941c28", "parameters": [ { "name": "id", "in": "path", "description": "Transaction ID", "required": true, "schema": { "type": "integer" } } ], "responses": { "204": { "description": "Transaction deleted" }, "404": { "description": "Transaction not found" }, "422": { "description": "Only pending transactions can be deleted" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/transactions/{id}/document": { "get": { "tags": [ "Compliance" ], "summary": "Download the legal e-invoice document", "description": "E-invoicing only: the structured e-invoice (e.g. EHF/Peppol UBL XML) exactly as it was sent to the buyer — the legally binding invoice. Available once the transaction is `submitted`. Taxora keeps its own archived copy, so the document stays downloadable here. Use `document_url` from the transaction to link it from your own system.", "operationId": "32172cc4379792056c2cde3dc66439a3", "parameters": [ { "name": "id", "in": "path", "description": "Transaction ID", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "The document (usually application/xml)", "content": { "application/xml": {} } }, "404": { "description": "Transaction not found" }, "409": { "description": "Not available yet — the e-invoice has not been sent, or the provider is still preparing the document" }, "502": { "description": "Provider error" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/transactions/{id}/submit": { "post": { "tags": [ "Compliance" ], "summary": "Submit (or retry) an existing transaction to the provider", "description": "Submits a transaction that is in 'pending' or 'error' state to B2Brouter/DGFiP. Replays the invoice lines stored in provider_payload so they don't have to be re-sent. Already-submitted transactions are rejected.", "operationId": "ce77bb6c10396aac8c480a0720986cfa", "responses": { "200": { "description": "Transaction submitted" }, "404": { "description": "Transaction not found" }, "422": { "description": "Transaction already submitted / enrollment not provisioned" }, "502": { "description": "Provider error" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/transactions/import": { "post": { "tags": [ "Compliance" ], "summary": "Bulk import compliance transactions from a CSV file", "description": "Uploads a semicolon-delimited CSV (max 2 MB). Required columns: invoice_number, invoice_date, transaction_type, subtotal, total, line_description, line_quantity, line_price, tax_name, tax_percent, tax_category. Optional columns: due_date, currency, tax_amount, counterparty_name, counterparty_country, counterparty_vat_number. Rows sharing an invoice_number are grouped into one transaction with multiple lines. Duplicates (same invoice natural key) are skipped without error.", "operationId": "a248d35a72961714ffbd408579ab505e", "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "required": [ "compliance_enrollment_id", "file" ], "properties": { "compliance_enrollment_id": { "type": "integer", "example": 12 }, "file": { "description": "CSV file, ';' delimiter, max 2048 KB", "type": "string", "format": "binary" } }, "type": "object" } } } }, "responses": { "200": { "description": "Import result", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "created": { "type": "integer", "example": 42 }, "skipped_duplicates": { "type": "integer", "example": 3 }, "errors": { "type": "array", "items": { "type": "string" }, "example": [ "Row 5: invalid transaction_type 'invalid'" ] } }, "type": "object" } }, "type": "object" } } } }, "404": { "description": "Enrollment not found for this company" }, "422": { "description": "Missing CSV columns / unreadable file / validation failed" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/compliance/vat-rates": { "get": { "tags": [ "Compliance" ], "summary": "List the VAT rates & DGFiP tax categories for a reporting country", "description": "Returns the canonical VAT rates and DGFiP tax categories (single source of truth, maintained in config/compliance.php). The rates are the seller's reporting-country rates. Defaults to the configured default country when no/unknown country is given.", "operationId": "1a82e9cb07033a70f4576ff55bd32dba", "parameters": [ { "name": "country", "in": "query", "description": "ISO 3166-1 alpha-2 reporting country code (e.g. FR)", "required": false, "schema": { "type": "string", "example": "FR" } } ], "responses": { "200": { "description": "VAT rates for the country" } }, "security": [ { "ApiKeyAuth": [] } ] } }, "/v1/reports/local-tax-numbers/summary": { "get": { "tags": [ "Reports" ], "summary": "How many companies the local tax numbers report would list", "operationId": "bd45103dd0aab18d3221e1e462e71850", "parameters": [ { "name": "date_from", "in": "query", "schema": { "type": "string", "format": "date" } }, { "name": "date_to", "in": "query", "schema": { "type": "string", "format": "date" } }, { "name": "countries[]", "in": "query", "schema": { "type": "array", "items": { "type": "string", "example": "PL" } } } ], "responses": { "200": { "description": "`companies` and `withTaxNumber` for the filters (ignores only_with_tax_number)." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/reports/local-tax-numbers": { "get": { "tags": [ "Reports" ], "summary": "Local tax numbers report (CSV)", "description": "Every company checked — single and bulk VAT checks and Smart Enrichment lookups — once (per VAT ID, or name + country without one; newest answer wins), with its local tax number: `taxNumber`, its national name `taxNumberName` (NIP, SIREN, Partita IVA, Steuernummer …) and `taxNumberSource` (`vat_id` = read off the confirmed VAT ID, `company_website` = published by the company). `vatStatus`: valid, invalid, unconfirmed, wrong_company, no_vat_id, not_found. `source`: vat_check or smart_enrichment; `checkId` is the VAT check uuid or the lookup job id.", "operationId": "d9eddd112406114d5ec630a185264c32", "parameters": [ { "name": "date_from", "in": "query", "schema": { "type": "string", "format": "date" } }, { "name": "date_to", "in": "query", "schema": { "type": "string", "format": "date" } }, { "name": "countries[]", "in": "query", "schema": { "type": "array", "items": { "type": "string", "example": "PL" } } }, { "name": "only_with_tax_number", "in": "query", "schema": { "type": "boolean" } } ], "responses": { "200": { "description": "CSV, UTF-8 with BOM, comma-separated." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/reports": { "get": { "tags": [ "Reports" ], "summary": "List report runs for the authenticated company", "operationId": "4209380269295829e80839781962d110", "parameters": [ { "name": "per_page", "in": "query", "description": "Items per page (default 25)", "schema": { "type": "integer", "maximum": 100, "minimum": 1 } }, { "name": "job_id", "in": "query", "description": "Filter report runs by report job id", "schema": { "type": "string", "format": "uuid" } }, { "name": "generated_only", "in": "query", "description": "Return only runs that have a generated report file", "schema": { "type": "boolean" } } ], "responses": { "200": { "description": "List of report runs", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "data": { "type": "array", "items": { "properties": { "id": { "type": "string", "format": "uuid" }, "job_id": { "type": "string", "format": "uuid" }, "type": { "type": "string", "example": "vat_certificates_list" }, "job_name": { "type": "string", "nullable": true }, "state": { "type": "string" }, "result": { "type": "string", "nullable": true }, "params": { "type": "object" }, "scheduled_at": { "type": "string", "format": "date-time", "nullable": true }, "started_at": { "type": "string", "format": "date-time", "nullable": true }, "finished_at": { "type": "string", "format": "date-time", "nullable": true }, "file_disk": { "type": "string", "nullable": true }, "file_path": { "type": "string", "nullable": true }, "file_name": { "type": "string", "nullable": true }, "file_mime": { "type": "string", "nullable": true }, "file_size": { "type": "integer", "nullable": true }, "error_message": { "type": "string", "nullable": true }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } }, "type": "object" } }, "current_page": { "type": "integer" }, "per_page": { "type": "integer" }, "total": { "type": "integer" } }, "type": "object" } }, "type": "object" } } } } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/reports/runs": { "post": { "tags": [ "Reports" ], "summary": "Create a report run for the authenticated company", "operationId": "f39314a9d43c7a049cc6cdcadd049efa", "requestBody": { "required": true, "content": { "application/json": { "schema": { "properties": { "id": { "type": "string", "format": "uuid", "nullable": true }, "job_id": { "type": "string", "format": "uuid" }, "state": { "type": "string", "example": "completed" }, "params": { "type": "object" }, "scheduled_at": { "type": "string", "format": "date-time", "nullable": true }, "started_at": { "type": "string", "format": "date-time", "nullable": true }, "finished_at": { "type": "string", "format": "date-time", "nullable": true }, "result": { "type": "string", "nullable": true }, "file_disk": { "type": "string", "nullable": true }, "file_path": { "type": "string", "nullable": true }, "file_name": { "type": "string", "nullable": true }, "file_mime": { "type": "string", "nullable": true }, "file_size": { "type": "integer", "nullable": true }, "error_message": { "type": "string", "nullable": true } }, "type": "object" } } } }, "responses": { "201": { "description": "Report run created", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object" } }, "type": "object" } } } }, "400": { "description": "Invalid request" }, "404": { "description": "Report job not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/reports/runs/{id}": { "delete": { "tags": [ "Reports" ], "summary": "Delete a report run (and its file) for the authenticated company", "operationId": "dc2d43f470f39ff42a3cddf8401d6545", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "message": { "type": "string", "example": "Report run deleted" } }, "type": "object" } }, "type": "object" } } } }, "400": { "description": "Invalid ID" }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/reports/runs/{id}/download": { "get": { "tags": [ "Reports" ], "summary": "Download a report run file", "operationId": "1e21a213431faf83c01df894ff53fbbb", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Report file", "content": { "application/octet-stream": { "schema": { "type": "string", "format": "binary" } } } }, "400": { "description": "Invalid ID" }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/reports/jobs": { "get": { "tags": [ "Reports" ], "summary": "List report jobs for the authenticated company", "operationId": "857d66ab6df11d161b55e40d034ebea4", "parameters": [ { "name": "per_page", "in": "query", "description": "Items per page (default 25)", "schema": { "type": "integer", "maximum": 100, "minimum": 1 } } ], "responses": { "200": { "description": "List of report jobs", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object" } }, "type": "object" } } } } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] }, "post": { "tags": [ "Reports" ], "summary": "Create or update a report job including scheduling", "operationId": "2c8e67ea08682adafc009c3d80bb4886", "requestBody": { "required": true, "content": { "application/json": { "schema": { "properties": { "id": { "type": "string", "format": "uuid", "nullable": true }, "type": { "type": "string", "example": "vat_certificates_bulk" }, "subtype": { "type": "string", "example": "scheduled", "nullable": true }, "name": { "type": "string", "nullable": true }, "params": { "description": "Job parameters. Common keys: lang (en|de), from_date, to_date, countries, include_documents. Date fields support placeholders: {{last_run_at}}, {{scheduled_at}} or relative strings like 'last monday', 'first day of last month'. Scheduled jobs store schedule metadata under params.schedule.", "type": "object" }, "schedule": { "properties": { "type": { "type": "string", "example": "weekly" }, "day": { "type": "integer", "example": 1 }, "time": { "type": "string", "example": "08:00" } }, "type": "object", "nullable": true } }, "type": "object" } } } }, "responses": { "200": { "description": "Report job saved", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object" } }, "type": "object" } } } } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/reports/jobs/{id}": { "get": { "tags": [ "Reports" ], "summary": "Get a report job by ID", "operationId": "7e67964f4a8cfb0bc46dfee5c05161a0", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Report job details", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object" } }, "type": "object" } } } }, "404": { "description": "Report job not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] }, "delete": { "tags": [ "Reports" ], "summary": "Delete a report job for the authenticated company", "operationId": "8b94d6469bb6e5f0e141f4a28d71ebf9", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true } }, "type": "object" } } } }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/smart-enrichment": { "post": { "tags": [ "Smart Enrichment" ], "summary": "Reverse VAT lookup (single)", "description": "Resolves a company name + address + country to its VAT/UID number with a confidence score. Returns a result synchronously when a confident match is found in your validated data; otherwise responds 202 with a jobId to poll (and delivers the result via the `enrichment.completed` webhook). Requires the Smart Enrichment add-on.", "operationId": "adc0601e4decccfbaf28314a80d4ac85", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "companyName", "country" ], "properties": { "companyName": { "type": "string", "maxLength": 255, "example": "Example Company GmbH" }, "country": { "description": "ISO 3166-1 alpha-2 country code", "type": "string", "maxLength": 2, "minLength": 2, "example": "AT" }, "street": { "type": "string", "maxLength": 255, "example": "Main Street 10", "nullable": true }, "postalCode": { "type": "string", "maxLength": 32, "example": "1010", "nullable": true }, "city": { "type": "string", "maxLength": 128, "example": "Vienna", "nullable": true } }, "type": "object" } } } }, "responses": { "200": { "description": "Synchronous result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SmartEnrichmentResult" } } } }, "202": { "description": "Accepted — processing asynchronously", "content": { "application/json": { "schema": { "properties": { "jobId": { "type": "string", "format": "uuid" }, "status": { "type": "string", "example": "processing" } }, "type": "object" } } } }, "403": { "description": "Smart Enrichment access not active" }, "404": { "description": "Feature not available" }, "422": { "description": "Validation error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/smart-enrichment/bulk": { "post": { "tags": [ "Smart Enrichment" ], "summary": "Reverse VAT lookup (bulk)", "description": "Submits a batch of company records for reverse VAT lookup. Always processed asynchronously: responds 202 with a jobId; per-item results are delivered via the `enrichment.completed` webhook and retrievable via GET /v1/smart-enrichment/{jobId}.", "operationId": "96c9ae19e7f58603844628db064d6791", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "items" ], "properties": { "items": { "type": "array", "items": { "required": [ "companyName", "country" ], "properties": { "companyName": { "type": "string", "example": "Example Company GmbH" }, "country": { "type": "string", "example": "DE" }, "street": { "type": "string", "nullable": true }, "postalCode": { "type": "string", "nullable": true }, "city": { "type": "string", "nullable": true }, "mode": { "description": "Per-row search mode; overrides the batch-level `mode`. A `complex` row counts as several checks (see `deepVerifyChecks` in GET /v1/smart-enrichment/usage, default 2).", "type": "string", "enum": [ "default", "complex" ], "nullable": true } }, "type": "object" } }, "mode": { "description": "Search mode for every row in the batch. `default` (Smart Search) runs one AI research pass and a second only when nothing is found. `complex` (Deep Verify) runs two independent research passes from the start and cross-checks them — higher hit rate on hard lookups. Every company counts as one check, found or not; a `complex` row counts as `deepVerifyChecks` checks (GET /v1/smart-enrichment/usage, default 2).", "type": "string", "enum": [ "default", "complex" ], "example": "default", "nullable": true } }, "type": "object" } } } }, "responses": { "202": { "description": "Accepted — batch processing asynchronously", "content": { "application/json": { "schema": { "properties": { "jobId": { "type": "string", "format": "uuid" }, "status": { "type": "string", "example": "processing" }, "itemCount": { "type": "integer", "example": 2 } }, "type": "object" } } } }, "403": { "description": "Smart Enrichment access not active" }, "422": { "description": "Validation error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/smart-enrichment/usage": { "get": { "tags": [ "Smart Enrichment" ], "summary": "Quota usage", "description": "Returns the current billing-period Smart Enrichment usage: checks used, the included monthly allowance, remaining included checks, the per-check overage price, and the optional hard cap. Every checked company counts as one check, whether a VAT number was found or not; `found` shows how many of them returned a VAT number.", "operationId": "50170e74c115486eebba3beb914e88d8", "responses": { "200": { "description": "Usage", "content": { "application/json": { "schema": { "properties": { "period": { "type": "string", "example": "2026-06" }, "used": { "description": "Checks this period (every checked company, found or not)", "type": "integer", "example": 312 }, "found": { "description": "VAT numbers found this period", "type": "integer", "example": 248 }, "deepVerifyChecks": { "description": "Checks one Deep Verify (mode=complex) lookup uses per company", "type": "integer", "example": 2 }, "included": { "type": "integer", "example": 300 }, "remaining": { "type": "integer", "example": 0 }, "overageCount": { "type": "integer", "example": 12 }, "overagePrice": { "type": "number", "format": "float", "example": 0.08 }, "overageAmount": { "description": "Amount due this period (overage checks × price)", "type": "number", "format": "float", "example": 0.96 }, "hardCap": { "type": "integer", "example": null, "nullable": true }, "trial": { "description": "Free start credit, present only while the account is on one. Once it is used up, new lookups answer 429 (code smart_enrichment_trial_exhausted).", "properties": { "credits": { "type": "integer", "example": 10 }, "used": { "description": "Checks so far (found or not)", "type": "integer", "example": 3 }, "reserved": { "description": "Rows of running lookups, reserved until they are checked", "type": "integer", "example": 2 }, "remaining": { "type": "integer", "example": 5 }, "validUntil": { "type": "string", "format": "date", "example": "2026-11-30", "nullable": true }, "exhausted": { "type": "boolean", "example": false } }, "type": "object", "nullable": true }, "history": { "description": "Recent monthly billing for full transparency", "type": "array", "items": { "properties": { "period": { "type": "string", "example": "2026-05" }, "matches": { "description": "Checks billed in this period (field name kept for compatibility)", "type": "integer", "example": 420 }, "amount": { "type": "string", "example": "9.60" }, "state": { "type": "string", "example": "billed" }, "billingType": { "type": "string", "example": "manual", "nullable": true }, "manualReference": { "type": "string", "example": "INV-2026-0042", "nullable": true } }, "type": "object" } } }, "type": "object" } } } }, "403": { "description": "Smart Enrichment access not active" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/smart-enrichment/history": { "get": { "tags": [ "Smart Enrichment" ], "summary": "Lookup history", "description": "Paginated history of Smart Enrichment lookups for the authenticated company, newest first. Each row is a compact summary (the query and the headline result); full detail is available via GET /v1/smart-enrichment/{jobId}.", "operationId": "fb03efc2987e03d17d29d96124f6b879", "parameters": [ { "name": "page", "in": "query", "required": false, "schema": { "type": "integer", "default": 1 } }, { "name": "perPage", "in": "query", "required": false, "schema": { "type": "integer", "default": 25, "maximum": 100 } }, { "name": "search", "in": "query", "description": "Company name, address, VAT or tax number. Matching rows of a batch are returned in `matchedRows`.", "required": false, "schema": { "type": "string" } }, { "name": "status", "in": "query", "description": "Only lookups with at least one row of this outcome. `found` includes numbers registered to another company, `not_found` includes rejected numbers.", "required": false, "schema": { "type": "string", "enum": [ "found", "wrong_company", "rejected", "not_found", "no_vat_exists" ] } }, { "name": "type", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "single", "batch" ] } }, { "name": "country", "in": "query", "description": "ISO 3166-1 alpha-2 country of the queried company.", "required": false, "schema": { "type": "string", "example": "DE" } }, { "name": "postal", "in": "query", "description": "Postal code prefix, e.g. `40` for the whole 40xxx area.", "required": false, "schema": { "type": "string", "example": "40" } }, { "name": "date_from", "in": "query", "required": false, "schema": { "type": "string", "format": "date" } }, { "name": "date_to", "in": "query", "required": false, "schema": { "type": "string", "format": "date" } } ], "responses": { "200": { "description": "Paginated history", "content": { "application/json": { "schema": { "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/SmartEnrichmentHistoryRow" } }, "meta": { "properties": { "currentPage": { "type": "integer", "example": 1 }, "perPage": { "type": "integer", "example": 25 }, "total": { "type": "integer", "example": 42 }, "lastPage": { "type": "integer", "example": 2 } }, "type": "object" } }, "type": "object" } } } }, "403": { "description": "Smart Enrichment access not active" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/smart-enrichment/export": { "get": { "tags": [ "Smart Enrichment" ], "summary": "Export lookups as CSV", "description": "Download the authenticated company's Smart Enrichment lookups as a CSV in the bulk-input shape plus resolved VAT columns. `status` is `wrong_company` when the number is valid but the tax authority registers it under another name (`matchedCompanyName` then carries that name). The trailing columns `vatValid`, `nameMatch`, `taxNumber`, `rejectedVatNumber`, `rejectedReason`, `taxNumberName` and `taxNumberSource` say whether the authority confirmed the number, whether it belongs to this company, the local tax number (read off the confirmed VAT ID, or published by the company), which numbers were rejected and why (several joined with |), and the local tax number's national name (SIREN, NIP …) and origin (`vat_id` = read off the confirmed VAT ID, `company_website` = published by the company). Optional filters: date range (created_at), minimum confidence, item status, and only-found.", "operationId": "265fd138147784cc6d83405951b95c88", "parameters": [ { "name": "date_from", "in": "query", "required": false, "schema": { "type": "string", "format": "date" } }, { "name": "date_to", "in": "query", "required": false, "schema": { "type": "string", "format": "date" } }, { "name": "min_confidence", "in": "query", "description": "0–100", "required": false, "schema": { "type": "number", "format": "float" } }, { "name": "status[]", "in": "query", "required": false, "schema": { "type": "array", "items": { "type": "string", "enum": [ "found", "no_vat_exists", "not_found" ] } } }, { "name": "only_found", "in": "query", "required": false, "schema": { "type": "boolean" } }, { "name": "job_id", "in": "query", "description": "Only this lookup or batch (its jobId).", "required": false, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "CSV file", "content": { "text/csv": {} } }, "403": { "description": "Smart Enrichment access not active" }, "422": { "description": "Validation error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/smart-enrichment/statistics": { "get": { "tags": [ "Smart Enrichment" ], "summary": "Lookup statistics", "description": "Aggregated Smart Enrichment statistics for the authenticated company: headline totals (lookups, items, matches, match rate, average confidence), a time series, and breakdowns by source, outcome and confidence band. Read-only. Defaults to the last 12 months and a monthly interval.", "operationId": "e8eca054b53eafbd132f4c0c835bb6dd", "parameters": [ { "name": "date_from", "in": "query", "description": "Inclusive lower bound (Y-m-d). Defaults to 12 months ago.", "required": false, "schema": { "type": "string", "format": "date" } }, { "name": "date_to", "in": "query", "description": "Inclusive upper bound (Y-m-d). Defaults to today. Must be >= date_from.", "required": false, "schema": { "type": "string", "format": "date" } }, { "name": "interval", "in": "query", "description": "Time-series bucket size. Defaults to month.", "required": false, "schema": { "type": "string", "enum": [ "day", "week", "month" ] } } ], "responses": { "200": { "description": "Statistics", "content": { "application/json": { "schema": { "properties": { "range": { "properties": { "date_from": { "type": "string", "format": "date" }, "date_to": { "type": "string", "format": "date" }, "interval": { "type": "string", "example": "month" } }, "type": "object" }, "totals": { "properties": { "jobs": { "type": "integer", "example": 42 }, "items": { "type": "integer", "example": 120 }, "found": { "type": "integer", "example": 96 }, "found_rate": { "type": "number", "format": "float", "example": 80 }, "avg_confidence": { "type": "number", "format": "float", "example": 87.4 } }, "type": "object" }, "time_series": { "type": "array", "items": { "properties": { "bucket": { "type": "string", "example": "2026-06" }, "jobs": { "type": "integer" }, "items": { "type": "integer" }, "found": { "type": "integer" } }, "type": "object" } }, "by_source": { "type": "array", "items": { "properties": { "source": { "type": "string", "example": "api" }, "jobs": { "type": "integer" }, "found": { "type": "integer" } }, "type": "object" } }, "by_outcome": { "type": "array", "items": { "properties": { "outcome": { "type": "string", "example": "found" }, "count": { "type": "integer" } }, "type": "object" } }, "confidence_buckets": { "type": "array", "items": { "properties": { "bucket": { "type": "string", "example": "high" }, "count": { "type": "integer" } }, "type": "object" } } }, "type": "object" } } } }, "403": { "description": "Smart Enrichment access not active" }, "422": { "description": "Validation error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/smart-enrichment/{jobId}": { "get": { "tags": [ "Smart Enrichment" ], "summary": "Get a lookup job", "description": "Returns a single or bulk Smart Enrichment job by id. A single lookup returns a flat result; a bulk job returns per-item results plus progress counters.", "operationId": "7d9006b73411dfd236036d37b0185d4b", "parameters": [ { "name": "jobId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Job result", "content": { "application/json": { "schema": { "oneOf": [ { "$ref": "#/components/schemas/SmartEnrichmentResult" }, { "properties": { "jobId": { "type": "string", "format": "uuid" }, "status": { "type": "string", "example": "completed" }, "itemCount": { "type": "integer" }, "completedCount": { "type": "integer" }, "foundCount": { "type": "integer" }, "results": { "type": "array", "items": { "$ref": "#/components/schemas/SmartEnrichmentResultItem" } } }, "type": "object" } ] } } } }, "403": { "description": "Smart Enrichment access not active" }, "404": { "description": "Job not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/smart-enrichment/{jobId}/recheck": { "post": { "tags": [ "Smart Enrichment" ], "summary": "Check rows again", "description": "Searches again for result rows without a usable answer (`not_found`, or a number registered to another company). Every recheck counts as a check like a new lookup (Deep Verify ×2), whether a VAT number is found or not. A row can be rechecked up to 3 times, with 7 days between two rechecks; `no_vat_exists` and found rows are never rechecked. Without `rows`, every row that qualifies is rechecked. Responds 202; each row that improves is delivered via the `enrichment.updated` webhook, and `GET /v1/smart-enrichment/{jobId}` shows the progress under `recheck`. Pass `dryRun: true` to see what would run and what it costs without starting anything.", "operationId": "f076c35aafd4c1a672471a6b1345c461", "parameters": [ { "name": "jobId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "properties": { "rows": { "description": "0-based row indexes of the lookup; omit for every row that qualifies", "type": "array", "items": { "type": "integer", "minimum": 0 }, "nullable": true }, "dryRun": { "type": "boolean", "example": false } }, "type": "object" } } } }, "responses": { "202": { "description": "Rechecks queued (200 for a dry run)", "content": { "application/json": { "schema": { "properties": { "jobId": { "type": "string", "format": "uuid" }, "rows": { "description": "Rows that are (or would be) rechecked", "type": "array", "items": { "type": "integer" } }, "checks": { "description": "Checks these rechecks use", "type": "integer", "example": 12 }, "skipped": { "description": "Rows left out, by reason: resolved, no_vat_exists, limit_reached, cooldown, running, pending", "type": "object", "example": { "cooldown": 2 } }, "dryRun": { "type": "boolean" } }, "type": "object" } } } }, "404": { "description": "Job not found" }, "422": { "description": "Nothing to recheck, the lookup is still running, or not available (sandbox, flat-fee import)" }, "429": { "description": "Start credit used up or monthly hard cap reached" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/tenants/me/entitlements": { "get": { "tags": [ "Tenant" ], "summary": "Get tenant entitlements and quota", "operationId": "1fe39dd17d02efe57675f1346f2a1d6a", "responses": { "200": { "description": "Entitlements" }, "401": { "description": "Unauthorized" }, "500": { "description": "Server error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/tax-numbers/check": { "post": { "tags": [ "VAT" ], "summary": "Check German and Austrian Steuernummern (format, check digit, tax office)", "description": "Up to 1,000 numbers per call. DE: ELSTER rules — the 13-digit ELSTER form or the 10/11-digit form from tax letters (`states` lists the federal states whose rules it fits; `elster`/`formatted` are only set when that is unambiguous). AT: 9 digits, check digit; `taxOfficeKnown` says whether the 2-digit tax office prefix is one in use. `valid` = such a number can exist; no authority confirms which company it belongs to (tax secrecy). Not counted as VAT checks.", "operationId": "9aa12e036620764d04595a3f2f3b9855", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "items" ], "properties": { "items": { "type": "array", "items": { "required": [ "country", "taxNumber" ], "properties": { "country": { "type": "string", "enum": [ "DE", "AT" ], "example": "DE" }, "taxNumber": { "type": "string", "example": "133/8150/8159" } }, "type": "object" } } }, "type": "object" } } } }, "responses": { "200": { "description": "One result per item, in order.", "content": { "application/json": { "schema": { "properties": { "results": { "type": "array", "items": { "properties": { "taxNumber": { "type": "string", "example": "133/8150/8159" }, "country": { "type": "string", "example": "DE" }, "valid": { "type": "boolean", "example": true }, "reason": { "description": "Why it is not valid.", "type": "string", "enum": [ "format", "check_digit", "unsupported_country" ], "nullable": true }, "formatted": { "type": "string", "example": "133/8150/8159", "nullable": true }, "elster": { "type": "string", "example": "5133081508159", "nullable": true }, "states": { "type": "array", "items": { "type": "string", "example": "NW" } }, "taxOffice": { "type": "string", "example": "5133", "nullable": true }, "taxOfficeKnown": { "type": "boolean", "nullable": true } }, "type": "object" } } }, "type": "object" } } } }, "422": { "description": "Invalid input or more than 1,000 items." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/bulk-checks": { "get": { "tags": [ "VAT" ], "summary": "Recent bulk VAT checks", "operationId": "81ea5e7f7f9754a6debcedba24ba42e1", "responses": { "200": { "description": "Newest first, 20 per page (`page` query)." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] }, "post": { "tags": [ "VAT" ], "summary": "Check many VAT IDs at once", "description": "Queues up to 1,000 VAT IDs (optionally with company name and address for the name match). Duplicates are checked once, malformed IDs are reported as `invalid_format` and not counted. Every other ID counts as one check; when the remaining monthly quota is smaller than that, nothing is queued (429, `quota_insufficient`). Poll GET /v1/vat/bulk-checks/{id} for progress and results.", "operationId": "5bc7305a7b643380aa62a76022d3eccd", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "items" ], "properties": { "name": { "type": "string", "example": "Kunden Oktober", "nullable": true }, "items": { "type": "array", "items": { "required": [ "vatUid" ], "properties": { "vatUid": { "type": "string", "example": "ATU63964918" }, "companyName": { "type": "string", "nullable": true }, "street": { "type": "string", "nullable": true }, "postalCode": { "type": "string", "nullable": true }, "city": { "type": "string", "nullable": true } }, "type": "object" } } }, "type": "object" } } } }, "responses": { "202": { "description": "Queued; the summary of the bulk check plus `duplicatesRemoved`." }, "409": { "description": "Not available in the sandbox environment." }, "422": { "description": "Invalid input or more than 1,000 IDs." }, "429": { "description": "`quota_insufficient` (with `remaining` and `needed`) or `subscription_inactive`." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/bulk-checks/quota": { "get": { "tags": [ "VAT" ], "summary": "VAT checks left this month (what a bulk check may use)", "operationId": "22c1d229130e1a69f99471d2c393c787", "responses": { "200": { "description": "`remaining` checks and the `maxItems` per upload." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/bulk-checks/{id}": { "get": { "tags": [ "VAT" ], "summary": "Progress and results of a bulk VAT check", "operationId": "72e8a40e0a92f5d52d03e9695697893d", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "The summary plus `items` (see VatBulkCheckItem), in upload order." }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/bulk-checks/{id}/retry": { "post": { "tags": [ "VAT" ], "summary": "Check the rows of a bulk check again that could not be checked", "description": "Rows with `error` (authority unreachable) or `quota_exceeded` are queued again; each counts as one check. Refused while the upload is still running (409) or when the quota cannot cover them (429 `quota_insufficient`).", "operationId": "7d60717e78c65a9d209486ac94d2891f", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "202": { "description": "Queued again; the summary plus `retried`." }, "409": { "description": "Still running, or nothing to retry." }, "429": { "description": "`quota_insufficient` with `remaining` and `needed`." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/bulk-checks/{id}/export": { "get": { "tags": [ "VAT" ], "summary": "Results of a bulk VAT check as CSV", "operationId": "b0da79c56efa1182fe809222ee2a7e85", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "CSV with vatUid, companyName, status, vatValid, officialName, official address, nameMatch, taxNumber, taxNumberName, taxNumberSource, checkedAt, historyUuid." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/validate": { "post": { "tags": [ "VAT" ], "summary": "Validate a VAT UID", "description": "Checks if a VAT UID is valid. If the AI company-name score is near zero and addressLine1 or addressLine2 is provided, Taxora retries scoring with the address line candidate and keeps the better deterministic result.", "operationId": "43a39536cf6714e12f99cf2910b92043", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "vat_uid" ], "properties": { "vat_uid": { "description": "The VAT UID to validate", "type": "string", "example": "ATU12345678" }, "company_name": { "description": "The company name to validate against the VAT UID", "type": "string", "example": "Example Company GmbH" }, "addressLine1": { "description": "Optional first address line. Used as fallback company-name candidate only when company_name scoring is near zero.", "type": "string", "maxLength": 255, "example": "Example Company GmbH", "nullable": true }, "addressLine2": { "description": "Optional second address line.", "type": "string", "maxLength": 255, "example": "Second Floor", "nullable": true }, "postalCode": { "description": "Optional postal code.", "type": "string", "maxLength": 32, "example": "1010", "nullable": true }, "city": { "description": "Optional city.", "type": "string", "maxLength": 120, "example": "Vienna", "nullable": true }, "countryCode": { "description": "Optional ISO 3166-1 alpha-2 country code.", "type": "string", "maxLength": 2, "minLength": 2, "example": "AT", "nullable": true }, "provider": { "description": "The VAT provider to use for validation. Possible values: 'fon' (Fon), 'vies' (Vies), 'france_vat' (France VAT), 'anaf' (ANAF), 'uk_hmrc' (UK HMRC), 'no_brreg' (Norwegian Brønnøysund register, for NO numbers), 'ch_uid' (Swiss UID register, for CHE numbers), 'ai_search' (AI Search), 'fon_vies_ai_search' (Fon + Vies + AI Search), 'uk_hmrc_ai_search' (UK HMRC + AI Search), 'no_brreg_ai_search' (Brønnøysund + AI Search), 'ch_uid_ai_search' (UID register + AI Search), 'fon_ai_search' (Fon + AI Search), 'fon_vies' (Fon + Vies), 'vies_ai_search' (Vies + AI Search). Default is null.", "type": "string", "example": "vies" } }, "type": "object" }, "examples": { "standardCompanyName": { "summary": "Standard request", "value": { "vat_uid": "ATU12345678", "company_name": "Example Company GmbH", "provider": "vies" } }, "addressLine1FallbackWins": { "summary": "Sandbox: addressLine1 fallback wins", "value": { "vat_uid": "ATU44000001", "company_name": "John Doe", "addressLine1": "Fallback Line One Trading GmbH", "postalCode": "1020", "city": "Wien", "countryCode": "AT", "provider": "sandbox" } }, "addressLine2FallbackWins": { "summary": "Sandbox: addressLine2 fallback wins", "value": { "vat_uid": "DE440000002", "company_name": "John Doe", "addressLine2": "Fallback Line Two Systems GmbH", "postalCode": "20095", "city": "Hamburg", "countryCode": "DE", "provider": "sandbox" } }, "fallbackAttemptedPrimaryKept": { "summary": "Sandbox: fallback attempted but primary kept", "value": { "vat_uid": "FR44000000003", "company_name": "John Doe", "addressLine1": "45 Avenue des Tests", "postalCode": "69002", "city": "Lyon", "countryCode": "FR", "provider": "sandbox" } }, "noFallbackHelp": { "summary": "Sandbox: no fallback help", "value": { "vat_uid": "IT44000000004", "company_name": "John Doe", "postalCode": "40121", "city": "Bologna", "countryCode": "IT", "provider": "sandbox" } } } } } }, "responses": { "200": { "description": "VAT UID is valid", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VatResource" } } } }, "400": { "description": "Invalid input" }, "422": { "description": "Invalid VAT number: wrong format, failing check digit or unsupported country. The error message names the reason." }, "500": { "description": "Internal Server Error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/validate-multiple": { "post": { "tags": [ "VAT" ], "summary": "Validate multiple VAT UIDs", "description": "Checks if multiple VAT UIDs are valid and returns their validation status.", "operationId": "8041f39590ae674006068ac6728a42ea", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "vat_uids" ], "properties": { "vat_uids": { "description": "An array of VAT UIDs to validate", "type": "array", "items": { "type": "string", "example": "ATU12345678" } }, "company_names": { "description": "An optional array of company names to validate against the VAT UIDs (order should match vat_uids array)", "type": "array", "items": { "type": "string", "example": "Example Company GmbH" } }, "provider": { "description": "The VAT provider to use for validation. Possible values: 'fon' (Fon), 'vies' (Vies), 'france_vat' (France VAT), 'anaf' (ANAF), 'uk_hmrc' (UK HMRC), 'no_brreg' (Norwegian Brønnøysund register, for NO numbers), 'ch_uid' (Swiss UID register, for CHE numbers), 'ai_search' (AI Search), 'fon_vies_ai_search' (Fon + Vies + AI Search), 'uk_hmrc_ai_search' (UK HMRC + AI Search), 'no_brreg_ai_search' (Brønnøysund + AI Search), 'ch_uid_ai_search' (UID register + AI Search), 'fon_ai_search' (Fon + AI Search), 'fon_vies' (Fon + Vies), 'vies_ai_search' (Vies + AI Search). Default is null.", "type": "string", "example": "vies" } }, "type": "object" } } } }, "responses": { "200": { "description": "List of validated VAT UIDs", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/VatResource" } } } } }, "400": { "description": "Invalid input" }, "422": { "description": "Invalid VAT number: wrong format, failing check digit or unsupported country. The error message names the reason." }, "500": { "description": "Internal Server Error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/validate-schema": { "post": { "tags": [ "VAT" ], "summary": "Validate VAT UID Schema", "description": "Validates if the given VAT UID follows the correct format and schema based on country-specific VAT rules.", "operationId": "0c6f5ab7ce400a008bcbbe256b230fa5", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "vat_uid" ], "properties": { "vat_uid": { "description": "The VAT UID to be validated", "type": "string", "maxLength": 20, "example": "ATU12345678" } }, "type": "object" } } } }, "responses": { "200": { "description": "VAT UID validation result", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "valid": { "description": "Indicates whether the VAT UID is valid", "type": "boolean", "example": true }, "message": { "description": "Descriptive validation message", "type": "string", "example": "Valid VAT UID." } }, "type": "object" } }, "type": "object" } } } }, "400": { "description": "Bad Request - Invalid Input", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": false }, "error": { "type": "string", "example": "Invalid format: A VAT UID must start with two uppercase letters." } }, "type": "object" } } } }, "500": { "description": "Internal Server Error", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": false }, "error": { "type": "string", "example": "Unexpected error occurred." } }, "type": "object" } } } } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/state": { "post": { "tags": [ "VAT" ], "summary": "Get the state of a VAT UID", "description": "Retrieves the current state of a VAT UID.", "operationId": "c2d2868b5628ecc5ec3e4eb03642988c", "parameters": [ { "name": "vat_uid", "in": "query", "description": "VAT UID to check", "required": true, "schema": { "type": "string", "example": "ATU12345678" } } ], "responses": { "200": { "description": "VAT State retrieved successfully", "content": { "application/json": { "schema": { "properties": { "state": { "type": "string", "example": "VALID" } }, "type": "object" } } } }, "400": { "description": "Invalid VAT UID" }, "500": { "description": "Internal Server Error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/history": { "post": { "tags": [ "VAT" ], "summary": "Get VAT history", "description": "Retrieves VAT history entries. Supports filtering by VAT UID, search term, and date range with pagination.", "operationId": "56a36f5aba3cca9c80ade16dfbaf3afb", "parameters": [ { "name": "vat_uid", "in": "query", "description": "VAT UID to retrieve history for (optional)", "required": false, "schema": { "type": "string", "example": "ATU12345678" } }, { "name": "search", "in": "query", "description": "Search term: if it's a valid VAT UID, performs an exact VAT UID match; otherwise searches by company name", "required": false, "schema": { "type": "string", "example": "Example GmbH" } }, { "name": "from_date", "in": "query", "description": "Filter results from this date (YYYY-MM-DD). If no date range is supplied and no VAT UID is specified, defaults to the last 12 months.", "required": false, "schema": { "type": "string", "format": "date", "example": "2025-01-01" } }, { "name": "to_date", "in": "query", "description": "Filter results up to this date (YYYY-MM-DD). If no date range is supplied and no VAT UID is specified, defaults to the last 12 months.", "required": false, "schema": { "type": "string", "format": "date", "example": "2026-01-01" } }, { "name": "perPage", "in": "query", "description": "Number of results per page", "required": false, "schema": { "type": "integer", "example": 30 } } ], "responses": { "200": { "description": "VAT History retrieved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VatCollection" } } } }, "500": { "description": "Internal Server Error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/history/{uuid}": { "get": { "tags": [ "VAT" ], "summary": "Get VAT history detail", "description": "Retrieves a single VAT history entry by its UUID. Supports fetching from sandbox when environment is SANDBOX.", "operationId": "49791e9a7d381291252c94b3a2101f59", "parameters": [ { "name": "uuid", "in": "path", "description": "UUID of the VAT history entry", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "environment", "in": "query", "description": "Select the environment to read from. Defaults to LIVE.", "required": false, "schema": { "type": "string", "enum": [ "LIVE", "SANDBOX", "DEV" ] } } ], "responses": { "200": { "description": "VAT history entry retrieved", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/VatResource" } }, "type": "object" } } } }, "401": { "description": "Not authorized" }, "404": { "description": "History entry not found" }, "503": { "description": "Sandbox not configured" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/history/fon-xml": { "get": { "tags": [ "VAT" ], "summary": "Download FON XML for VAT history entries", "description": "Returns the FON XML containing only the requested VAT history entries. All entries must belong to the same FON XML document.", "operationId": "f405dab0f7e992ac0dd25e4b7d114217", "parameters": [ { "name": "uuids", "in": "query", "description": "VAT history UUIDs to include", "required": true, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string", "format": "uuid" } } } ], "responses": { "200": { "description": "Filtered FON XML", "content": { "application/xml": { "schema": { "type": "string", "format": "binary" } } } }, "401": { "description": "Not authorized", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Not authorized!" } }, "type": "object" } } } }, "404": { "description": "History entry not found", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "VAT history entry not found." } }, "type": "object" } } } }, "422": { "description": "Invalid request", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "History entry is not backed by a FON XML document." } }, "type": "object" } } } } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/search": { "post": { "tags": [ "VAT" ], "summary": "Search VAT records", "description": "Find VAT records based on search filters.", "operationId": "8b7fad4d7378d51885af890961d39f90", "parameters": [ { "name": "search", "in": "query", "description": "Search term to filter VAT records", "required": false, "schema": { "type": "string", "example": "Company Name" } }, { "name": "perPage", "in": "query", "description": "Number of results per page", "required": false, "schema": { "type": "integer", "example": 30 } } ], "responses": { "200": { "description": "VAT search results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VatCollection" } } } }, "500": { "description": "Internal Server Error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/certificate": { "post": { "tags": [ "VAT" ], "summary": "Generate VAT Confirmation Certificate", "description": "Generates a downloadable PDF certificate for a validated VAT ID based on the provided UUID. The certificate language defaults to English if not specified.", "operationId": "generateVatCertificate", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "uuid" ], "properties": { "uuid": { "description": "Unique identifier of the VAT validation request.", "type": "string", "example": "d7b4f3a9-8c23-4f8d-94a1-b1a90c8f254c" }, "lang": { "description": "(Optional) Language for the generated PDF certificate. Allowed values: 'en' (English), 'de' (German). Defaults to 'en' if not provided.", "type": "string", "example": "en", "nullable": true } }, "type": "object" } } } }, "responses": { "200": { "description": "PDF file generated successfully", "headers": { "Content-Type": { "description": "application/pdf", "schema": { "type": "string" } } }, "content": { "application/pdf": { "schema": { "type": "string", "format": "binary" } } } }, "400": { "description": "Validation Error", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "The given data was invalid." }, "errors": { "properties": { "uuid": { "type": "array", "items": { "type": "string", "example": "The selected uuid is invalid." } }, "lang": { "type": "array", "items": { "type": "string", "example": "The selected language is invalid. Allowed values: 'en', 'de'." } } }, "type": "object" } }, "type": "object" } } } }, "404": { "description": "UUID not found", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "UUID not found." } }, "type": "object" } } } }, "500": { "description": "Server Error", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Internal Server Error." } }, "type": "object" } } } } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/certificates/bulk-export": { "post": { "tags": [ "VAT" ], "summary": "Initiate Bulk Export of VAT Certificates", "description": "Initiates an asynchronous process to export multiple VAT certificates for a company within a date range. The process generates a ZIP file containing all certificates and sends an email with a download link when complete.", "operationId": "initiateVatCertificatesBulkExport", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "from_date", "to_date" ], "properties": { "from_date": { "description": "Start date for the export range (YYYY-MM-DD)", "type": "string", "format": "date", "example": "2023-01-01" }, "to_date": { "description": "End date for the export range (YYYY-MM-DD)", "type": "string", "format": "date", "example": "2023-12-31" }, "countries": { "description": "Optional array of country codes to filter by (e.g. ['DE', 'AT'])", "type": "array", "items": { "type": "string" }, "nullable": true }, "lang": { "description": "Optional language for the certificates. Allowed values: 'en' (English), 'de' (German). Defaults to 'en' if not provided.", "type": "string", "example": "en", "nullable": true }, "include_documents": { "description": "Include provider documents (combined XML, screenshots as zip entries) in the export archive", "type": "boolean", "example": false } }, "type": "object" } } } }, "responses": { "202": { "description": "Export process initiated successfully", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "VAT certificates export initiated. You will receive an email with a download link when the export is complete." }, "export_id": { "description": "Unique identifier for the export job", "type": "string", "example": "f47ac10b-58cc-4372-a567-0e02b2c3d479" } }, "type": "object" } } } }, "400": { "description": "Validation Error", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "The given data was invalid." }, "errors": { "properties": { "from_date": { "type": "array", "items": { "type": "string", "example": "The from date field is required." } }, "to_date": { "type": "array", "items": { "type": "string", "example": "The to date field is required." } }, "lang": { "type": "array", "items": { "type": "string", "example": "The selected language is invalid. Allowed values: 'en', 'de'." } } }, "type": "object" } }, "type": "object" } } } }, "500": { "description": "Server Error", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Internal Server Error." } }, "type": "object" } } } } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/certificates/download/{exportId}": { "get": { "tags": [ "VAT" ], "summary": "Download VAT Certificates Export", "description": "Downloads the requested VAT certificates export (ZIP archive with certificates or single PDF list) if it belongs to the authenticated company.", "operationId": "downloadVatCertificatesBulkExport", "parameters": [ { "name": "exportId", "in": "path", "description": "The unique identifier of the export job", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "ZIP archive with certificates or single PDF list", "headers": { "Content-Type": { "description": "application/zip or application/pdf", "schema": { "type": "string" } } }, "content": { "application/zip": { "schema": { "type": "string", "format": "binary" } }, "application/pdf": { "schema": { "type": "string", "format": "binary" } } } }, "400": { "description": "Bad Request", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Invalid export ID" } }, "type": "object" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Export job does not belong to the company" } }, "type": "object" } } } }, "404": { "description": "Not Found", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Export job not found" } }, "type": "object" } } } }, "500": { "description": "Server Error", "content": { "application/json": { "schema": { "properties": { "error": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Internal Server Error" } }, "type": "object" } } } } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/certificates/list-export": { "post": { "tags": [ "VAT" ], "summary": "Initiate List Export of VAT Checks", "description": "Initiates an asynchronous process that creates a single PDF listing VAT checks in the given period.", "operationId": "initiateVatCertificatesListExport", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "from_date", "to_date" ], "properties": { "from_date": { "type": "string", "format": "date", "example": "2023-01-01" }, "to_date": { "type": "string", "format": "date", "example": "2023-12-31" }, "countries": { "type": "array", "items": { "type": "string" }, "nullable": true }, "lang": { "type": "string", "example": "en", "nullable": true }, "include_documents": { "description": "Include provider documents (combined XML, screenshots as zip entries) in the export archive", "type": "boolean", "example": false } }, "type": "object" } } } }, "responses": { "202": { "description": "Export initiated" }, "400": { "description": "Validation Error" }, "500": { "description": "Server Error" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/verify/{uuid}": { "get": { "tags": [ "VAT" ], "summary": "Verify a VAT certificate", "description": "Validates the verification token and returns the VAT request data associated with the certificate UUID.", "operationId": "1f84d38d186ec9e8c612b179dc15ae3b", "parameters": [ { "name": "uuid", "in": "path", "description": "UUID of the VAT request history record", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "token", "in": "query", "description": "HMAC verification token from the QR code", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Verification successful", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/VatResource" } }, "type": "object" } } } }, "400": { "description": "Validation error" }, "403": { "description": "Invalid verification token" }, "404": { "description": "VAT verification record not found" } } } }, "/v1/vat/history/export": { "get": { "tags": [ "VAT" ], "summary": "VAT checks as CSV, with the columns and format you choose", "description": "Every VAT check of your company (single, bulk and the checks behind Smart Enrichment), newest first. `columns[]` picks and orders the columns (see GET /v1/vat/history/export/columns); `delimiter` comma|semicolon|tab; `language` en|de for the header; `date_format` iso|datetime|de; `timezone` e.g. Europe/Vienna; `latest_only=1` keeps one row per VAT ID. Filters: `from`, `to` (Y-m-d), `search`, `statuses[]`, `countries[]`. Not counted as checks.", "operationId": "5468ef45e819963ca500088a66bc71ac", "parameters": [ { "name": "columns[]", "in": "query", "schema": { "type": "array", "items": { "type": "string", "example": "vat_number" } } }, { "name": "delimiter", "in": "query", "schema": { "type": "string", "enum": [ "comma", "semicolon", "tab" ] } }, { "name": "language", "in": "query", "schema": { "type": "string", "enum": [ "en", "de" ] } }, { "name": "date_format", "in": "query", "schema": { "type": "string", "enum": [ "iso", "datetime", "de" ] } }, { "name": "timezone", "in": "query", "schema": { "type": "string", "example": "Europe/Vienna" } }, { "name": "latest_only", "in": "query", "schema": { "type": "boolean" } }, { "name": "from", "in": "query", "schema": { "type": "string", "format": "date" } }, { "name": "to", "in": "query", "schema": { "type": "string", "format": "date" } }, { "name": "search", "in": "query", "schema": { "type": "string" } }, { "name": "statuses[]", "in": "query", "schema": { "type": "array", "items": { "type": "string", "enum": [ "valid", "invalid", "invalid_format", "fraud", "unknown" ] } } }, { "name": "countries[]", "in": "query", "schema": { "type": "array", "items": { "type": "string", "example": "DE" } } } ], "responses": { "200": { "description": "CSV, UTF-8 with BOM." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/history/export/preview": { "get": { "tags": [ "VAT" ], "summary": "The first rows of the VAT checks CSV, as JSON", "description": "Same parameters as /v1/vat/history/export. Returns `header` and up to 5 `rows`.", "operationId": "0fa5c2c758976eb68dfa6585df259261", "responses": { "200": { "description": "`header` and `rows`." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/history/export/columns": { "get": { "tags": [ "VAT" ], "summary": "Columns the VAT checks CSV can contain", "operationId": "11c983eff25b6e4f4bacdfb8180656e8", "responses": { "200": { "description": "`columns` (key, English and German header) and the `defaults`." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/history/export/templates": { "get": { "tags": [ "VAT" ], "summary": "Saved CSV export templates: yours and those shared in your company", "operationId": "c1015c70269d66f630d5888dc7d8a5ac", "responses": { "200": { "description": "`templates`: id, name, shared, mine, owner, settings (columns, delimiter, language, date_format, latest_only)." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] }, "post": { "tags": [ "VAT" ], "summary": "Save a CSV export template (same name = update)", "operationId": "a43a81d61ca08756a2ea5d043f5cf7cb", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "name", "settings" ], "properties": { "name": { "type": "string", "example": "For our ERP" }, "shared": { "description": "Visible to everyone in your company.", "type": "boolean" }, "settings": { "description": "columns[], delimiter, language, date_format, latest_only", "type": "object" } }, "type": "object" } } } }, "responses": { "201": { "description": "The saved template." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/vat/history/export/templates/{id}": { "delete": { "tags": [ "VAT" ], "summary": "Delete a CSV export template (your own; shared ones also as company admin)", "operationId": "ece2f60fc85ae1e11e322ac72f1a37eb", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "204": { "description": "Deleted." }, "404": { "description": "Not found or not yours." } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/webhooks": { "get": { "tags": [ "Webhooks" ], "summary": "List webhook endpoints", "description": "Returns all webhook endpoints configured for the authenticated company.", "operationId": "251ec39272318a1b91510bc856f5fc9e", "responses": { "200": { "description": "List of webhook endpoints", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookEndpoint" } } }, "type": "object" } } } }, "401": { "description": "Not authorized" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] }, "post": { "tags": [ "Webhooks" ], "summary": "Create a webhook endpoint", "description": "Registers a new HTTPS endpoint. Set `signing_enabled` to have every request signed with a per-endpoint secret (`Taxora-Signature` header, HMAC-SHA256). The secret is returned in this response and can be revealed again later via `GET /v1/webhooks/{id}/signing/secret`.", "operationId": "41ce50fb0d496d307346c5aa76166bb2", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "url", "events" ], "properties": { "url": { "description": "Must be HTTPS", "type": "string", "format": "uri", "example": "https://your-server.com/taxora-webhook" }, "events": { "description": "Event types this endpoint subscribes to. At least one required.", "type": "array", "items": { "type": "string", "enum": [ "vat.validated", "vat.state_changed", "compliance.ledger.state_changed", "compliance.transaction.state_changed", "enrichment.completed", "enrichment.updated" ] }, "example": [ "vat.validated" ] }, "is_active": { "type": "boolean", "default": true }, "description": { "type": "string", "maxLength": 255, "example": "Production webhook", "nullable": true } }, "type": "object" } } } }, "responses": { "201": { "description": "Endpoint created.", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "endpoint": { "$ref": "#/components/schemas/WebhookEndpoint" }, "signing_secret": { "description": "Signing secret (only when signing_enabled was true), used to verify the Taxora-Signature header.", "type": "string", "example": "whsec_3b2kq0J8Xn1o0m7dJcF4l7Qp9sN2aV5eW6rT8yU1iO0", "nullable": true } }, "type": "object" } }, "type": "object" } } } }, "400": { "description": "Validation failed" }, "401": { "description": "Not authorized" }, "422": { "description": "Endpoint limit reached (max 20 per company)" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/webhooks/{id}": { "get": { "tags": [ "Webhooks" ], "summary": "Get a webhook endpoint", "operationId": "22931aeae54bd39fe9921ad9e491eb58", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Webhook endpoint", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/WebhookEndpoint" } }, "type": "object" } } } }, "401": { "description": "Not authorized" }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] }, "put": { "tags": [ "Webhooks" ], "summary": "Update a webhook endpoint", "description": "Partially update URL, event subscriptions, active state or description. All fields are optional.", "operationId": "25a2796d5623e7b6931773d543df8ad1", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "content": { "application/json": { "schema": { "properties": { "url": { "type": "string", "format": "uri" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "vat.validated", "vat.state_changed", "compliance.ledger.state_changed", "compliance.transaction.state_changed", "enrichment.completed", "enrichment.updated" ] } }, "is_active": { "type": "boolean" }, "description": { "type": "string", "nullable": true } }, "type": "object" } } } }, "responses": { "200": { "description": "Updated endpoint", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/WebhookEndpoint" } }, "type": "object" } } } }, "400": { "description": "Validation failed" }, "401": { "description": "Not authorized" }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] }, "delete": { "tags": [ "Webhooks" ], "summary": "Delete a webhook endpoint", "description": "Permanently deletes the endpoint and all its delivery records.", "operationId": "2bade0a3abd8228a02e86a39952955d7", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Deleted successfully" }, "401": { "description": "Not authorized" }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/webhooks/{id}/deliveries": { "get": { "tags": [ "Webhooks" ], "summary": "List delivery attempts", "description": "Returns the last 100 delivery attempts for this endpoint, newest first. Deliveries are retained for 30 days.", "operationId": "c26467ee5ce0dd2a39c746027eb2a146", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Paginated delivery log", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookDelivery" } }, "meta": { "properties": { "current_page": { "type": "integer" }, "per_page": { "type": "integer" }, "total": { "type": "integer" }, "last_page": { "type": "integer" } }, "type": "object" } }, "type": "object" } }, "type": "object" } } } }, "401": { "description": "Not authorized" }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/webhooks/{id}/test": { "post": { "tags": [ "Webhooks" ], "summary": "Send a test event", "description": "Dispatches a `webhook.test` delivery to verify your endpoint is reachable and correctly verifying the signature. Check the delivery log to see the outcome.", "operationId": "d2da11b123131e2a94f162da46e65307", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Test dispatched", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "properties": { "delivery_id": { "description": "UUID of the created delivery record", "type": "string", "format": "uuid" } }, "type": "object" } }, "type": "object" } } } }, "401": { "description": "Not authorized" }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/webhooks/{id}/signing/enable": { "post": { "tags": [ "Webhooks" ], "summary": "Enable signing", "description": "Turns on HMAC signing for this endpoint and returns the signing secret. Idempotent — an endpoint that is already signed keeps (and returns) its current secret. From now on every request carries `Taxora-Signature: t=,v1=`.", "operationId": "3ad266a7e2da4cdcaa78fbc8ee0ef662", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Signing enabled", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/WebhookSigningSecret" } }, "type": "object" } } } }, "401": { "description": "Not authorized" }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/webhooks/{id}/signing/disable": { "post": { "tags": [ "Webhooks" ], "summary": "Disable signing", "description": "Turns off signing and destroys all secrets of this endpoint. Requests are sent without `Taxora-Signature` afterwards; enabling again issues a new secret.", "operationId": "7b597e4ee009e96b002ccf2e1672089d", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Signing disabled", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/WebhookEndpoint" } }, "type": "object" } } } }, "401": { "description": "Not authorized" }, "404": { "description": "Not found" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/webhooks/{id}/signing/secret": { "get": { "tags": [ "Webhooks" ], "summary": "Reveal the signing secret", "description": "Returns the current signing secret of this endpoint.", "operationId": "44eae710bde179898df6c3c3a7c6f65d", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Current secret", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/WebhookSigningSecret" } }, "type": "object" } } } }, "401": { "description": "Not authorized" }, "404": { "description": "Not found" }, "409": { "description": "Signing is not enabled for this endpoint" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } }, "/v1/webhooks/{id}/signing/rotate": { "post": { "tags": [ "Webhooks" ], "summary": "Rotate the signing secret", "description": "Issues a new signing secret. The previous secret keeps signing for `expires_in_hours` (default 24, max 168): during that window each request carries two `v1=` signatures, so you can deploy the new secret without dropping events. `0` revokes the old secret immediately.", "operationId": "17815c08989d6c1050e772918a794666", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "content": { "application/json": { "schema": { "properties": { "expires_in_hours": { "description": "How long the previous secret stays valid", "type": "integer", "default": 24, "maximum": 168, "minimum": 0 } }, "type": "object" } } } }, "responses": { "200": { "description": "New secret", "content": { "application/json": { "schema": { "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/WebhookSigningSecret" } }, "type": "object" } } } }, "400": { "description": "Validation failed" }, "401": { "description": "Not authorized" }, "404": { "description": "Not found" }, "409": { "description": "Signing is not enabled for this endpoint" } }, "security": [ { "bearerAuth": [], "ApiKeyAuth": [] } ] } } }, "components": { "schemas": { "ComplianceEnrollment": { "properties": { "id": { "type": "integer", "example": 12 }, "company_id": { "type": "integer", "example": 42 }, "country": { "type": "string", "example": "fr" }, "regime": { "description": "Provider regime: dgfip_flux10 (France), peppol_bis3 (Norway, EHF over Peppol)", "type": "string", "example": "dgfip_flux10" }, "service": { "description": "Service booked for this country", "type": "string", "enum": [ "e_reporting", "e_invoicing" ], "example": "e_reporting" }, "provider": { "type": "string", "example": "b2brouter" }, "status": { "type": "string", "example": "regime_activated" }, "status_label": { "type": "string", "example": "Regime activated" }, "status_error": { "type": "string", "nullable": true }, "provider_account_id": { "type": "string", "example": "83428" }, "tax_id": { "type": "string", "example": "FR32123456789" }, "company_register_id": { "type": "string", "example": "12345678900012" }, "company_register_scheme": { "type": "string", "example": "0009" }, "regime_config": { "type": "object", "example": { "naf_code": "47", "enterprise_size": "pme", "type_operation": "mixed" } }, "reporting_start_date": { "type": "string", "format": "date", "example": "2026-09-01" }, "notification_email": { "type": "string", "example": "tax@acme.fr" }, "auto_send": { "type": "boolean", "example": true } }, "type": "object" }, "SmartEnrichmentResultItem": { "properties": { "status": { "description": "`no_vat_exists` = the company exists but legitimately has no VAT/UID (not an error, not billed).", "type": "string", "enum": [ "found", "no_vat_exists", "not_found", "processing" ], "example": "found" }, "vatNumber": { "type": "string", "example": "ATU12345678", "nullable": true }, "vatType": { "type": "string", "example": "ust_idnr", "nullable": true }, "vatValid": { "description": "Only on `found`: the tax authority's verdict on the number (FinanzOnline / BZSt / VIES / national registers). Null when no official check ran.", "type": "boolean", "example": true, "nullable": true }, "aiScore": { "description": "Only on `found`: 0–100, how well the requested company name matches the name the register has for the number. Null when the register discloses no name (e.g. DE/AT via VIES).", "type": "number", "format": "float", "example": 18, "nullable": true }, "nameMatch": { "description": "Only on `found`: `ok` = the requested name matches the register; `mismatch` = it does not — the number belongs to a different company, unless `registeredOwner` is set (then it is the right business filed under its owner and your record should be updated). Null when no name was disclosed.", "type": "string", "enum": [ "ok", "mismatch" ], "example": "mismatch", "nullable": true }, "officialName": { "description": "Only on `found`: the name the register has the number under. Write it into your records when `nameMatch` is `mismatch`.", "type": "string", "example": "Seibel Kevin", "nullable": true }, "officialAddress": { "description": "Only on `found`: the registered address the official check returned, field by field. Null where the register discloses none.", "properties": { "street": { "type": "string", "example": "Beethovenstr. 2" }, "postal_code": { "type": "string", "example": "67258" }, "city": { "type": "string", "example": "Heßheim" }, "country": { "type": "string", "example": "DE" } }, "type": "object", "nullable": true }, "taxNumber": { "description": "The company's LOCAL tax / business number, in its national notation without spaces — what domestic e-invoicing asks for (PL NIP, IT Partita IVA, FR SIREN, ES NIF, BE enterprise number …). On `found` it is read off the confirmed VAT ID where that country's VAT ID contains it (`taxNumberSource` = `vat_id`). Otherwise it is a domestic number the company itself publishes, e.g. a German or Austrian Steuernummer on its Impressum (`taxNumberSource` = `company_website`) — that one is not a VAT ID, cannot be used as one, and no authority confirms it. Null when there is none.", "type": "string", "example": "123456789", "nullable": true }, "taxNumberType": { "description": "What `taxNumber` is. Null when there is none.", "type": "string", "enum": [ "fr_siren", "fr_siret", "it_partita_iva", "es_nif", "pl_nip", "be_enterprise_number", "dk_cvr", "pt_nif", "ro_cui", "cz_ico", "sk_dic", "se_orgnr", "no_orgnr", "fi_business_id", "si_tax_number", "hr_oib", "bg_eik", "gr_afm", "de_steuernummer", "at_steuernummer", "domestic_tax_number" ], "example": "fr_siren", "nullable": true }, "taxNumberLabel": { "description": "The number's name in its country (SIREN, NIP, Steuernummer …), for display.", "type": "string", "example": "SIREN", "nullable": true }, "taxNumberSource": { "description": "Where `taxNumber` comes from: `vat_id` = read off the VAT ID the tax authority confirmed (exact); `company_website` = published by the company itself (found, not officially confirmable).", "type": "string", "enum": [ "vat_id", "company_website" ], "example": "vat_id", "nullable": true }, "confidence": { "description": "0–100", "type": "number", "format": "float", "example": 96, "nullable": true }, "matchedCompanyName": { "type": "string", "example": "Example Company GmbH", "nullable": true }, "matchedAddress": { "description": "Official/registered address of the matched company, when available.", "type": "string", "example": "Hauptstraße 10, 1010 Wien, AT", "nullable": true }, "country": { "type": "string", "example": "AT", "nullable": true }, "source": { "type": "string", "example": "corpus", "nullable": true }, "sourceUrl": { "description": "Only on `found`: the web page the VAT number was read from — usually the company's own Impressum / legal notice. Null when the number came from our own data or a register.", "type": "string", "format": "uri", "example": "https://kawelke-abschlepp.de/Impressum", "nullable": true }, "sourceUrls": { "description": "Only on `found`: every page the VAT number was read from, `sourceUrl` first — the independent research passes that found the same number each contribute theirs. At most 5; empty for any other status.", "type": "array", "items": { "type": "string", "format": "uri" }, "example": [ "https://kawelke-abschlepp.de/Impressum", "https://www.northdata.de/Kawelke" ] }, "registeredOwner": { "description": "Only on `found`, when the tax authority has the VAT ID under a PERSON rather than the trading name — typical for a German sole proprietorship (e.K.). The number was confirmed for that owner, who is named in the company's Impressum; `matchedCompanyName` stays the trading name.", "type": "string", "example": "Kevin Seibel", "nullable": true }, "mode": { "description": "The search mode this lookup actually ran in.", "type": "string", "enum": [ "default", "complex" ], "example": "default", "nullable": true }, "providerVerdicts": { "description": "What each independent research pass concluded. Populated when more than one pass ran (complex mode, or a fallback). Two passes reporting the same vatNumber is the strongest confirmation this layer produces.", "type": "array", "items": { "properties": { "provider": { "description": "The kind of research pass.", "type": "string", "enum": [ "ai_search", "ai_search_independent", "source_research", "address_correction" ], "example": "source_research" }, "model": { "description": "Always null; kept for compatibility.", "type": "string", "example": null, "nullable": true }, "status": { "type": "string", "example": "found" }, "vatNumber": { "type": "string", "example": "DE811704788", "nullable": true }, "confidence": { "type": "number", "format": "float", "example": 92, "nullable": true }, "grounded": { "description": "Whether the answer was backed by a real web search rather than model memory.", "type": "boolean", "example": true }, "sourceUrl": { "type": "string", "nullable": true } }, "type": "object" }, "nullable": true }, "addressQuality": { "description": "What we made of the address you submitted. Use `warnings` to correct your own records — `postal_code_city_mismatch` and `postal_code_unassigned` mean the postal code you sent is wrong, and `derivedPlace` is where it actually points.", "properties": { "providedPostalCode": { "type": "string", "example": "40547", "nullable": true }, "providedCity": { "type": "string", "example": "Düsseldorf", "nullable": true }, "postalCodeFormatValid": { "type": "boolean", "example": true, "nullable": true }, "postalCodeAssigned": { "type": "boolean", "example": true, "nullable": true }, "postalCodeTrusted": { "description": "False when the postal code was excluded from the search because it is malformed, non-existent, or contradicts the city.", "type": "boolean", "example": true }, "derivedPlace": { "description": "The city/region the postal code points at.", "type": "string", "example": "Düsseldorf", "nullable": true }, "cityMatchesPostalCode": { "type": "boolean", "example": true, "nullable": true }, "warnings": { "type": "array", "items": { "type": "string", "example": "postal_code_city_mismatch" } } }, "type": "object", "nullable": true }, "rejectedCandidates": { "description": "Only on `not_found`: VAT numbers the research did name but the official check threw out. `vat_invalid` = the tax authority reports the number as not (or no longer) valid; `name_mismatch` = valid, but registered to a different company; `unbound`/`unverified` = could not be tied to the company or could not be checked.", "type": "array", "items": { "properties": { "vatNumber": { "type": "string", "example": "DE176664507" }, "reason": { "type": "string", "enum": [ "vat_invalid", "name_mismatch", "unbound", "unverified", "rejected" ], "example": "vat_invalid" }, "vatValidationUuid": { "description": "The stored official VAT check of this number (open it with GET /v1/vat/history/{uuid}). Set for real VAT IDs only, not for domestic tax numbers.", "type": "string", "format": "uuid", "nullable": true }, "vatValid": { "description": "The authority's verdict in that stored check.", "type": "boolean", "nullable": true } }, "type": "object" } } }, "type": "object" }, "SmartEnrichmentResult": { "description": "Single-lookup response: a job id plus the resolved result fields.", "type": "object", "allOf": [ { "properties": { "jobId": { "type": "string", "format": "uuid" } }, "type": "object" }, { "$ref": "#/components/schemas/SmartEnrichmentResultItem" } ] }, "SmartEnrichmentHistoryRow": { "properties": { "jobId": { "type": "string", "format": "uuid" }, "status": { "type": "string", "example": "found" }, "isBulk": { "type": "boolean", "example": false }, "itemCount": { "type": "integer", "example": 1 }, "foundCount": { "type": "integer", "example": 1 }, "query": { "properties": { "companyName": { "type": "string", "nullable": true }, "country": { "type": "string", "nullable": true }, "city": { "type": "string", "nullable": true } }, "type": "object" }, "input": { "description": "Full first input (incl. street + postalCode) for the detail view.", "properties": { "companyName": { "type": "string", "nullable": true }, "street": { "type": "string", "nullable": true }, "postalCode": { "type": "string", "nullable": true }, "city": { "type": "string", "nullable": true }, "country": { "type": "string", "nullable": true } }, "type": "object", "nullable": true }, "result": { "oneOf": [ { "$ref": "#/components/schemas/SmartEnrichmentResultItem" } ], "nullable": true }, "createdAt": { "type": "string", "format": "date-time", "nullable": true }, "finishedAt": { "type": "string", "format": "date-time", "nullable": true }, "startedAt": { "description": "When processing began; null while still queued.", "type": "string", "format": "date-time", "nullable": true }, "queueSeconds": { "description": "Seconds between submission and the start of processing.", "type": "integer", "nullable": true }, "runSeconds": { "description": "Seconds spent researching and confirming.", "type": "integer", "nullable": true }, "durationSeconds": { "description": "Total seconds from submission to result; null until finished.", "type": "integer", "nullable": true } }, "type": "object" }, "VatBulkCheckItem": { "properties": { "position": { "description": "Bulk VAT checks: many VAT IDs at once, checked in the background. Each number becomes a normal\nstored VAT check (VAT history, documents, `vat.validated` webhook) and counts as one check.", "type": "integer", "example": 0 }, "vatUid": { "type": "string", "example": "PL5260250995" }, "companyName": { "type": "string", "example": "Polskie Fabryki Sp. z o.o.", "nullable": true }, "status": { "description": "`invalid_format` = not a VAT ID (never sent, not counted); `error` = the authority could not be reached (not counted); `quota_exceeded` = the monthly quota ran out first (not counted).", "type": "string", "enum": [ "pending", "valid", "invalid", "unconfirmed", "error", "invalid_format", "quota_exceeded" ], "example": "valid" }, "vatValid": { "type": "boolean", "example": true, "nullable": true }, "officialName": { "type": "string", "nullable": true }, "officialAddress": { "type": "object", "nullable": true }, "nameMatch": { "description": "Only when a company name was given and the authority disclosed one.", "type": "string", "enum": [ "ok", "mismatch" ], "nullable": true }, "score": { "type": "number", "nullable": true }, "taxNumber": { "description": "The local tax number read off the confirmed VAT ID (see Smart Enrichment `taxNumber`).", "type": "string", "example": "5260250995", "nullable": true }, "taxNumberType": { "type": "string", "example": "pl_nip", "nullable": true }, "taxNumberLabel": { "type": "string", "example": "NIP", "nullable": true }, "taxNumberSource": { "type": "string", "example": "vat_id", "nullable": true }, "message": { "type": "string", "nullable": true }, "historyUuid": { "description": "The stored VAT check (GET /v1/vat/history/{uuid}).", "type": "string", "nullable": true }, "checkedAt": { "type": "string", "format": "date-time", "nullable": true } }, "type": "object" }, "WebhookEndpoint": { "properties": { "id": { "type": "integer", "example": 1 }, "url": { "type": "string", "format": "uri", "example": "https://your-server.com/taxora-webhook" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "vat.validated", "vat.state_changed", "compliance.ledger.state_changed", "compliance.transaction.state_changed", "enrichment.completed", "enrichment.updated" ] }, "example": [ "vat.validated", "compliance.ledger.state_changed" ] }, "is_active": { "type": "boolean", "example": true }, "description": { "type": "string", "example": "Production webhook", "nullable": true }, "signing": { "$ref": "#/components/schemas/WebhookSigning" }, "created_at": { "type": "string", "format": "date-time", "example": "2026-05-20T10:00:00+00:00" }, "updated_at": { "type": "string", "format": "date-time", "example": "2026-05-20T10:00:00+00:00" } }, "type": "object" }, "WebhookSigning": { "description": "Opt-in HMAC signing state. Never contains the secret — use GET /v1/webhooks/{id}/signing/secret.", "properties": { "enabled": { "description": "When true every request carries a Taxora-Signature header", "type": "boolean", "example": true }, "secret_hint": { "description": "Last 4 characters of the current secret", "type": "string", "example": "x9Qa", "nullable": true }, "secret_created_at": { "type": "string", "format": "date-time", "nullable": true }, "previous_secret_expires_at": { "description": "Set while a rotated-out secret still signs (rotation grace period)", "type": "string", "format": "date-time", "nullable": true } }, "type": "object" }, "WebhookSigningSecret": { "properties": { "secret": { "description": "HMAC-SHA256 key. Use the full string including the whsec_ prefix.", "type": "string", "example": "whsec_3b2kq0J8Xn1o0m7dJcF4l7Qp9sN2aV5eW6rT8yU1iO0" }, "signing": { "$ref": "#/components/schemas/WebhookSigning" } }, "type": "object" }, "WebhookDelivery": { "properties": { "id": { "description": "Delivery UUID — also present as 'id' in the sent payload", "type": "string", "format": "uuid", "example": "550e8400-e29b-41d4-a716-446655440000" }, "event_type": { "type": "string", "example": "vat.validated" }, "status": { "type": "string", "enum": [ "pending", "delivered", "failed" ], "example": "delivered" }, "payload": { "description": "The exact JSON body sent to your endpoint", "type": "object" }, "http_status": { "type": "integer", "example": 200, "nullable": true }, "response_body": { "description": "First 4 096 bytes of your endpoint's response body", "type": "string", "nullable": true }, "attempts": { "type": "integer", "example": 1 }, "delivered_at": { "type": "string", "format": "date-time", "nullable": true }, "created_at": { "type": "string", "format": "date-time" } }, "type": "object" }, "UserResource": { "title": "User Resource", "description": "Authenticated user resource with permissions", "properties": { "id": { "type": "integer", "example": 1 }, "uuid": { "type": "string", "format": "uuid", "example": "550e8400-e29b-41d4-a716-446655440000" }, "company_uuid": { "type": "string", "format": "uuid", "nullable": true }, "company": { "oneOf": [ { "$ref": "#/components/schemas/CompanyResource" } ], "nullable": true }, "stripe_id": { "type": "string", "nullable": true }, "pm_type": { "type": "string", "nullable": true }, "pm_last_four": { "type": "string", "nullable": true }, "trial_ends_at": { "type": "string", "format": "date-time", "nullable": true }, "name": { "type": "string", "example": "John Doe" }, "email": { "type": "string", "format": "email", "example": "john@example.com", "nullable": true }, "client_id": { "type": "string", "example": "client_abc123", "nullable": true }, "state": { "type": "string", "example": "active" }, "type": { "type": "string", "example": "default" }, "email_verified_at": { "type": "string", "format": "date-time", "nullable": true }, "current_team_id": { "type": "integer", "nullable": true }, "permissions": { "description": "List of permissions assigned to the user", "type": "array", "items": { "type": "object" } }, "avatar_url": { "type": "string", "nullable": true }, "profile": { "type": "object" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } }, "type": "object" }, "CompanyResource": { "title": "Company Resource", "properties": { "id": { "type": "integer", "example": 1 }, "uuid": { "type": "string", "format": "uuid", "example": "550e8400-e29b-41d4-a716-446655440000" }, "name": { "type": "string", "example": "Taxora GmbH" }, "vat_uid": { "type": "string", "example": "ATU12345678" }, "address_line_1": { "type": "string", "nullable": true }, "address_line_2": { "type": "string", "nullable": true }, "street": { "type": "string", "nullable": true }, "zip_code": { "type": "string", "nullable": true }, "city": { "type": "string", "nullable": true }, "country_code": { "type": "string", "example": "AT", "nullable": true }, "email": { "type": "string", "format": "email", "example": "office@taxora.com" }, "phone_number": { "type": "string", "nullable": true }, "rate_limit": { "description": "Legacy alias for vat_rate_limit. Deprecated; use api_rate_limit and vat_rate_limit instead.", "type": "integer", "example": 100, "deprecated": true }, "api_rate_limit": { "description": "Configured monthly API request limit for the company.", "type": "integer", "example": 100 }, "vat_rate_limit": { "description": "Configured monthly VAT validation limit for the company.", "type": "integer", "example": 100 }, "billing_provider": { "description": "Internal billing entitlement provider for the company.", "type": "string", "example": "manual", "nullable": true }, "billing_status": { "description": "Internal billing entitlement status for the company.", "type": "string", "example": "active", "nullable": true }, "state": { "type": "string", "example": "active" }, "source": { "type": "string", "example": "web" }, "source_ref": { "type": "string", "nullable": true }, "vat_history_valid_threshold_override": { "type": "integer", "example": 60, "nullable": true }, "vat_history_valid_threshold_effective": { "type": "integer", "example": 50 }, "subscription_plan": { "type": "string", "example": "free" }, "trial_ends_at": { "type": "string", "format": "date-time", "nullable": true }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } }, "type": "object" }, "UsageSummary": { "properties": { "id": { "type": "integer", "example": 123 }, "company_id": { "type": "integer", "example": 1 }, "feature": { "type": "string", "example": "ereporting_transaction" }, "country": { "type": "string", "example": "FR", "nullable": true }, "regime": { "type": "string", "nullable": true }, "billing_period": { "type": "string", "example": "2026-06" }, "event_count": { "type": "integer", "example": 500 }, "billable_amount": { "type": "string", "example": "49.00", "nullable": true }, "state": { "type": "string", "example": "open", "nullable": true }, "state_label": { "type": "string", "example": "Open", "nullable": true }, "period_closed_at": { "type": "string", "format": "date-time", "nullable": true }, "billing_triggered_at": { "type": "string", "format": "date-time", "nullable": true }, "billed_at": { "type": "string", "format": "date-time", "nullable": true }, "stripe_invoice_id": { "type": "string", "nullable": true }, "stripe_subscription_item_id": { "type": "string", "nullable": true }, "billing_notes": { "type": "string", "nullable": true }, "events": { "type": "array", "items": { "type": "object" } }, "created_at": { "type": "string", "format": "date-time", "nullable": true }, "updated_at": { "type": "string", "format": "date-time", "nullable": true } }, "type": "object" }, "VatSandboxTestData": { "title": "Sandbox VAT Test Data", "description": "Static VAT UIDs available in sandbox and development environments for testing integration flows.", "properties": { "valid_vat_uids": { "description": "VAT numbers that always return a valid response in sandbox/development mode.", "type": "array", "items": { "type": "string" }, "example": [ "ATU12345678", "DE123456789", "FR99345678901", "IT12398765432", "GB999999973", "ATU44000001", "DE440000002", "FR44000000003", "IT44000000004", "ATU00000000", "DE222222220", "FR11223344556", "IT55667788990" ] }, "invalid_vat_uids": { "description": "VAT numbers that always return an invalid response in sandbox/development mode.", "type": "array", "items": { "type": "string" }, "example": [ "ATU99999999", "DE000000000", "FR00000000000", "IT00000000000", "GB000000000" ] }, "notes": { "description": "Additional guidance for consumers using the sandbox test UIDs.", "type": "string", "example": "Use these VAT numbers when calling /v1/vat/validate or /v1/vat/validate-multiple in sandbox or development environments to receive deterministic mock responses. Address fallback simulator examples: ATU44000001 returns Fallback Line One Trading GmbH, Testgasse 11, 1020 Wien, AT; send company_name=John Doe plus addressLine1=Fallback Line One Trading GmbH and the sandbox will force a zero primary company_name score and a winning addressLine1 fallback, so requested_company_name becomes Fallback Line One Trading GmbH and score_source=addressLine1Fallback. DE440000002 returns Fallback Line Two Systems GmbH, Musterstrasse 22, 20095 Hamburg, DE; send company_name=John Doe plus addressLine2=Fallback Line Two Systems GmbH and the sandbox will force addressLine2Fallback to win. FR44000000003 returns Primary Keeps Adresse SAS, 45 Avenue des Tests, 69002 Lyon, FR; send company_name=John Doe plus addressLine1=45 Avenue des Tests to observe fallback attempted with two score_attempts but score_source remaining companyName. IT44000000004 returns No Fallback Support SRL, Via Prova 9, 40121 Bologna, IT; send company_name=John Doe without helpful address lines to observe score_source=companyName and a single score_attempt. Extra deterministic score examples: ATU00000000(score=0, official provider valid), DE222222220(score=20), FR11223344556(score=60), IT55667788990(score=80)." } }, "type": "object" }, "VatCollection": { "title": "VAT Collection", "description": "A collection of VAT records", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/VatResource" } }, "links": { "description": "Pagination links (present when paginated).", "properties": { "first": { "type": "string", "example": "https://api.taxora.io/api/v1/vat/history?page=1" }, "last": { "type": "string", "example": "https://api.taxora.io/api/v1/vat/history?page=10" }, "prev": { "type": "string", "example": null, "nullable": true }, "next": { "type": "string", "example": "https://api.taxora.io/api/v1/vat/history?page=2", "nullable": true } }, "type": "object" }, "meta": { "description": "Pagination meta (present when paginated).", "properties": { "current_page": { "type": "integer", "example": 1 }, "from": { "type": "integer", "example": 1 }, "last_page": { "type": "integer", "example": 10 }, "path": { "type": "string", "example": "https://api.taxora.io/api/v1/vat/history" }, "per_page": { "type": "integer", "example": 30 }, "to": { "type": "integer", "example": 30 }, "total": { "type": "integer", "example": 300 }, "links": { "type": "array", "items": { "properties": { "url": { "type": "string", "example": "https://api.taxora.io/api/v1/vat/history?page=1", "nullable": true }, "label": { "type": "string", "example": "1" }, "page": { "type": "integer", "example": 1, "nullable": true }, "active": { "type": "boolean", "example": true } }, "type": "object" } } }, "type": "object" } }, "type": "object" }, "VatResource": { "title": "VAT Resource", "description": "Response structure for a VAT request", "properties": { "uuid": { "description": "Unique identifier for the VAT record", "type": "string", "format": "uuid", "example": "550e8400-e29b-41d4-a716-446655440000" }, "vat_uid": { "description": "The validated VAT UID", "type": "string", "example": "ATU12345678" }, "state": { "description": "State of the VAT number (e.g., VALID, INVALID, NOT_FOUND)", "type": "string", "example": "VALID" }, "country_code": { "description": "Country code of the VAT registration", "type": "string", "example": "AT" }, "company_name": { "description": "Registered company name for the VAT number", "type": "string", "example": "Example GmbH" }, "company_address": { "description": "Registered company address", "type": "string", "example": "Musterstraße 12, 1010 Wien, Austria" }, "provider": { "description": "Upstream provider used to process the VAT request when available", "type": "string", "example": "vies", "nullable": true }, "used_providers": { "description": "Collection of upstream providers that participated in the validation run", "type": "array", "items": { "type": "string" }, "example": [ "fon", "vies" ], "nullable": true }, "valid_providers": { "description": "Providers that explicitly reported the VAT as valid in this history snapshot.", "type": "array", "items": { "type": "string" }, "example": [ "fon" ], "nullable": true }, "invalid_providers": { "description": "Providers that explicitly reported the VAT as invalid in this history snapshot.", "type": "array", "items": { "type": "string" }, "example": [ "vies" ], "nullable": true }, "provider_audit": { "description": "Immutable per-provider audit snapshot captured for this history entry.", "type": "object", "nullable": true }, "requested_company_name": { "description": "Effective company-name candidate used for scoring. If addressLine1 fallback was selected, this equals addressLine1.", "type": "string", "example": "Example Company GmbH", "nullable": true }, "requested_company_name_original": { "description": "Original company_name received from the API request.", "type": "string", "example": "John Doe", "nullable": true }, "requested_input_address": { "description": "Normalized address input received from the API request.", "properties": { "addressLine1": { "type": "string", "example": "Example Company GmbH", "nullable": true }, "addressLine2": { "type": "string", "example": "Second Floor", "nullable": true }, "postalCode": { "type": "string", "example": "1010", "nullable": true }, "city": { "type": "string", "example": "Vienna", "nullable": true }, "countryCode": { "type": "string", "example": "AT", "nullable": true } }, "type": "object", "nullable": true }, "checked_at": { "description": "Timestamp of the last VAT check", "type": "string", "format": "date-time", "example": "2024-01-19T12:45:00Z" }, "environment": { "description": "Environment where the VAT validation was executed (e.g. LIVE or SANDBOX)", "type": "string", "example": "LIVE" }, "score": { "description": "Risk Score! 100 OK, 50 Could be fraud...", "type": "number", "format": "float", "example": 100 }, "breakdown": { "description": "Detailed breakdown of the score calculation", "type": "array", "items": { "properties": { "type": { "type": "string", "example": "AI Name Comparison" }, "step_type": { "type": "string", "example": "AiNameComparisonStep" }, "score": { "type": "integer", "example": 25 }, "valid": { "type": "boolean", "example": true }, "summary": { "type": "string", "example": "Company names match" }, "code": { "type": "string", "example": "MATCH" }, "details": { "type": "array", "items": { "type": "string" } }, "notes": { "type": "object" } }, "type": "object" } }, "score_source": { "description": "Source used for the final AI name score (companyName, addressLine1Fallback, or addressLine2Fallback).", "type": "string", "example": "companyName", "nullable": true }, "score_attempts": { "description": "Debug view of executed score attempts.", "type": "array", "items": { "properties": { "source": { "type": "string", "example": "companyName" }, "score": { "type": "number", "format": "float", "example": 0 } }, "type": "object" }, "nullable": true }, "provider_valid": { "description": "Official provider verdict for this response when available: true for valid, false for invalid, null when no official provider verdict could be determined.", "type": "boolean", "example": true, "nullable": true }, "provider_vat_state": { "description": "Latest VAT state reported by the upstream provider when available", "type": "string", "example": "VALID", "nullable": true }, "provider_note": { "description": "Explanatory note included when the provider state differs from the validation result", "type": "string", "example": "Provider reports VAT Number is valid, but the check failed (e.g., name/address mismatch).", "nullable": true }, "provider_last_checked_at": { "description": "Timestamp of the most recent upstream provider confirmation", "type": "string", "format": "date-time", "example": "2024-01-19T12:40:00Z", "nullable": true }, "has_api_error": { "description": "True when at least one provider encountered a technical/API failure during the latest validation run.", "type": "boolean", "example": true, "nullable": true }, "error_message": { "description": "Primary technical error message captured for the latest validation run when available.", "type": "string", "example": "VIES service unavailable.", "nullable": true }, "next_api_recheck_at": { "description": "Scheduled retry time when the latest validation result was preserved because official providers returned only API errors.", "type": "string", "format": "date-time", "example": "2026-04-24T14:00:00Z", "nullable": true }, "provider_document": { "description": "Deprecated: use provider_documents instead. This field will be removed in the next API version. For history entries, the document is resolved via explicit history links and may exist without a provider request.", "properties": { "id": { "type": "integer", "example": 123 }, "provider": { "type": "string", "example": "fon" }, "document_type": { "type": "string", "example": "fon_daily_xml" }, "state": { "type": "string", "example": "imported" }, "document_date": { "type": "string", "format": "date", "example": "2025-12-08" }, "check_date": { "type": "string", "format": "date", "example": "2025-12-08" }, "mime": { "type": "string", "example": "application/xml" }, "size": { "type": "integer", "example": 12345 }, "hash": { "type": "string", "example": "abc123" }, "meta": { "type": "object", "nullable": true }, "line": { "properties": { "id": { "type": "integer", "example": 456 }, "vat_uid": { "type": "string", "example": "ATU12345678" }, "row_number": { "type": "integer", "example": 12 }, "entry_identifier": { "type": "string", "example": "1" }, "reference": { "type": "string", "example": "FONREF" }, "meta": { "type": "object", "nullable": true } }, "type": "object", "nullable": true } }, "type": "object", "nullable": true, "deprecated": true }, "provider_documents": { "description": "All linked provider documents (may include multiple providers/types). For history entries, links are created even when no provider request exists.", "type": "array", "items": { "properties": { "id": { "type": "integer", "example": 123 }, "provider": { "type": "string", "example": "vies" }, "document_type": { "type": "string", "example": "vies_screenshot" }, "state": { "type": "string", "example": "imported" }, "document_date": { "type": "string", "format": "date", "example": "2025-12-08" }, "check_date": { "type": "string", "format": "date", "example": "2025-12-08" }, "mime": { "type": "string", "example": "application/json" }, "size": { "type": "integer", "example": 12345 }, "hash": { "type": "string", "example": "abc123" }, "meta": { "type": "object", "nullable": true }, "line": { "properties": { "id": { "type": "integer", "example": 456 }, "vat_uid": { "type": "string", "example": "ATU12345678" }, "row_number": { "type": "integer", "example": 12 }, "entry_identifier": { "type": "string", "example": "1" }, "reference": { "type": "string", "example": "FONREF" }, "meta": { "type": "object", "nullable": true } }, "type": "object", "nullable": true } }, "type": "object" }, "nullable": true } }, "type": "object" } }, "securitySchemes": { "ApiKeyAuth": { "type": "apiKey", "description": "API key required for all requests. Provide the key via the x-api-key header.", "name": "x-api-key", "in": "header" }, "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "JWT access token returned by /v1/login. Use as Authorization: Bearer ." } } }, "tags": [ { "name": "Company", "description": "API Endpoints for managing companies" }, { "name": "Authentication", "description": "Obtain and refresh the Bearer token used by session-bound endpoints." }, { "name": "Billing", "description": "Read-only usage summaries for billable modules." }, { "name": "Compliance", "description": "E-reporting and e-invoicing: enrol a country, record and submit transactions, read tax reports, and look up companies in national registers or Peppol." }, { "name": "Reports", "description": "Scheduled report jobs and their generated runs." }, { "name": "Smart Enrichment", "description": "Reverse VAT lookup: find the VAT number for a company name and country. Jobs run asynchronously; poll the job or use the SDK helper to wait for completion." }, { "name": "Tenant", "description": "Entitlements of the authenticated tenant." }, { "name": "VAT", "description": "Endpoints related to VAT operations. Sandbox & development environment users can reference the VatSandboxTestData schema for ready-to-use test VAT UIDs." }, { "name": "Webhooks", "description": "Configure outgoing webhook endpoints and inspect delivery history" } ], "security": [ { "ApiKeyAuth": [] } ] }