Quickstart
A complete end-to-end flow through the Agent API: create a test key, set up a client organization (including address), enroll it in the Peppol sandbox, issue an invoice, send it over Peppol, track its status, and receive a webhook. All in the sandbox, no credits, a real Peppol TEST network.
Prerequisites
| Item | Value |
|---|---|
| Base URL | https://api.efaktura.sk/v1 |
| Authentication | The X-API-Key header, plus X-Organization-Id for operations on an organization |
| Test key | efk_pk_test_… |
efk_pk_test_… = sandbox (Peppol TEST network, no credits), efk_pk_live_… = production.Integration flow
POST /v1/agent/peppol/connector/send): it validates, reserves credit, and sends in one go, with idempotency and opt-in auto-fix. For bulk sending from a spreadsheet, use CSV ingest. The step-by-step flow below is the universal foundation.In the partner portal, under API keys, create a sandbox key. It's shown only once, so store it in a secret store. A partner key (efk_pk_*) can create client organizations; it's tied to your partner account.
A partner key creates a white-label child organization. In this call you don't send X-Organization-Id: the organization doesn't exist yet. The org:provision scope is required.
street, city, postalCode) and dic + ic_dph right away. Without a complete seller address, Peppol sending fails on SK validation rules (BT-35/37/38). More in the Invoices section.curl -X POST https://api.efaktura.sk/v1/agent/organizations \
-H "X-API-Key: efk_pk_test_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Tatra Servis s.r.o.",
"ico": "12345678",
"dic": "2020202020",
"ic_dph": "SK2020202020",
"address": {
"street": "Hlavná 1",
"city": "Bratislava",
"postalCode": "81101",
"country": "SK"
}
}'Response (201 Created, or 200 if an existing organization was reused):
{
"data": {
"org_id": "0a2c1f3e-…",
"partner_id": "7b8d…",
"slug": "tatra-servis-sro",
"reused": false,
"status": "caka_na_token"
}
}org_id is the value you send in X-Organization-Id from now on. You can get the organization's detail (including participant_id and peppol_status) via GET /v1/agent/organizations/{org_id}.
Enroll registers the organization's DIČ as a Peppol participant in the TEST SMP (9915:<DIČ>). The invoice:send scope and the X-Organization-Id header are required. In the sandbox, the verification token is optional; for production (live) enroll it is required (a Financial Administration verification code, more in Going live).
curl -X POST https://api.efaktura.sk/v1/agent/peppol/enroll \
-H "X-API-Key: efk_pk_test_..." \
-H "X-Organization-Id: 0a2c1f3e-…" \
-H "Content-Type: application/json" \
-d '{}'{
"data": {
"status": "active",
"registration_id": "…",
"participant_id": "9915:2020202020"
}
}The organization's DIČ must have 10 digits, otherwise enroll returns VALIDATION_ERROR.
You issue an invoice via POST /v1/agent/invoices (scope invoice:create). The seller is derived from the organization, the buyer from customer (or an existing customer_id). For the invoice to be sendable over Peppol, the buyer must have a complete address and (for a company) ico/dic/ic_dph.
curl -X POST https://api.efaktura.sk/v1/agent/invoices \
-H "X-API-Key: efk_pk_test_..." \
-H "X-Organization-Id: 0a2c1f3e-…" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"name": "Customer s.r.o.",
"ico": "87654321",
"dic": "2010101010",
"ic_dph": "SK2010101010",
"address": {
"street": "Obchodná 5",
"city": "Košice",
"postalCode": "04001",
"country": "SK"
},
"email": "fakturacia@odberatel.sk"
},
"items": [
{
"description": "Service work",
"quantity": 2,
"unit": "hod",
"unit_price": 50,
"vat_rate": 23
}
],
"payment_method": "bank_transfer",
"due_days": 14
}'Response (201 Created), then save the id:
{
"id": "b1f0d7a2-…",
"invoice_number": "2026001",
"status": "issued",
"customer": { "id": "…", "name": "Customer s.r.o." },
"items": [ … ],
"subtotal": "100.00",
"vat_total": "23.00",
"total": "123.00",
"currency": "EUR",
"issue_date": "2026-06-22",
"due_date": "2026-07-06",
"pdf_url": "https://…",
"created_at": "2026-06-22T10:00:00.000Z"
}Sending queues the invoice (scope invoice:send). A test key routes the send through the sandbox AP on the real Peppol TEST network, no credits.
curl -X POST https://api.efaktura.sk/v1/agent/peppol/send/b1f0d7a2-… \
-H "X-API-Key: efk_pk_test_..." \
-H "X-Organization-Id: 0a2c1f3e-…"Response (202 Accepted):
{
"data": {
"invoice_id": "b1f0d7a2-…",
"job_id": "peppol-send:b1f0d7a2-…",
"status": "queued"
}
}POST /v1/agent/peppol/send/batch with the body { "invoiceIds": ["…", "…"] } (1–200 IDs).You check transmission status via GET /v1/agent/peppol/status/{invoiceId} (scope invoice:read). The endpoint's actual states are: QUEUED, SENDING, SENT, DEFERRED, ERROR; if nothing has been sent yet, a synthetic not_sent value is returned. (DELIVERED is a webhook event state, not a polling-endpoint state.) Details in Receiving and statuses.
curl https://api.efaktura.sk/v1/agent/peppol/status/b1f0d7a2-… \
-H "X-API-Key: efk_pk_test_..." \
-H "X-Organization-Id: 0a2c1f3e-…"{
"data": {
"invoice_id": "b1f0d7a2-…",
"state": "SENT",
"error_message": null,
"receiver_identifier": "9915:2010101010",
"document_id": "…",
"updated_at": "2026-06-22T10:00:05.000Z"
}
}Instead of polling, we recommend webhooks. Register an HTTPS endpoint in the portal and react to peppol.document.sent / peppol.document.delivered / peppol.document.failed, or to an inbound document via peppol.document.received. Every delivery is HMAC-signed: verify the signature and deduplicate by X-Webhook-Id. The full picture is in Webhooks.
{
"event": "peppol.document.delivered",
"timestamp": "2026-06-22T10:00:08.000Z",
"data": {
"invoiceId": "b1f0d7a2-…",
"invoiceNumber": "2026001",
"documentType": "invoice",
"mode": "test",
"state": "DELIVERED",
"messageId": "…",
"transactionId": "…",
"orgId": "0a2c1f3e-…"
}
}Next steps
Before sending, you can pre-validate your UBL XML (Validation). Once the flow is verified in the sandbox, move on to Going live: production enroll requires a Financial Administration verification token and partner activation.