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 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", … }
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 /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:

  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/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