Nasjonal e-fakturering via API

Forhåndskontroll (CIUS-RO for Romania), innsending i det nasjonale e-fakturasystemet, normalisert status, signert svar og den innkommende leverandørinnboksen.

Forhåndskontroll (CIUS-RO for Romania), innsending i det nasjonale e-fakturasystemet, normalisert status, signert svar og den innkommende leverandørinnboksen.

← Tilbake til API-dokumentasjonen

Din første faktura på 6 steg

  1. Kjør POST /v1/invoices/{id}/efactura/validate. Forhåndskontrollen (CIUS-RO for Romania) sender ingenting til det nasjonale e-fakturasystemet og forteller deg nøyaktig hva som ville blitt avvist.
  2. Send inn med POST /v1/invoices/{id}/efactura/submit, alltid med en Idempotency-Key. Du får et submission_id og en status.
  3. Poll GET /v1/efactura/submissions/{id} til den når accepted eller rejected.
  4. Tving en fersk spørring til det nasjonale e-fakturasystemet med POST /v1/efactura/submissions/{id}/refresh — den teller mot kvoten på 10 per minutt.
  5. Last ned arkivet med det nasjonale e-fakturasystemets signerte svar (i Romania: ANAF) via GET /v1/efactura/submissions/{id}/download.

Alle endepunkter

MetodeEndepunktScopeIdempotency-KeyForespørsler / minutt
GET/invoices/{invoice_id}/xml
Last ned UBL-XML (CIUS-RO for Romania)
invoices:read—120
POST/invoices/{invoice_id}/efactura/validate
Forhåndskontroll (CIUS-RO for Romania) — valider uten å sende
efactura:read—120
POST/invoices/{invoice_id}/efactura/submit
Send fakturaen til det nasjonale e-fakturasystemet (i Romania: SPV)
efactura:submitpåkrevd10
GET/efactura/submissions
List innsendinger til det nasjonale e-fakturasystemet
efactura:read—120
GET/efactura/submissions/{submission_id}
Hent én innsending
efactura:read—120
POST/efactura/submissions/{submission_id}/refresh
Spør det nasjonale e-fakturasystemet om gjeldende status
efactura:read—10
GET/efactura/submissions/{submission_id}/download
Last ned arkivet med det signerte svaret
efactura:read—120
GET/efactura/inbox
Leverandørfakturaer mottatt via det nasjonale e-fakturasystemet
efactura:read—120
GET/efactura/inbox/{inbound_id}
Hent én innkommende faktura
efactura:read—120
GET/efactura/inbox/{inbound_id}/download
Last ned arkivet for den innkommende fakturaen
efactura:read—120
POST/efactura/inbox/sync
Hent nye meldinger fra det nasjonale e-fakturasystemet til innboksen
efactura:read—10

Hva 4invoices-API-et er

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)
bash
# Pull new SPV messages, then read the inbound supplier invoices.
curl -sS -X POST https://api.4invoices.net/v1/efactura/inbox/sync \
  -H "Authorization: Bearer $ACCESS_TOKEN"

curl -sS "https://api.4invoices.net/v1/efactura/inbox?limit=50" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# ANAF allows roughly ONE message-list call per minute per CIF,
# så /inbox/sync teller mot innsendingskvoten på 10/min. Kjør den fra cron, ikke poll den.

https://api.4invoices.net/v1 · https://api.4invoices.net/v1/openapi.json

Prosessen mot det nasjonale e-fakturasystemet

not_sentvalidatingqueuedsentprocessingacceptedrejectederror

Feil

StatusTypeKode
422invalid_request_errorcius_ro_incomplete

Vanlige feil

  • Normalisert livssyklus: not_sent → validating → queued → sent → processing → accepted | rejected | error.
  • accepted betyr lovlig overført. rejected betyr at det nasjonale e-fakturasystemet avviste den: rett opp og send inn på nytt. error er en transportfeil på vår side og er trygt å prøve igjen.
  • Innsending kan ikke angres: en ny kopi av samme faktura kan ikke trekkes tilbake fra det nasjonale e-fakturasystemet. Derfor er Idempotency-Key obligatorisk.
  • GET /v1/invoices/{id}/xml gir deg UBL-XML (CIUS-RO for Romania) uten noen innsending i det hele tatt — for ditt eget arkiv eller en revisjon.
  • Innboks: POST /v1/efactura/inbox/sync henter nye meldinger, GET /v1/efactura/inbox lister dem, og /download henter arkivet for hver innkommende faktura.
  • e-Factura-endepunktene fungerer bare for rumenske tenants; ellers får du en 404.

Spørsmål og svar for utviklere

Hvor lang tid tar det før det nasjonale e-fakturasystemet godtar en faktura?

Det varierer fra sekunder til timer. Ikke blokker salget: send inn asynkront og behandle accepted og rejected som hendelser.

Kan jeg få XML-en (CIUS-RO for Romania) uten å sende noe til det nasjonale e-fakturasystemet?

Ja. GET /v1/invoices/{id}/xml genererer dokumentet uten innsending, og /efactura/validate med include_xml=true returnerer det base64-kodet.

Hvor ofte kan jeg kjøre inbox/sync?

Høyst 10 kall per minutt, men i praksis tillater ANAF i Romania omtrent ett kall til meldingslisten per minutt per CIF. Kjør den fra cron, hvert par minutter.

Hva gjør jeg hvis statusen blir stående på error?

error er en transport- eller autentiseringsfeil på vår side, så det er trygt å prøve igjen. Hvis den vedvarer, send request_id til kundestøtte.