OSS / IOSS return
OSS return validator (lines only; dispatch-country breakdown not implemented): the output is the set of return lines per member state of consumption, supply type and rate, checked against the rates table, not a filable return. Implementing Regulation (EU) 2020/194 Annex III also requires goods to be split by member state of dispatch or fixed establishment; the row model carries no dispatch country, so a seller shipping from stock in several member states cannot file from this output (assessment 2026-10-28). Send the quarter's (OSS) or month's (IOSS) B2C sales as JSON rows or as a CSV export (Content-Type: text/csv, header row in English, French or German; or JSON {period, scheme, csv}). Each row names the member state of consumption, the rate (or a rates-table category), the net amount, optionally the VAT amount, the supply date and the supply type. The service aggregates per member state, supply type and rate; validates every row against the dated rates table (the rate must be one the member state applies; a rate changed inside the table's window is accepted with a warning when the supply predates the change), reconciles VAT with net × rate, checks the dates against the period, and nets credit notes; rows marked correctionOfPeriod become the corrections section. Returns the per-country summary and the upload file. On 2026-10-24 no national portal format could be fetched (the BZSt publishes its CSV record layout only inside the logged-in form; the DGFiP publishes none), so the file is a clearly labelled generic CSV and portals[] says so per member state. Up to 50000 rows or 4.5 MB. Add ?output=csv to receive the file itself instead of JSON. Send an Idempotency-Key header (1–128 characters, unique per request) and a retry after a dropped response replays the stored answer for 24 hours without a second charge (Idempotent-Replayed: true); the same key with a different body or query is refused with 409 idempotency_conflict.
About the return file
The lines follow the content of the OSS return set by Implementing Regulation (EU) 2020/194: per member state of consumption, rate type and rate, the taxable amount and the VAT, plus corrections of earlier periods per member state. Rates are checked against the dated table (verified 2026-10-24). No national portal publishes a fetchable import specification for the first two member states of identification (France, Germany) as of 2026-10-24, so the file is a labelled generic CSV; the walkthrough is on the "OSS return: one file per quarter" page. 25 calls per accepted return; a 422 costs nothing; send an Idempotency-Key header and a retry replays the stored answer for 24 hours without being charged again. The endpoint validates lines; the dispatch-country breakdown is not implemented.
/vat/oss/returnOSS return validator (lines only; dispatch-country breakdown not implemented)
OSS return validator (lines only; dispatch-country breakdown not implemented): the output is the set of return lines per member state of consumption, supply type and rate, checked against the rates table, not a filable return. Implementing Regulation (EU) 2020/194 Annex III also requires goods to be split by member state of dispatch or fixed establishment; the row model carries no dispatch country, so a seller shipping from stock in several member states cannot file from this output (assessment 2026-10-28). Send the quarter's (OSS) or month's (IOSS) B2C sales as JSON rows or as a CSV export (Content-Type: text/csv, header row in English, French or German; or JSON {period, scheme, csv}). Each row names the member state of consumption, the rate (or a rates-table category), the net amount, optionally the VAT amount, the supply date and the supply type. The service aggregates per member state, supply type and rate; validates every row against the dated rates table (the rate must be one the member state applies; a rate changed inside the table's window is accepted with a warning when the supply predates the change), reconciles VAT with net × rate, checks the dates against the period, and nets credit notes; rows marked correctionOfPeriod become the corrections section. Returns the per-country summary and the upload file. On 2026-10-24 no national portal format could be fetched (the BZSt publishes its CSV record layout only inside the logged-in form; the DGFiP publishes none), so the file is a clearly labelled generic CSV and portals[] says so per member state. Up to 50000 rows or 4.5 MB. Add ?output=csv to receive the file itself instead of JSON. Send an Idempotency-Key header (1–128 characters, unique per request) and a retry after a dropped response replays the stored answer for 24 hours without a second charge (Idempotent-Replayed: true); the same key with a different body or query is refused with 409 idempotency_conflict.
- Tiers
- freecreditsplan
- Cost
- 25 calls per accepted return (0 when the rows are refused with 422; 0 on an Idempotency-Key replay)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| output | query | "json" | "csv" | json (default): summary, files and portal notes. csv: the generic CSV file alone, with Content-Disposition.Example: json |
| Idempotency-Key | header | string | Unique per request (a UUID will do; ^[A-Za-z0-9_.:-]{1,128}$). A retry with the same key, query and body replays the stored answer for 24 hours (Idempotent-Replayed: true) instead of building and charging a second return; another body under the same key is 409. |
Request body
Media types: application/json.
| Field | Type | Description |
|---|---|---|
| period* | string | 2026-Q3 for OSS (quarterly), 2026-09 for IOSS (monthly). |
| scheme | "union" | "non_union" | "import" | Default union. |
| rows* | OssSaleRow[] | |
| csv | string | Alternative to rows: the CSV text of the export. |
{
"period": "2026-Q3",
"scheme": "union",
"rows": [
{
"country": "DE",
"rate": 19,
"net": 1250,
"vat": 237.5,
"date": "2026-07-14",
"supplyType": "goods"
},
{
"country": "DE",
"rate": 7,
"net": 310,
"vat": 21.7,
"date": "2026-08-02",
"supplyType": "goods"
},
{
"country": "FR",
"category": "digital_services",
"net": 980,
"date": "2026-09-21"
},
{
"country": "IT",
"rate": 22,
"net": -45,
"vat": -9.9,
"date": "2026-05-30",
"correctionOfPeriod": "2026-Q2"
}
]
}Request
curl -X POST -H "Authorization: Bearer vp_live_YOUR_KEY" -H "Content-Type: application/json" \
-d '{"period":"2026-Q3","scheme":"union","rows":[{"country":"DE","rate":19,"net":1250,"vat":237.5,"date":"2026-07-14","supplyType":"goods"},{"country":"DE","rate":7,"net":310,"vat":21.7,"date":"2026-08-02","supplyType":"goods"},{"country":"FR","category":"digital_services","net":980,"date":"2026-09-21"},{"country":"IT","rate":22,"net":-45,"vat":-9.9,"date":"2026-05-30","correctionOfPeriod":"2026-Q2"}]}' \
"https://veriport.io/api/v1/vat/oss/return"Response 200
The return: lines, corrections, totals, the file, and what each portal accepts.
Media types: application/json, text/csv.
| Field | Type | Description |
|---|---|---|
| scheme* | "union" | "non_union" | "import" | |
| period* | object | |
| period.label | string | |
| period.kind | "quarter" | "month" | |
| period.start | string (date) | |
| period.end | string (date) | |
| period.dueDate | string (date) | Last day of the month following the period. |
| currency* | "EUR" | |
| lines* | object[] | |
| corrections* | object[] | |
| totals* | object | |
| totals.rows | integer | |
| totals.countries | integer | |
| totals.net | number | |
| totals.vat | number | |
| totals.correctionsVat | number | |
| totals.vatPayable | number | |
| byCountry | object[] | |
| rates | object | |
| rates.verifiedOn | string (date) | |
| warnings | object[] | |
| files* | object[] | |
| portals* | object[] |
{
"scheme": "union",
"period": {
"label": "2026-Q3",
"kind": "quarter",
"start": "2026-07-01",
"end": "2026-09-30",
"dueDate": "2026-10-31"
},
"currency": "EUR",
"lines": [
{
"country": "DE",
"countryName": "Germany",
"supplyType": "goods",
"rateKind": "standard",
"rate": 19,
"rows": 1,
"net": 1250,
"vat": 237.5,
"vatComputed": 237.5
},
{
"country": "DE",
"countryName": "Germany",
"supplyType": "goods",
"rateKind": "reduced",
"rate": 7,
"rows": 1,
"net": 310,
"vat": 21.7,
"vatComputed": 21.7
},
{
"country": "FR",
"countryName": "France",
"supplyType": "services",
"rateKind": "standard",
"rate": 20,
"rows": 1,
"net": 980,
"vat": 196,
"vatComputed": 196
}
],
"corrections": [
{
"period": "2026-Q2",
"country": "IT",
"countryName": "Italy",
"rows": 1,
"vat": -9.9,
"net": -45
}
],
"totals": {
"rows": 4,
"countries": 2,
"net": 2540,
"vat": 455.2,
"correctionsVat": -9.9,
"vatPayable": 445.3
},
"byCountry": [
{
"country": "DE",
"countryName": "Germany",
"net": 1560,
"vat": 259.2
},
{
"country": "FR",
"countryName": "France",
"net": 980,
"vat": 196
}
],
"rates": {
"verifiedOn": "2026-10-24"
},
"warnings": [],
"files": [
{
"id": "generic_csv",
"filename": "oss-return-union-2026-Q3-generic.csv",
"contentType": "text/csv; charset=utf-8",
"portal": null,
"content": "period,scheme,member_state,member_state_name,supply_type,rate_kind,rate_percent,taxable_amount_eur,vat_amount_eur,rows,correction_of_period\r\n2026-Q3,union,DE,Germany,goods,standard,19,1250.00,237.50,1,\r\n…"
}
],
"portals": [
{
"memberState": "FR",
"portal": "impots.gouv.fr — guichet unique TVA (espace professionnel)",
"status": "generic",
"note": "No public file-import specification was found; key the lines in."
},
{
"memberState": "DE",
"portal": "BZStOnline-Portal (Mein BOP)",
"status": "generic",
"note": "CSV import exists; its record layout is published only inside the logged-in form."
}
]
}Headers: RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, RateLimit-Policy, X-Quota-Remaining, X-Tier.
Errors
- 400
invalid_parameter— A parameter is missing or malformed. - 401
unauthorized— The API key is missing, unknown or revoked. - 402
quota_exceeded— Monthly allowance and credits are used up. - 409
idempotency_conflict— The Idempotency-Key is in use. - 413
payload_too_large— Too many rows or too many bytes. - 422
unprocessable_file— The uploaded rows cannot be turned into a return. - 429
rate_limited— Too many requests per second.
Sources
- Commission Implementing Regulation (EU) 2020/194 — the OSS/IOSS VAT return: content per member state of consumption, rate type, rate, taxable amount, VAT amount, corrections (Annex III) — European Commission (EUR-Lex), consulted 2026-10-24
- One Stop Shop — guide to the VAT OSS: declare and pay, quarterly periods, corrections in a later return — European Commission, DG TAXUD, consulted 2026-10-24
- BZSt — One-Stop-Shop, EU-Regelung: elektronische Abgabe der Steuererklärung im BZStOnline-Portal, wahlweise mit Import-Funktion — Bundeszentralamt für Steuern, consulted 2026-10-24. The page confirms a CSV import function for the OSS return; the record layout (Datensatztabelle) is published only inside the logged-in form’s import help, so this build could not fetch it. The German file is therefore the labelled generic CSV, written to the public BOP CSV rules.
- BZStOnline-Portal (Mein BOP) — Allgemeine Anleitung zur Erstellung von CSV-Dateien für die Importfunktion (UTF-8, one separator , or ;, decimal point, #v version line) — ELSTER / Bundeszentralamt für Steuern, consulted 2026-10-24
- impots.gouv.fr — guichet unique TVA (OSS/IOSS): déclaration en ligne dans l’espace professionnel — DGFiP, consulted 2026-10-24. No public file-import specification for the French OSS return was found on 2026-10-24; the French file is the labelled generic CSV until the DGFiP publishes one.