eFakturuj / API Docs
eFakturuj Guides

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 is one base URL and one header:

  • Base URL: https://api.efakturuj.sk/api/v1
  • Auth: X-Api-Key: efk_… — a single key type (see Authentication)

The flow at a glance

POST /invoices                  → create a draft           (returns {id})
POST /invoices/{id}/validate    → check BIS 3.0.20          (no delivery — safe to loop)
POST /invoices/{id}/send        → 5-corner: invoice → buyer (C3) + SK TDD → tax authority (C5)
GET  /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 /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); discover a buyer's id with GET /lookup/... if you don't have it.

curl -X POST https://api.efakturuj.sk/api/v1/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", … }
FieldNotes
peppol_idscheme:identifier. eFakturuj splits it into the UBL EndpointID (schemeID + value) for you — never send the scheme inline.
vat_rate / vat_category_codeSK rates: 0, 5, 19, 23; category S (standard), Z (zero), AE (reverse charge).
supplier_ibanRequired for the payment means block.
amountsAlways strings (decimal-safe).

2. Validate before you send

POST /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/invoices/<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 /invoices/{id}/ubl returns the generated UBL if you want to inspect it.

3. Send — the 5-corner flow

POST /invoices/{id}/send queues the real delivery and returns immediately. A single send performs the full 5-corner exchange:

  1. the invoice → the buyer's Access Point (C3), and
  2. 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/invoices/<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 /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 /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.
  • A dedicated self-serve sandbox with an internal Peppol loop-back (full send → MLS → TDD lifecycle, no real delivery, isolated from production) is on the roadmap. Until it lands, validate before you send, and coordinate a controlled first live send with us.

Next steps