De publieke 4invoices-API stuurt factuurgegevens vanuit je systeem naar 4invoices en brengt de factuur volledig door het nationale e-factureringssysteem (in Roemenië: het SPV van ANAF). Één productiehost, één client_credentials-flow, idempotente fiscale writes en één foutenvelop op elke route.
https://api.4invoices.net/v1 · OpenAPI-specificatie (zonder sleutel)
Wat de 4invoices-API is
- De publieke API van 4invoices is REST over HTTPS, met JSON als invoer en JSON als uitvoer.
- Eén productiehost: https://api.4invoices.net/v1. Er is geen aparte testhost.
- De OpenAPI 3.1-specificatie is openbaar en vereist geen sleutel — importeer haar rechtstreeks in Postman of in een clientgenerator.
- Elke respons bevat een X-Request-Id-header; vermeld die wanneer u om ondersteuning vraagt.
- Elke fiscale schrijfbewerking is idempotent: een nieuwe poging na een time-out geeft nooit een tweede document uit.
- De volledige cyclus van het nationale e-factureringssysteem via de API (in Roemenië: ANAF e-Factura): precontrole, indiening, opvolging, ondertekend antwoord en de inkomende inbox. Geen enkele Roemeense concurrent biedt dit.
- SmartBill heeft geen enkel endpoint voor indiening bij het nationale e-factureringssysteem (ANAF, in Roemenië) — verzending is een accountinstelling die alleen in de interface bestaat — en helemaal geen endpoint om facturen op te vragen.
- Oblio kan klanten en producten alleen aanmaken als neveneffect van het uitgeven van een document, niet als volwaardige bronnen.
- Generatie van UBL / CIUS-RO-XML (Roemenië) zonder indiening: u krijgt het wettelijke document als bestand zonder het nationale e-factureringssysteem aan te raken.
- Idempotentie bij fiscale schrijfbewerkingen: een nieuwe poging na een time-out levert geen tweede factuur op en verbruikt geen tweede nummer.
- Een programmatisch leesbare inbox met leveranciersfacturen — de basis voor geautomatiseerde afstemming.
Je eerste factuur in 6 stappen
- Maak een credential aan in het paneel, onder Facturatie → Instellingen → API-toegang, en kopieer het client_secret — het wordt één keer getoond.
- Vul het bedrijfsprofiel aan en activeer minstens één reeks van het type fiscale, anders geeft het uitgeven issuer_profile_incomplete of no_series_configured terug.
- Maak een credential aan in het paneel, onder Facturatie → Instellingen → API-toegang, en kopieer het client_secret — het wordt één keer getoond.
- Vul het bedrijfsprofiel aan en activeer minstens één reeks van het type fiscale, anders geeft het uitgeven issuer_profile_incomplete of no_series_configured terug.
- Wissel het credential in voor een token: POST /v1/auth/token met grant_type client_credentials. Het token geldt één uur — cache het, vraag er niet één per request aan.
- Geef de factuur uit: POST /v1/invoices met een Idempotency-Key-header en vat_rate als percentage (21, niet 0.21).
- Voer de preflight (CIUS-RO voor Roemenië) uit met POST /v1/invoices/{id}/efactura/validate en stuur de factuur daarna naar het nationale e-factureringssysteem (in Roemenië: ANAF) met POST /v1/invoices/{id}/efactura/submit.
- Volg de status met GET /v1/efactura/submissions/{id} tot die accepted of rejected bereikt.
bash
# 1 — token (1 uur, cache het)
ACCESS_TOKEN=$(curl -sS -X POST https://api.4invoices.net/v1/auth/token \
-H 'Content-Type: application/json' \
-d '{"grant_type":"client_credentials","client_id":"cli_XXX","client_secret":"sec_XXX"}' \
| python3 -c 'import sys,json; print(json.load(sys.stdin)["access_token"])')
# 2 — de factuur uitgeven (Idempotency-Key is VERPLICHT)
curl -sS -X POST https://api.4invoices.net/v1/invoices \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-10457-invoice' \
-d '{"buyer":{"name":"Exemplu Comert SRL","tax_id":"RO12345678","county":"Cluj","city":"Cluj-Napoca","country":"RO"},
"lines":[{"description":"Abonament SaaS","quantity":1,"unit_price":400,"vat_rate":21}]}'
# 3 — preflight CIUS-RO, then send to ANAF
curl -sS -X POST https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/validate \
-H "Authorization: Bearer $ACCESS_TOKEN"
curl -sS -X POST https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/submit \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Idempotency-Key: efactura-inv_01J7ABC-1'javascript
const BASE = "https://api.4invoices.net/v1";
const token = await fetch(`${BASE}/auth/token`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "client_credentials",
client_id: process.env.FOURINVOICES_CLIENT_ID,
client_secret: process.env.FOURINVOICES_CLIENT_SECRET,
}),
}).then((r) => r.json()).then((d) => d.access_token);
const invoice = await fetch(`${BASE}/invoices`, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
"Idempotency-Key": `order-${orderId}-invoice`,
},
body: JSON.stringify({
buyer: { name: "Exemplu Comert SRL", tax_id: "RO12345678", county: "Cluj", city: "Cluj-Napoca", country: "RO" },
lines: [{ description: "Abonament SaaS", quantity: 1, unit_price: 400, vat_rate: 21 }],
currency: "RON",
metadata: { order_id: String(orderId) },
}),
}).then((r) => r.json());
console.log(invoice.number, invoice.totals); // "FCT-000123" { net, vat, gross }python
import os, uuid, requests
BASE = "https://api.4invoices.net/v1"
token = requests.post(f"{BASE}/auth/token", json={
"grant_type": "client_credentials",
"client_id": os.environ["FOURINVOICES_CLIENT_ID"],
"client_secret": os.environ["FOURINVOICES_CLIENT_SECRET"],
}, timeout=30).json()["access_token"]
headers = {
"Authorization": f"Bearer {token}",
# Eén sleutel per LOGISCHE bewerking — hergebruik die bij een retry, genereer nooit een nieuwe.
"Idempotency-Key": f"order-{order_id}-invoice",
}
invoice = requests.post(f"{BASE}/invoices", headers=headers, json={
"buyer": {"name": "Exemplu Comert SRL", "tax_id": "RO12345678",
"county": "Cluj", "city": "Cluj-Napoca", "country": "RO"},
"lines": [{"description": "Abonament SaaS", "quantity": 1,
"unit_price": 400, "vat_rate": 21}], # percentage, niet 0.21
"currency": "RON",
}, timeout=60).json()
print(invoice["number"], invoice["totals"])Authenticatie
- De flow is client_credentials: u wisselt client_id + client_secret in voor een Bearer-access_token.
- Het token verloopt na 3600 seconden. Vernieuw het vóór het verloopt, niet bij elke aanroep — POST /auth/token heeft een eigen rate limit per IP.
- Het client_secret wordt alleen als hash opgeslagen en kan niet worden hersteld. Raakt u het kwijt, dan maakt u een nieuwe credential aan en trekt u de oude in.
- Uitsluitend server-to-server. CORS laat geen enkele browser-origin toe: vanuit JavaScript op een pagina zou het secret uitlekken naar de bezoeker.
- Scopes worden per credential toegekend. Geef elk systeem een aparte credential, met alleen de minimale scopes die het nodig heeft.
Facturatie → Instellingen → API-toegang
bash
curl -sS -X POST https://api.4invoices.net/v1/auth/token \
-H 'Content-Type: application/json' \
-d '{
"grant_type": "client_credentials",
"client_id": "cli_XXXXXXXXXXXX",
"client_secret": "sec_XXXXXXXXXXXXXXXXXXXX"
}'
# → {"access_token":"eyJ...","token_type":"Bearer","expires_in":3600,
# "scope":"invoices:read invoices:write efactura:submit"}javascript
// Cache het token; vraag niet bij elk request een nieuw aan.
let cached = { token: "", expiresAt: 0 };
async function getToken() {
if (cached.token && Date.now() < cached.expiresAt - 60_000) return cached.token;
const res = await fetch("https://api.4invoices.net/v1/auth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "client_credentials",
client_id: process.env.FOURINVOICES_CLIENT_ID,
client_secret: process.env.FOURINVOICES_CLIENT_SECRET,
}),
});
if (!res.ok) throw new Error(`token ${res.status}`);
const data = await res.json();
cached = { token: data.access_token, expiresAt: Date.now() + data.expires_in * 1000 };
return cached.token;
}Btw-tarieven zijn percentages
vat_rate: 21 ✓ · vat_rate: 0.19 ✗ · vat_rate: 1 ✗- vat_rate is een PERCENTAGE: 21 betekent 21%.
- Waarden in (0, 1] worden geweigerd — 0.19 is een breuk, en 1 is dubbelzinnig tussen 1% en 100%.
- 0 is geldig en betekent vrijgesteld of verlegd; zet de wettelijke vermelding in notes.
- unit_price is de NETTO-eenheidsprijs wanneer de uitgever btw-plichtig is.
- De totalen nodig vóór u vastlegt? POST /v1/invoices/preview-totals voert dezelfde berekening uit zonder een fiscaal nummer te verbruiken.
Idempotentie bij fiscale schrijfacties
- De Idempotency-Key-header is VERPLICHT op POST /invoices, POST /invoices/{id}/storno en POST /invoices/{id}/efactura/submit.
- Sleutels worden 24 uur onthouden. Dezelfde sleutel opnieuw sturen met dezelfde body geeft het oorspronkelijke resultaat terug en zet Idempotency-Replayed: true.
- Dezelfde sleutel met een andere body geeft 409 idempotency_key_reuse terug — een reeds uitgegeven fiscaal document wordt nooit overschreven.
- Eén sleutel per LOGISCHE bewerking, niet per HTTP-poging: order-10457-invoice, geen nieuwe UUID bij elke nieuwe poging.
- De reden is juridisch, niet technisch: een verbruikt fiscaal nummer en een bij het nationale e-factureringssysteem ingediende factuur kunnen niet worden ingetrokken.
bash
curl -sS -X POST https://api.4invoices.net/v1/invoices \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-10457-invoice' \
-d '{
"buyer": {
"name": "Exemplu Comert SRL",
"tax_id": "RO12345678",
"address": "Str. Fabricii 12",
"city": "Cluj-Napoca",
"county": "Cluj",
"country": "RO",
"email": "[email protected]"
},
"lines": [
{ "description": "Abonament SaaS, iulie", "quantity": 1, "unit_price": 400, "vat_rate": 21, "unit": "buc" },
{ "description": "Implementare", "quantity": 6, "unit_price": 250, "vat_rate": 21, "unit": "ora" }
],
"currency": "RON",
"document_kind": "factura",
"due_date": "2026-08-15",
"metadata": { "order_id": "10457" }
}'Alle endpoints
| Methode | Endpoint | Scope | Idempotency-Key | Verzoeken / minuut |
|---|---|---|---|---|
| POST | /auth/token Inloggegevens ruilen voor een toegangstoken | — | — | 120 |
| GET | /me Tenant, scopes en huidige limieten | invoices:read | — | 120 |
| POST | /invoices Een factuur of proforma uitgeven | invoices:write | verplicht | 30 |
| GET | /invoices Facturen weergeven (cursorpaginering) | invoices:read | — | 120 |
| POST | /invoices/preview-totals Totalen berekenen zonder iets aan te maken | invoices:read | — | 120 |
| GET | /invoices/{invoice_id} Eén factuur ophalen | invoices:read | — | 120 |
| GET | /invoices/{invoice_id}/pdf De PDF van de factuur downloaden | invoices:read | — | 120 |
| GET | /invoices/{invoice_id}/xml De UBL / CIUS-RO-XML (Roemenië) downloaden | invoices:read | — | 120 |
| POST | /invoices/{invoice_id}/storno Een creditnota uitgeven die deze factuur tenietdoet | invoices:write | verplicht | 30 |
| POST | /invoices/{invoice_id}/payments De factuur als betaald markeren | invoices:write | — | 30 |
| DELETE | /invoices/{invoice_id}/payments De factuur als onbetaald markeren | invoices:write | — | 30 |
| GET | /clients Klanten weergeven | clients:read | — | 120 |
| POST | /clients Een klant aanmaken of bijwerken | clients:write | — | 30 |
| GET | /lookup/company/{tax_id} Een CUI controleren in het ANAF-register (Roemenië) | clients:read | — | 120 |
| GET | /series Nummerreeksen weergeven | invoices:read | — | 120 |
| POST | /invoices/{invoice_id}/efactura/validate Precontrole (CIUS-RO voor Roemenië) — valideren zonder verzenden | efactura:read | — | 120 |
| POST | /invoices/{invoice_id}/efactura/submit De factuur naar ANAF (SPV, Roemenië) sturen | efactura:submit | verplicht | 10 |
| GET | /efactura/submissions Inzendingen bij ANAF (Roemenië) weergeven | efactura:read | — | 120 |
| GET | /efactura/submissions/{submission_id} Eén inzending ophalen | efactura:read | — | 120 |
| POST | /efactura/submissions/{submission_id}/refresh De huidige status opvragen bij ANAF (Roemenië) | efactura:read | — | 10 |
| GET | /efactura/submissions/{submission_id}/download Het archief van het ondertekende antwoord downloaden | efactura:read | — | 120 |
| GET | /efactura/inbox Via het SPV (Roemenië) ontvangen leveranciersfacturen | efactura:read | — | 120 |
| GET | /efactura/inbox/{inbound_id} Eén inkomende factuur ophalen | efactura:read | — | 120 |
| GET | /efactura/inbox/{inbound_id}/download Het archief van de inkomende factuur downloaden | efactura:read | — | 120 |
| POST | /efactura/inbox/sync Nieuwe berichten uit het SPV (Roemenië) naar de inbox halen | efactura:read | — | 10 |
25 endpoints · https://api.4invoices.net/v1/openapi.json
Scopes
- invoices:read
- invoices:write
- clients:read
- clients:write
- efactura:read
- efactura:submit
Nationale e-facturering (ANAF e-Factura, Roemenië)
- Het echte onderscheidende punt: de volledige cyclus van het nationale e-factureringssysteem (in Roemenië: ANAF e-Factura) verloopt via de API, niet alleen het genereren van het document.
- POST /invoices/{id}/efactura/validate voert de precontrole uit (CIUS-RO voor Roemenië) en geeft precies de velden terug die het nationale e-factureringssysteem zou weigeren, zonder iets te versturen.
- GET /invoices/{id}/xml genereert de UBL / CIUS-RO-XML (Roemenië) zonder indiening — handig voor uw eigen archief of een interne audit.
- POST /invoices/{id}/efactura/submit dient de factuur in bij het nationale e-factureringssysteem (in Roemenië: het SPV van ANAF). Dit is onomkeerbaar: een tweede exemplaar van dezelfde factuur kan niet meer worden ingetrokken.
- De levenscyclus is genormaliseerd: not_sent → validating → queued → sent → processing → accepted | rejected | error. accepted betekent wettelijk verzonden; error is een transportfout aan onze kant en mag veilig opnieuw worden geprobeerd.
- GET /efactura/submissions/{id}/download haalt het archief met het ondertekende antwoord van ANAF (Roemenië) op.
- Ook de inkomende kant bestaat: POST /efactura/inbox/sync haalt nieuwe berichten uit het SPV (Roemenië) op en GET /efactura/inbox toont de facturen die uw leveranciers u hebben gestuurd.
bash
# CIUS-RO preflight. Sends NOTHING to ANAF.
curl -sS -X POST "https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/validate?include_xml=true" \
-H "Authorization: Bearer $ACCESS_TOKEN"
# → {"invoice_id":"inv_01J7ABC","valid":false,
# "errors":["buyer.county is required for RO buyers"],
# "xml_base64":"PD94bWwg..."}bash
curl -sS -X POST https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/submit \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Idempotency-Key: efactura-inv_01J7ABC-1'
# → {"submission_id":"sub_01J7XYZ","status":"queued"}python
import time, requests
BASE = "https://api.4invoices.net/v1"
TERMINAL = {"accepted", "rejected"}
H = {"Authorization": f"Bearer {token}"}
def wait_for_anaf(submission_id, timeout=900):
deadline = time.time() + timeout
delay = 15
while time.time() < deadline:
r = requests.get(f"{BASE}/efactura/submissions/{submission_id}", headers=H, timeout=30)
r.raise_for_status()
status = r.json()["status"]
if status in TERMINAL:
return r.json()
# /refresh asks ANAF directly and shares the 10/min submit bucket.
requests.post(f"{BASE}/efactura/submissions/{submission_id}/refresh", headers=H, timeout=30)
time.sleep(delay)
delay = min(delay * 2, 120)
raise TimeoutError(submission_id)Fouten
- Elke 4xx en 5xx gebruikt dezelfde envelop: { "error": { type, code, message, param?, doc_url, request_id, errors? } }.
- type is de grove categorie waarop u vertakt („kan ik het opnieuw proberen?”), en code is de stabiele reden die u in uw eigen systeem mapt.
- param is het pad met punten naar het foutieve veld, bijvoorbeeld lines.0.vat_rate.
- errors[] verschijnt wanneer één request problemen heeft in meer dan één veld.
- request_id wordt aan onze kant gelogd. Vermeld het in elk supportticket — het identificeert het exacte request.
- Ook voor een id die bij een andere tenant hoort, wordt een 404 teruggegeven: we bevestigen nooit dat gegevens van iemand anders bestaan.
json
{
"error": {
"type": "invalid_request_error",
"code": "validation_failed",
"message": "Datele trimise nu sunt valide.",
"param": "lines.0.vat_rate",
"doc_url": "https://4invoices.net/ro/api-dezvoltatori#errors",
"request_id": "req_8a893f2f33d4472da8d6e144",
"errors": [
{ "param": "lines.0.vat_rate", "message": "VAT rate must be a percent (21), not a fraction", "type": "value_error" }
]
}
}| Status | Type | Code |
|---|---|---|
| 401 | authentication_error | missing_bearer_token |
| 401 | authentication_error | invalid_client |
| 401 | authentication_error | token_expired |
| 401 | authentication_error | invalid_token |
| 401 | authentication_error | unauthorized |
| 403 | permission_error | insufficient_scope |
| 403 | permission_error | forbidden |
| 404 | not_found_error | not_found |
| 409 | conflict_error | idempotency_key_reuse |
| 409 | conflict_error | idempotency_in_progress |
| 409 | conflict_error | no_series_configured |
| 422 | invalid_request_error | validation_failed |
| 422 | invalid_request_error | issuer_profile_incomplete |
| 422 | invalid_request_error | cius_ro_incomplete |
| 422 | invalid_request_error | cannot_storno_draft |
| 422 | invalid_request_error | nothing_to_storno |
| 422 | invalid_request_error | invalid_json_number |
| 429 | rate_limit_error | rate_limit_exceeded |
| 502 | upstream_error | upstream_error |
| 503 | service_unavailable_error | service_unavailable |
Snelheidslimieten
| Bucket | Verzoeken / minuut | Betekenis |
|---|---|---|
| read | 120 | GET *, POST /invoices/preview-totals, POST /invoices/{id}/efactura/validate |
| write | 30 | POST /invoices, POST /invoices/{id}/storno, POST|DELETE /invoices/{id}/payments, POST /clients |
| submit | 10 | POST /invoices/{id}/efactura/submit, POST /efactura/submissions/{id}/refresh, POST /efactura/inbox/sync |
- Limieten gelden per credential, per minuut: 120 voor leesbewerkingen, 30 voor schrijfbewerkingen, 10 voor e-factureringsbewerkingen (submit, refresh, inbox/sync).
- X-RateLimit-Limit, X-RateLimit-Remaining en X-RateLimit-Reset staan op ELKE respons, ook op de 429.
- Een 429 bevat ook Retry-After in seconden. Respecteer die waarde; probeer het niet opnieuw in een strakke lus.
- De bucket van 10/min bestaat omdat ANAF in Roemenië zelf ongeveer één aanroep voor het ophalen van de berichtenlijst per minuut per CIF toestaat.
- Plan /efactura/inbox/sync in een cronjob, niet met agressief opvragen.
- Hogere limieten nodig? Vraag ze aan via het contactformulier, met uw verwachte dagvolume.
X-RateLimit-Limit · X-RateLimit-Remaining · X-RateLimit-Reset · Retry-After
http
HTTP/2 429
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1785312000
Retry-After: 17
Content-Type: application/json
{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded",
"message":"...","doc_url":"https://4invoices.net/ro/api-dezvoltatori#errors",
"request_id":"req_..."}}javascript
// Respecteer Retry-After; probeer nooit een 4xx anders dan 429 opnieuw.
async function call(url, init, attempt = 0) {
const res = await fetch(url, init);
if (res.status === 429 || res.status >= 500) {
if (attempt >= 5) return res;
const retryAfter = Number(res.headers.get("Retry-After")) || 2 ** attempt;
await new Promise((r) => setTimeout(r, retryAfter * 1000));
return call(url, init, attempt + 1);
}
return res;
}
// Een schrijfretry MOET dezelfde Idempotency-Key hergebruiken, anders geef je
// een tweede fiscaal document uit.Gidsen per onderwerp
Elk onderwerp heeft een eigen pagina met de bijbehorende endpoints, voorbeelden en fouten.
- Authenticatie op de 4invoices-APIRuil client_id en client_secret voor een Bearer-token van één uur, uitsluitend server-to-server.
- Facturen uitgeven via de APIPOST /invoices met Idempotency-Key, btw in percentages, plus lijst, creditnota en betaald markeren.
- Klanten en registercontrole bij ANAF (Roemenië)Een op tax_id gededupliceerde invoeging of update, plus een controle in het ANAF-register (Roemenië) zodat de e-factuur niet wordt geweigerd.
- ANAF e-Factura (Roemenië) via de APIVoor Roemenië: CIUS-RO-preflight, SPV-indiening, genormaliseerde status, ondertekend antwoord en inbox met leveranciersfacturen.
- Nummerreeksen in de APIZonder actieve reeks van het type fiscale geeft uitgifte 409 no_series_configured.
- Foutcodes en de foutenvelopEén vorm op elke route: type, code, message, param, doc_url, request_id en errors.
- Snelheidslimieten en nieuwe pogingen120 lezingen, 30 schrijfacties en 10 e-factureringsbewerkingen per minuut per credential, met X-RateLimit-*-headers.
Veelgemaakte fouten
- De btw als breuk (0.19) of als 1 sturen. Beide worden geweigerd; stuur 19 of 21.
- Een token per request aanvragen. Het token is een uur geldig; sla het op in de cache, anders loopt u tegen de limiet per IP van het token-endpoint aan.
- Bij elke nieuwe poging een nieuwe idempotentiesleutel genereren — precies het scenario dat dubbele facturen oplevert.
- Aanroepen vanuit JavaScript in de browser. CORS blokkeert elke origin, en het secret zou hoe dan ook worden blootgesteld.
- Indienen bij het nationale e-factureringssysteem zonder precontrole (in Roemenië: CIUS-RO). Een verkeerde indiening kan niet worden ingetrokken.
- /efactura/submissions/{id}/refresh vaker dan 10 keer per minuut pollen — die bucket wordt gedeeld met submit.
- Uitgeven voordat het bedrijfsprofiel volledig is en er een actieve fiscale reeks bestaat.
Vragen en antwoorden voor ontwikkelaars
Hoe krijg ik credentials voor de 4invoices-API?
In het paneel, onder Facturatie → Instellingen → API-toegang. Je krijgt een client_id en een client_secret; het secret wordt één keer getoond en alleen als hash bewaard.
Hoe lang is het access_token geldig?
3600 seconden, dus één uur. Cache het en vernieuw voor het verloopt — het token-endpoint heeft een eigen limiet per IP.
Hoe stuur ik het btw-tarief?
Als percentage: 21 voor 21%. Waarden in (0, 1] worden geweigerd, dus 0.19 en 1 falen op validatie.
Welke calls vereisen een Idempotency-Key?
POST /invoices, POST /invoices/{id}/storno en POST /invoices/{id}/efactura/submit. Keys blijven 24 uur bekend en een replay geeft het originele document terug met Idempotency-Replayed: true.
Kan ik een factuur direct via de API bij ANAF e-Factura (Roemenië) indienen?
Ja, voor Roemenië: CIUS-RO-preflight met /efactura/validate, indienen met /efactura/submit, de genormaliseerde status volgen op /efactura/submissions/{id} en het ondertekende ANAF-antwoord downloaden.
Wat zijn de snelheidslimieten?
Per inloggegeven, per minuut: 120 lezingen, 30 schrijfacties en 10 e-factureringsbewerkingen. Elk antwoord bevat X-RateLimit-*-headers, en een 429 voegt Retry-After toe.
Kan ik de API vanuit mijn frontend aanroepen?
Nee. Het is uitsluitend server-to-server: geen browser-origin komt door CORS, en een client_secret hoort niet in code die de bezoeker bereikt.
Waarom krijg ik issuer_profile_incomplete bij mijn eerste factuur?
Het bedrijfsprofiel is onvolledig of er is geen actieve reeks van het type fiscale. Vul beide in het paneel aan; de API weigert een ongeldig fiscaal document te maken.