Invoiz API
Create draft invoices, credit notes and customers from your own systems — and optionally send them over Peppol or by email.
The Invoiz API is a small REST API over HTTPS. Requests and responses are JSON. Every document you create lands in your Invoiz account as a draft, tagged with an API badge, so you can review it before it goes out — unless you explicitly ask us to send it.
Base URL
https://rzcbampaeqjrghtuzzyq.supabase.co/functions/v1/api
Authentication
Create an API key in Invoiz under Settings → API keys. The full key is shown once — store it somewhere safe; we only keep a hash. Send it on every request as a Bearer token:
Authorization: Bearer invz_sk_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
Or, if you prefer, with the X-API-Key header. Keys can be revoked at any time from the same screen; a revoked key immediately returns 401.
Conventions & errors
- All request bodies are JSON; send
Content-Type: application/json. - Every response has a boolean
ok. Errors look like{ "ok": false, "error": "…" }. - Amounts are numbers in the document currency (default
EUR). Totals are computed for you from the line items. - Idempotency: pass a unique
external_refwhen creating a document. A repeatedexternal_refreturns the existing document instead of creating a duplicate.
| Status | Meaning |
|---|---|
200 / 201 | Success |
400 | Bad request — a field is missing or invalid |
401 | Missing, invalid or revoked API key |
402 | The company needs an active Pro or Business plan |
404 | Resource not found |
422 | Can’t send — company or customer isn’t send-ready (see Auto-send) |
500 | Unexpected server error |
Find a customer
Look up an existing customer by VAT number or email before creating one.
Response
{
"ok": true,
"found": true,
"customer": {
"id": "c1a2…",
"name": "Acme BV",
"vat_number": "BE0123456789",
"emails": ["finance@acme.be"],
"peppol_id": null
}
}
When no match is found you get { "ok": true, "found": false, "customer": null }.
Create a customer
If a customer with the same VAT number or email already exists for your company, that one is returned instead of a duplicate.
| Field | Type | Notes |
|---|---|---|
name | string | required to create |
vat_number | string | optional — needed for Peppol |
enterprise_number | string | optional |
email / emails | string / string[] | optional — needed for email sending |
peppol_scheme, peppol_id | string | optional — explicit Peppol endpoint |
iban, bic | string | optional |
address | object | optional — { street, postalCode, city, country } |
curl "$BASE/customers" \
-H "Authorization: Bearer $INVOIZ_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme BV",
"vat_number": "BE0123456789",
"email": "finance@acme.be",
"address": { "street": "Havenlaan 1", "postalCode": "1000", "city": "Brussel", "country": "BE" }
}'
Create a draft invoice
Identify the customer one of three ways: pass customer_id, or a customer object matched by VAT/email, or a full customer object that is created if it doesn’t exist yet.
| Field | Type | Notes |
|---|---|---|
customer_id | string | Use an existing customer… |
customer | object | …or match/create one inline (see above) |
lines | array | required — see Line items |
currency | string | optional — default EUR |
issue_date, due_date | string | optional — YYYY-MM-DD |
note | string | optional |
buyer_reference | string | optional — customer PO / reference |
external_ref | string | optional — your ID, for idempotency |
send | object | optional — auto-send |
Request
curl "$BASE/invoices" \
-H "Authorization: Bearer $INVOIZ_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer": { "name": "Acme BV", "vat_number": "BE0123456789", "email": "finance@acme.be" },
"issue_date": "2026-07-21",
"due_date": "2026-08-20",
"external_ref": "order-10432",
"lines": [
{ "description": "Consulting — July", "quantity": 3, "unit_price": 750, "vat_category": "21" },
{ "description": "Hosting", "quantity": 1, "unit_price": 40, "vat_category": "21" }
]
}'
Response
{
"ok": true,
"invoice": {
"id": "9f2a…",
"kind": "invoice",
"status": "draft",
"number": null,
"total": 2770.90,
"currency": "EUR",
"source": "api"
},
"customer_id": "c1a2…",
"customer_created": true,
"send": {}
}
Create a draft credit note
Identical to creating an invoice, with one extra optional field. Amounts are entered as positive numbers.
| Field | Type | Notes |
|---|---|---|
credit_of_invoice_id | string | optional — the invoice this credits |
curl "$BASE/credit-notes" \
-H "Authorization: Bearer $INVOIZ_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "c1a2…",
"credit_of_invoice_id": "9f2a…",
"lines": [ { "description": "Refund — hosting", "quantity": 1, "unit_price": 40, "vat_category": "21" } ]
}'
Get an invoice
Fetch the current status of any invoice or credit note you created — handy for polling after an auto-send.
{
"ok": true,
"invoice": {
"id": "9f2a…", "kind": "invoice",
"status": "peppol_submitted", "number": "2026-0042",
"total": 2770.90, "peppol_status": "submitted"
}
}
Auto-send over Peppol / email
Add a send object to a create request to dispatch the document immediately instead of leaving it as a draft.
"send": { "peppol": true, "email": true }
- peppol — issues the document and delivers it over the Peppol network. Requires your company to be Peppol-ready (valid VAT, address, IBAN/BIC) and the customer to be reachable on Peppol (a valid VAT/enterprise number or explicit
peppol_id). - email — issues the document and emails a PDF to the customer. Requires at least one customer email.
The response includes a per-channel send result so you always know what happened:
{
"ok": true,
"invoice": { "status": "peppol_submitted", "number": "2026-0042" },
"send": {
"peppol": { "ok": true, "status": "peppol_submitted" },
"email": { "ok": true }
}
}
{ "ok": false, "error": "…" }. Omit send to keep everything as a reviewable draft.Line items & VAT codes
Each entry in lines accepts:
| Field | Type | Notes |
|---|---|---|
description | string | required |
quantity | number | optional — default 1 |
unit_price | number | optional — excl. VAT, default 0 |
vat_category | string | optional — default "21" (see below) |
vat_rate | number | optional — override the rate explicitly |
unit | string | optional — UN/ECE code, default "C62" (each) |
VAT categories
| Code | Rate | Meaning |
|---|---|---|
21 / 12 / 6 | 21% / 12% / 6% | Standard Belgian rates |
0 | 0% | Zero-rated |
MC | 0% | Reverse charge (medecontractant) |
ICL / ICD | 0% | Intra-community goods / services |
EX | 0% | Export outside the EU |
KO | 0% | Small-enterprise exemption (art. 56bis) |
Full example
Create a customer if needed, raise an invoice, and send it over Peppol — in one call:
BASE="https://rzcbampaeqjrghtuzzyq.supabase.co/functions/v1/api"
curl "$BASE/invoices" \
-H "Authorization: Bearer $INVOIZ_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"name": "Acme BV",
"vat_number": "BE0123456789",
"email": "finance@acme.be"
},
"due_date": "2026-08-20",
"external_ref": "order-10432",
"lines": [
{ "description": "Consulting — July", "quantity": 3, "unit_price": 750, "vat_category": "21" }
],
"send": { "peppol": true }
}'