Validació prèvia (a Romania, CIUS-RO), presentació al sistema nacional (a Romania, el SPV), estat normalitzat, resposta signada i safata d'entrada de proveïdors.
← Torna a la documentació de l'API
La teva primera factura en 6 passos
- Executa POST /v1/invoices/{id}/efactura/validate. La validació prèvia (a Romania, CIUS-RO) no envia res al sistema nacional de facturació electrònica i t'indica exactament què seria rebutjat.
- Presenta-la amb POST /v1/invoices/{id}/efactura/submit, sempre amb un Idempotency-Key. Reps un submission_id i un estat.
- Consulta GET /v1/efactura/submissions/{id} fins que arribi a accepted o rejected.
- Força una consulta nova al sistema nacional de facturació electrònica amb POST /v1/efactura/submissions/{id}/refresh — compta en el grup de 10 per minut.
- Descarrega l'arxiu amb la resposta signada del sistema nacional (a Romania, l'ANAF) via GET /v1/efactura/submissions/{id}/download.
Tots els punts finals
| Mètode | Punt final | Àmbit | Idempotency-Key | Peticions / minut |
|---|---|---|---|---|
| GET | /invoices/{invoice_id}/xml Descarrega el XML UBL (a Romania, CIUS-RO) | invoices:read | — | 120 |
| POST | /invoices/{invoice_id}/efactura/validate Validació prèvia (a Romania, CIUS-RO) — valida sense enviar | efactura:read | — | 120 |
| POST | /invoices/{invoice_id}/efactura/submit Presenta la factura al sistema nacional de facturació electrònica (a Romania, ANAF/SPV) | efactura:submit | obligatori | 10 |
| GET | /efactura/submissions Llista les presentacions al sistema nacional de facturació electrònica | efactura:read | — | 120 |
| GET | /efactura/submissions/{submission_id} Recupera una presentació | efactura:read | — | 120 |
| POST | /efactura/submissions/{submission_id}/refresh Demana al sistema nacional de facturació electrònica l'estat actual | efactura:read | — | 10 |
| GET | /efactura/submissions/{submission_id}/download Descarrega l'arxiu de la resposta signada | efactura:read | — | 120 |
| GET | /efactura/inbox Factures de proveïdors rebudes via el sistema nacional de facturació electrònica | efactura:read | — | 120 |
| GET | /efactura/inbox/{inbound_id} Recupera una factura rebuda | efactura:read | — | 120 |
| GET | /efactura/inbox/{inbound_id}/download Descarrega l'arxiu de la factura rebuda | efactura:read | — | 120 |
| POST | /efactura/inbox/sync Recull els nous missatges del sistema nacional de facturació electrònica a la safata d'entrada | efactura:read | — | 10 |
Què és l'API de 4invoices
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,
# així que /inbox/sync consumeix del grup de 10/min. Programa'l amb cron, no el sondegis.https://api.4invoices.net/v1 · https://api.4invoices.net/v1/openapi.json
El cicle amb el sistema nacional de facturació electrònica
Errors
| Estat | Tipus | Codi |
|---|---|---|
| 422 | invalid_request_error | cius_ro_incomplete |
Errors habituals
- Cicle de vida normalitzat: not_sent → validating → queued → sent → processing → accepted | rejected | error.
- accepted vol dir transmesa legalment. rejected vol dir que el sistema nacional de facturació electrònica la va refusar: corregeix-la i torna a presentar-la. error és una fallada de transport per la nostra part i es pot reintentar sense risc.
- La presentació és irreversible: una segona còpia de la mateixa factura no es pot retirar del sistema nacional de facturació electrònica. Per això l'Idempotency-Key és obligatòria.
- GET /v1/invoices/{id}/xml et dona el XML UBL (a Romania, CIUS-RO) sense cap presentació — per al teu arxiu o per a una auditoria.
- Safata d'entrada: POST /v1/efactura/inbox/sync recull els nous missatges, GET /v1/efactura/inbox els llista, i /download descarrega l'arxiu de cada factura rebuda.
- Els punts finals e-Factura només funcionen per a clients romanesos; en cas contrari reps un 404.
Preguntes i respostes per a desenvolupadors
Quant triga el sistema nacional de facturació electrònica a acceptar una factura?
Varia, de segons a hores. No bloquegis la venda: presenta de manera asíncrona i tracta accepted i rejected com a esdeveniments.
Puc obtenir el XML (a Romania, CIUS-RO) sense enviar res al sistema nacional de facturació electrònica?
Sí. GET /v1/invoices/{id}/xml genera el document sense presentació, i /efactura/validate amb include_xml=true el retorna codificat en base64.
Cada quant puc executar inbox/sync?
Com a màxim 10 crides per minut, però a la pràctica, a Romania, l'ANAF permet aproximadament una crida de llistat de missatges per minut per CIF. Executa'l des d'un cron, cada pocs minuts.
Què faig si l'estat es queda en error?
error és una fallada de transport o d'autenticació per la nostra part, per tant es pot reintentar sense risc. Si persisteix, envia el request_id a suport.