Nordlet

Docs / Guides

EU VAT engine

Place-of-supply resolution, OSS/IOSS returns, SME exemption and distance-sales thresholds.

Cross-border VAT treatment for EU/EEA sales: place-of-supply resolution, reverse charge, marketplace deemed-supplier handling, per-country rate reference, and OSS/IOSS returns. Everything below is API-first; scopes shown per endpoint.

Rate reference

POST /v1/reference/eu-vat-rates/list (reference:read) — statutory VAT rates for all EU-27, filterable by countryCode and date. Rate-validity windows are tracked from 2024-01-01 (EE 24 % from 2025-07, RO 21 %/11 % from 2025-08, SK 23 %/19 % from 2025-01, FI 13.5 % and LT 12 % from 2026-01, CZ 12 % from 2024-01).

Source: European Commission "Taxes in Europe" database (TEDB, https://ec.europa.eu/taxation_customs/tedb/), retrieved 2026-07-16; Lithuanian 2026 changes confirmed against VMI (https://www.vmi.lt/evmi/pvm-tarifai), Finnish 2026 change against vero.fi. Scope: mainland/standard-territory rates only — regional variants (Austrian Jungholz, Greek islands, Azores/Madeira, French overseas territories and Corsica) are not modelled.

POST /v1/reference/vat-classifiers/list now returns a countryCode per classifier (existing i.SAF PVM* codes are LT); POST /v1/reference/vat-classifiers/upsert (reference:write) loads classifier sets for additional countries — the data path for future country packs.

Treatment resolution

POST /v1/reference/vat/resolve (reference:read) answers "what VAT do I charge?" for a supply. Input: partnerId or customerCountryCode (+ optional customerIsBusiness override — inferred from the partner's VAT code otherwise), supplyType (goods | services | digital), date, and situation flags: belowDistanceSalesThreshold, facilitatedByMarketplace (you sell through a deemed-supplier platform), actingAsMarketplace (you are the platform), sellerEstablishedInEu, importedConsignmentValueEur.

Output: scheme, vatCountryCode, reverseCharge, deemedSupplier, zeroRated, the destination country's rate menu, the legal basis (Directive 2006/112/EC article), and advisory notes (e.g. a reminder that the art. 138 exemption needs a VIES-valid customer VAT number).

Rules implemented:

Situation Result
Same-country supply domestic, home rates
Intra-EU B2B goods intra_eu_b2b — zero-rated art. 138 supply, customer self-accounts
Intra-EU B2B services reverse_charge — art. 44/196
Intra-EU B2C goods/digital above €10 000 oss_union — destination rates, art. 33(a)/58
Intra-EU B2C below €10 000 (belowDistanceSalesThreshold) domestic at origin, art. 59c
Intra-EU B2C general services domestic, art. 45
Goods to non-EU export — zero-rated art. 146(1)
Services/digital to non-EU out_of_scope (art. 44/59)
Sale via deemed-supplier marketplace (facilitatedByMarketplace) marketplace_deemed — zero-rated art. 136a supply to the platform
Imported consignment ≤ €150 B2C ioss — destination VAT at sale, art. 369l–369x; deemed supplier when actingAsMarketplace (art. 14a(1))
Exempt small enterprise (company is not a VAT payer), domestic supply sme_exempt — no VAT, art. 284(1)
Exempt small enterprise, cross-border EU B2C, holds a cross-border EX number sme_exempt — art. 284(2); valid while below the destination threshold and €100 000 Union turnover
Exempt small enterprise, cross-border EU B2C, no EX number keeps oss_union/origin with a note that a cross-border EX number would make it exempt

The €10 000 threshold (art. 59c) can be passed explicitly as belowDistanceSalesThreshold; when omitted, the engine tracks it automatically from ledger data (see the threshold endpoint below) and annotates the resolution with the running totals.

SME exemption (Directive 2020/285, from 2025). When the company is not a registered VAT payer the resolver treats it as a small enterprise using the exemption: domestic supplies resolve to sme_exempt (no VAT), and cross-border EU B2C supplies resolve to sme_exempt too when the company holds a cross-border EX number (smeExemptionNumber on the company profile) — otherwise it keeps the normal OSS/origin treatment with a note suggesting the cross-border scheme. Eligibility (staying below the destination threshold and the €100 000 Union-wide turnover cap) is the filer's responsibility; the resolver flags it in the notes. Set the EX number via account/companies/update (smeExemptionNumber).

Invoices

sales/invoices/create|update accept vatScheme (one of the schemes above), vatCountryCode (the Member State of consumption; required and validated as EU for oss_union/ioss) and deemedSupplier. E-commerce orders accept shipToCountryCode and marketplace; orders/fulfill resolves the treatment from the ship-to country automatically and stamps the draft invoice (assumes goods and an exceeded distance-sales threshold — adjust the draft before issuing if not).

OSS / IOSS returns

POST /v1/declarations/eu/oss/compute (declarations:read) { year, quarter } — Union-scheme quarterly return per Annex III of Commission Implementing Regulation (EU) 2020/194: rows per Member State of consumption × rate type (STANDARD/REDUCED) × rate with taxable amount and VAT, credit notes netted, plus totals. Only issued documents with vatScheme: "oss_union" are included. Warnings flag non-statutory rates for the destination and period, skipped zero-rated lines, documents without vatCountryCode, and supplies taxed in the Member State of identification.

POST /v1/declarations/eu/ioss/compute { year, month } — the same shape monthly for vatScheme: "ioss" (imported consignments ≤ €150).

Both responses carry a corrections array (plus correctionsTotal): a credit note issued in the current period but linked (via creditedInvoiceId) to an original from an earlier OSS/IOSS period is moved out of the period rows and reported as a prior-period correction — country, original year, original quarter (OSS) or month (IOSS), and the negative VAT delta — as required by Annex III of 2020/194. Credit notes with no creditedInvoiceId are netted into the current period and flagged with a warning so they can be linked; corrections older than three years are flagged (art. 61 of Regulation 282/2011).

Available to any company established in the EU (not gated to LT).

Distance-sales threshold

POST /v1/declarations/eu/distance-sales-threshold/get (declarations:read) { date? } — tracks the art. 59c €10 000 union threshold from ledger data: current and preceding calendar-year totals of cross-border B2C distance sales (OSS-scheme invoices plus cross-border consumer invoices with no scheme), whether the company is still below the threshold, and the remaining headroom. Non-EUR documents are summed at document value with a warning. The VAT resolver consults this automatically when belowDistanceSalesThreshold is not supplied.

SME exemption thresholds

POST /v1/declarations/eu/sme-thresholds/list returns the per-Member-State domestic VAT exemption thresholds under Directive (EU) 2020/285 (the €85 000 national cap and €100 000 Union-turnover cap are included). Figures are taken from the Commission's SME portal country pages; where a national page defers to TEDB without a stated figure, the entry is null rather than guessed. Some thresholds are set in national currency (DKK/HUF/RON) and some countries publish sectoral thresholds (e.g. Ireland: services €42 500, goods €85 000).

POST /v1/declarations/eu/sme-threshold/get { date? } reports a non-VAT-payer company's position against its own country's threshold: current calendar-year turnover plus the preceding year's (precedingTurnover), status (below / approaching at 80% / exceeded, or not_applicable for a registered VAT payer, unknown when the threshold isn't on file or the currency differs), remaining headroom, and warnings. Quarantine advisories are included: exceeding the threshold flags the exemption as unavailable for the rest of the current and the following calendar year, and a company below the threshold this year but over it last year is warned that the exemption cannot be resumed until the year after (both years must stay below — art. 284(2) mechanics; the Union-turnover endpoint carries the same advisory for the €100 000 cap). For countries with a national intra-EU trigger — Lithuania's €14 000 for services supplied to and goods/services acquired from other Member States — the response includes an intraEu breakdown (acquisitions from EU suppliers + reverse-charge services supplied) with its own status and warning.

Cross-border SME scheme: Union turnover and quarterly report

POST /v1/declarations/eu/union-turnover/get { date? } tracks the €100 000 "turnover in the Union" cap for the cross-border SME scheme (art. 284(2)) from ledger data — the total value of supplies made within the EU (exports and out-of-scope supplies excluded) in the current and preceding calendar year — returning both years' totals, status, headroom, and warnings (not_applicable for a VAT payer).

POST /v1/declarations/eu/sme-cross-border-report/compute { year, quarter } produces the quarterly report an SME on the scheme owes its home Member State (art. 284b): the total value of supplies made in each Member State that quarter, one row per country (the member state of supply = the invoice's consumption country, else the partner's country, else home), plus the total. Non-EU supplies are excluded.

National VAT-return packs

POST /v1/declarations/eu/vat-return/packs/list enumerates the available country packs; POST /v1/declarations/eu/vat-return/compute { countryCode, year, month, months? } dispatches to the pack registered for that country and returns the return as numbered boxes ({ code, label, amount }) plus warnings, notes and the official source. Requires the company to be registered in that country (422 otherwise). Lithuania (FR0600) ships as the first pack, wrapping the existing FR0600 builder; further countries are added as data-only adapters once their official form layout is verified.

The older POST /v1/reports/oss rollup remains as a heuristic analytics view (partner-country based, no scheme required); the declaration endpoints are the filing-grade path. Both derive the home country from the company instead of assuming Lithuania.