Sandbox vs. production
The goal is one code path for both environments. Going to production means swapping the test key efk_pk_test_… for the live key efk_pk_live_…; the base URL and the order of calls stay the same.
When the sandbox behaves like production
Right away for accounts registered from 02.10.2026 and for older accounts whose owner switched on Team & permissions → Sandbox like production in the portal (it can be switched off until 01.11.2026). From 01.11.2026 for everyone. Other older accounts keep the lenient sandbox from the “Sandbox (lenient)” column until 01.11.2026.
Differences
| Area | Sandbox (lenient) | Production (live key) | Sandbox like production |
|---|---|---|---|
Peppol registration on POST /v1/agent/organizations | Enrolls the company in the TEST network automatically (the peppol_sandbox field). | Never. | No longer. Call POST /v1/agent/peppol/enroll. |
verificationTokenHex in POST /v1/agent/peppol/enroll | Optional, the response carries a warning. | Required, verified at the Financial Administration. | Required in the sandbox too (any hex is enough). |
| Sending without a Peppol account | Passes today. | Rejected: “Peppol účet nie je aktívny”. | The sandbox rejects it too, with a hint to call enroll. |
| Peppol ID | 9915:<DIČ> | 0245:<DIČ> | No change. |
Peppol ID in the sandbox
GET /v1/agent/peppol/recipient and receiverPeppolId in POST /v1/agent/peppol/preflight also accept 0245:<DIČ> in the sandbox and find the test participant 9915:<DIČ>. This applies to these two read calls only. Sending invoices through the Agent API takes the recipient from the buyer DIČ, so the alias does not affect it.
9915 scheme in EndpointID in the sandbox. This holds in the Peppol test network at every provider.Test tokens
They work with test keys only, exact value, case-insensitive. Live keys never simulate.
| Token | Result |
|---|---|
000000000000dead | 400 Verifikačný token nie je platný and a participant.failed webhook, identical to production. |
000000000000beef | 201 with status: "send_only" and reception.held_by { ap_host: "sandbox-other-ap.efaktura.test", cert_org: "Sandbox iný poštár" }, plus a participant.failed webhook with code PARTICIPANT_HELD_ELSEWHERE. Reception is held by another provider; sending works. |
000000000000beef with a non-empty migrationCode | 201 with status: "enrolled" (simulates migrating reception). |
| Any other hex | 201 with status: "enrolled". |
Transition signals
In the lenient sandbox, the response to a token-less sandbox enroll and to an auto-enrolling POST /v1/agent/organizations carries a top-level warnings: [{ code, message }] next to data, with codes SANDBOX_TOKEN_MISSING and SANDBOX_AUTO_ENROLL. These headers are added too:
Deprecation: @1790899200
Sunset: Sat, 31 Oct 2026 23:00:00 GMT
Link: <https://developers.efaktura.sk/docs/sandbox>; rel="deprecation"Sunset equals 01.11.2026 00:00 in Bratislava.
Network isolation
Live now. A send is refused when the organization's Peppol registration belongs to the other network than the key (a sandbox organization on a live key or vice versa): “Organizácia je registrovaná v inej Peppol sieti, než do ktorej sa odosiela…”.
Recommended code
In the sandbox one enroll call with any hex token activates the organization; store org_id and check peppol_status. In production the organization activates after the client picks the provider on the FS portal, either by the client clicking our e-mail or by your enroll with the client's code (see Going live).
# 1. Create the organization
# random IČO/DIČ: sample values may be used by another partner (409)
ICO=$(printf '%08d' $(( (RANDOM<<15 | RANDOM) % 100000000 )))
DIC=2$(printf '%09d' $(( (RANDOM<<15 | RANDOM) % 1000000000 )))
curl -X POST https://api.efaktura.sk/v1/agent/organizations \
-H "X-API-Key: $EFAKTURA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Tatra Servis s.r.o.", "ico": "'$ICO'", "dic": "'$DIC'", "ic_dph": "SK'$DIC'", ... }'
# store data.org_id
# 2. Enroll: the Financial Administration token in production, e.g. "a1b2c3" in the sandbox
curl -X POST https://api.efaktura.sk/v1/agent/peppol/enroll \
-H "X-API-Key: $EFAKTURA_API_KEY" \
-H "X-Organization-Id: $SENDER_ORG_ID" \
-H "Content-Type: application/json" \
-d '{ "verificationTokenHex": "a1b2c3" }'
# 3. Check the status
curl https://api.efaktura.sk/v1/agent/organizations/$SENDER_ORG_ID \
-H "X-API-Key: $EFAKTURA_API_KEY"
# peppol_status (the response is a plain object, no data envelope)