Getting started
This is the start-here guide for integrating your system with eFakturuj. In five steps you'll push a Peppol BIS Billing 3.0 invoice through the Slovak 5-corner model — the invoice to the buyer's Access Point and the Slovak Tax Data Document (SK TDD) to the tax authority — and know it arrived.
Everything below uses one header and the base URL for the environment you want to call:
- Production:
https://api.efakturuj.sk/api/v1 - Sandbox testing:
https://api.sandbox.efakturuj.sk/api/v1 - Auth:
X-Api-Key: efk_…— a single key type (see Authentication)
Use the sandbox endpoint while developing. It has the same API shape, but runs against isolated test data and does not deliver documents to the real Peppol network or bill them.
Invoice, customer, payment, billing, and settings routes are company-scoped.
Set COMPANY_ID to the UUID of the company you are acting for.
The flow at a glance
POST /companies/{company_id}/invoices → create a draft (returns {id})
POST /companies/{company_id}/invoices/{id}/validate → check BIS 3.0.20 (no delivery — safe to loop)
POST /companies/{company_id}/invoices/{id}/send → 5-corner: invoice → buyer (C3) + SK TDD → tax authority (C5)
GET /companies/{company_id}/invoices/{id} → track DRAFT → SENT_PEPPOL → DELIVERED
0. Get an API key
Create one in the dashboard (Settings → API keys) or via the API. Keys are a
single type, prefixed efk_ — there is no per-key test/live toggle; the
behaviour is decided by the deployment you call.
curl -X POST https://api.efakturuj.sk/api/v1/api-keys \
-H 'Authorization: Bearer <your-dashboard-jwt>' \
-H 'Content-Type: application/json' \
-d '{"name": "my-integration", "scopes": ["invoices:read","invoices:write","invoices:send"]}'
# → { "api_key": "efk_…", "key_prefix": "efk_…", "id": "…" }
Store api_key securely — it's shown once. Send it as X-Api-Key on every call.
1. Create an invoice
POST /companies/{company_id}/invoices takes the whole document in one call.
The supplier and buyer each carry a Peppol participant id in
scheme:identifier form (e.g. 0245:2122813913); check a buyer's reachability
with POST /tools/peppol-check if you don't have a confirmed id.
curl -X POST https://api.efakturuj.sk/api/v1/companies/$COMPANY_ID/invoices \
-H 'X-Api-Key: efk_…' -H 'Content-Type: application/json' \
-d '{
"invoice_number": "2026-0001",
"issue_date": "2026-06-25", "due_date": "2026-07-25",
"currency_code": "EUR",
"supplier": { "name": "Moja firma s.r.o.", "vat_id": "SK2122813913", "ico": "53510160",
"street": "Mlynské nivy 5", "city": "Bratislava", "postal_code": "82109",
"country_code": "SK", "peppol_id": "0245:2122813913" },
"buyer": { "name": "Odberateľ s.r.o.", "vat_id": "SK2020999999", "ico": "20209999",
"street": "Hlavná 1", "city": "Košice", "postal_code": "04001",
"country_code": "SK", "peppol_id": "0245:2020999999" },
"supplier_iban": "SK3112000000001987426375",
"lines": [ { "line_number": 1, "item_name": "Konzultácie", "quantity": "1",
"unit_code": "HUR", "unit_price": "100.00",
"vat_rate": "23.00", "vat_category_code": "S" } ]
}'
# → { "id": "…", "status": "draft", … }
| Field | Notes |
|---|---|
peppol_id | scheme:identifier. eFakturuj splits it into the UBL EndpointID (schemeID + value) for you — never send the scheme inline. |
vat_rate / vat_category_code | SK rates: 0, 5, 19, 23; category S (standard), Z (zero), AE (reverse charge). |
supplier_iban | Required for the payment means block. |
| amounts | Always strings (decimal-safe). |
2. Validate before you send
POST /companies/{company_id}/invoices/{id}/validate runs XSD + Peppol BIS
3.0.20 + Slovak Schematron and returns the issues — without sending
anything. This is your safe development loop: iterate here until
valid: true with zero errors, then send.
curl -X POST https://api.efakturuj.sk/api/v1/companies/$COMPANY_ID/invoices/$INVOICE_ID/validate \
-H 'X-Api-Key: efk_…'
# → { "valid": true, "xml_validation": { "xsd_valid": true, "peppol_valid": true, "errors": [] } }
Each error carries the Schematron rule id (e.g. BR-CO-10) and a message —
map them straight back to the field you sent. GET /companies/{company_id}/invoices/{id}/ubl
returns the generated UBL if you want to inspect it.
3. Send — the 5-corner flow
POST /companies/{company_id}/invoices/{id}/send queues the real delivery and
returns immediately. A single send performs the full 5-corner exchange:
- the invoice → the buyer's Access Point (C3), and
- a referencing SK Tax Data Document → the Slovak tax authority (C5),
each correlated by a deterministic BDID-01 UUID. You never build the TDD — it's derived from the invoice.
curl -X POST https://api.efakturuj.sk/api/v1/companies/$COMPANY_ID/invoices/$INVOICE_ID/send \
-H 'X-Api-Key: efk_…'
# → { "invoice_id": "…", "status": "queued", "message": "Invoice queued for delivery" }
4. Track delivery
The send is asynchronous. Poll GET /companies/{company_id}/invoices/{id} or
(recommended) subscribe to webhooks. The status walks:
DRAFT → SENT_PEPPOL → DELIVERED (DELIVERED = the buyer's AP returned a positive MLS)
The matching SK TDD is filed in the same step; its acknowledgement (the MLS from the tax authority) is tracked alongside.
5. Credit notes
A credit note is the same call with invoice_type: "381" and a reference to the
invoice it credits:
-d '{ "invoice_type": "381", "source_invoice_id": "<original-invoice-id>", … }'
Send it the same way — POST /companies/{company_id}/invoices/{id}/send files
the credit note + its TDD.
Testing safely
- Validate-only (step 2) never delivers and never bills — use it freely to prove your data produces a compliant invoice.
- For full send testing, call the sandbox endpoint:
https://api.sandbox.efakturuj.sk/api/v1. It supports the same requests as production while keeping delivery and billing isolated.
Next steps
- Authentication — key scopes, JWT vs API key
- Sending invoices — the field-by-field reference
- Receiving invoices — inbound + the MLS you send back
- Webhooks · Errors · Idempotency