Factuarea APIDevelopers

Facturació FACe (B2G)

Envia factures FacturaE 3.2.2 a FACe — codis DIR3, XML signat XAdES-EPES conservat per intent, estats de tramitació, transmissions incertes i com recuperar-te, anul·lació, simulació en sandbox i l'scope facturae:write.

Facturar a una administració pública espanyola (B2G) és obligatori a través de FACe, el punt general d'entrada de factures electròniques (Ley 25/2013). Factuarea genera l'XML FacturaE 3.2.2 de qualsevol factura emesa, el signa XAdES-EPES amb el certificat de la teva empresa i el presenta al web service de FACe — i després segueix rastrejant l'estat de tramitació que informa FACe fins que la factura es paga (o es rebutja).

El cicle de vida complet el cobreixen les cinc operacions del grup FacturaE de la Referència de l'API:

Les lectures usen l'scope facturae:read; enviar i anul·lar requereixen facturae:write. El mòdul FacturaE està inclòs des del pla Profesional.

Totes les rutes d'aquesta guia pengen de /v1/companies/{company}/…: {company} és l'id (UUID v7) del NIF amb què operes, i als exemples curl és $COMPANY_ID. Arribar a un NIF explica com resoldre'l.

Abans d'enviar

Configura els codis DIR3 del client. Tot client administració pública porta tres codis del directori DIR3, cadascun amb el format ^[A-Z][A-Z0-9]{8,9}$ (p. ex. L01280796), i opcionalment un quart, el proponent. Configura'ls en crear o actualitzar el client:

curl -X PATCH https://api.factuarea.com/v1/companies/$COMPANY_ID/contacts/0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42/customer-profile \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
  -H "Content-Type: application/json" \
  -d '{
    "dir3_accounting_office": "L01280796",
    "dir3_managing_body": "L01280796",
    "dir3_processing_unit": "L01280796"
  }'
CampRol DIR3
dir3_accounting_officeOficina contable (01)
dir3_managing_bodyÓrgano gestor (02)
dir3_processing_unitUnidad tramitadora (03)
dir3_proponentProponente (04), opcional

L'administració t'indica els codis (els tres primers sovint coincideixen); també pots consultar-los al directori públic DIR3. L'operació reemplaça el perfil, de manera que un codi que deixis fora s'esborra: envia tots els que vulguis conservar.

La factura captura aquests codis quan es crea, i pots substituir-los per factura o corregir-los després d'emetre amb una revisió administrativa. L'encaminament que compta és el de la factura, no el del contacte en viu; els rols 01 a 03 són obligatoris per enviar i el 04 és opcional. Si la factura té un encaminament conegut sense centres, l'enviament falla amb client_missing_dir3_codes encara que el contacte tingui codis.

Puja un certificat de signatura actiu. FACe només accepta factures signades, així que l'enviament requereix el certificat FNMT (PKCS#12) que la teva empresa ja usa per a VeriFactu (POST /v1/companies/{company}/verifactu/certificates). Sense certificat actiu l'enviament falla amb signing_certificate_required.

Emet la factura. Les factures en esborrany no poden viatjar a FACe — enviar o emetre abans la factura és el que congela el seu contingut legal. Els esborranys i les factures programades (encara sense número fiscal) responen invoice_not_emittable_for_facturae.

Descarregar l'XML FacturaE

Pots descarregar l'XML en qualsevol moment — per a presentació manual, arxiu o validació — sense involucrar FACe. Qualsevol factura que ja tingui número fiscal és exportable (també una cobrada, anul·lada o cancel·lada); només les factures draft i scheduled no ho són. Una factura anterior sense calendari de pagaments capturat s'exporta sense el bloc de venciments: Factuarea mai no l'inventa.

curl -OJ https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197b1c2-89ab-7def-8123-456789abcdef/facturae \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"

Amb un certificat actiu el cos va signat XAdES-EPES (política de signatura Facturae v3.1) i el fitxer es diu .xsig; sense, l'XML torna sense signar com a .xml. El header de resposta X-Facturae-Signed: true|false distingeix ambdós casos. Consulta la referència de l'endpoint.

La descàrrega tolera l'absència de certificat (obtens l'XML sense signar); l'enviament a FACe no — FACe exigeix la signatura.

Per obtenir el fitxer exacte que es va presentar en un intent, afegeix submission_id:

curl -OJ "https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197b1c2-89ab-7def-8123-456789abcdef/facturae?submission_id=0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d" \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"

Això retorna els bytes conservats d'aquell intent: mai no regenera, torna a signar ni llegeix el certificat o el contacte actuals, així que és l'evidència del que va rebre l'administració encara que la factura, els codis DIR3 o el certificat hagin canviat després. La resposta afegeix X-Facturae-Sha256 (i el mateix valor com a ETag) quan es coneix el hash del fitxer conservat. Un fitxer absent o corrupte respon 500 facturae_artifact_unavailable; no es regenera. La factura i l'intent s'han de correspondre; si no, 404.

Enviar a FACe

L'operació d'enviament no necessita cos de petició: la factura viatja a la ruta. Cada crida prepara un intent: congela la factura, l'encaminament DIR3 efectiu (proponent inclòs), el calendari de pagaments, el certificat que signa i l'XML signat exacte, i només després parla amb FACe:

curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197b1c2-89ab-7def-8123-456789abcdef/face-submissions \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
  -H "Idempotency-Key: $(uuidgen)"

Resposta (201 per a un intent nou):

{
  "data": {
    "id": "0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
    "object": "face_submission",
    "invoice_id": "0197b1c2-89ab-7def-8123-456789abcdef",
    "status": "submitted",
    "registry_number": "202612345678",
    "dir3_accounting_office": "L01280796",
    "dir3_managing_body": "L01280796",
    "dir3_processing_unit": "L01280796",
    "error_code": null,
    "error_message": null,
    "status_updated_at": "2026-06-12T10:15:00Z",
    "last_polled_at": null,
    "created_at": "2026-06-12T10:15:00Z",
    "dir3_proponent": null,
    "administrative_version": 1,
    "administrative_revision_id": null,
    "payment_terms_version": 1,
    "source_fingerprint": "6d2f8a4c1b73e5b0a9c4d7e1f3a6b8c2d5e9f0a1b4c7d8e2f3a5b6c9d0e1f2a3",
    "artifact_sha256": "b4c7d8e2f3a5b6c9d0e1f2a36d2f8a4c1b73e5b0a9c4d7e1f3a6b8c2d5e9f0a1",
    "prepared_at": "2026-06-12T10:14:58Z",
    "transmission_started_at": "2026-06-12T10:14:59Z",
    "can_transmit": false,
    "requires_reconciliation": false,
    "signing_certificate_fingerprint": "e5b0a9c4d7e1f3a6b8c2d5e9f0a1b4c7d8e2f3a5b6c9d0e1f2a36d2f8a4c1b73",
    "artifact_status": "ready"
  }
}

registry_number és l'assentament registral de FACe que acredita la presentació — conserva'l per a qualsevol disputa amb l'administració. Els camps addicionals identifiquen el que ha congelat l'intent: source_fingerprint, artifact_sha256 (hash de l'XML conservat), l'administrative_version i la payment_terms_version usades i l'empremta del certificat. artifact_status és ready, unverified (un intent anterior al hash), unavailable o corrupt.

L'intent és la unitat, no la crida

El cos és opcional. Sense ell, Factuarea crea la identitat de l'intent i respon 201. També pots enviar el teu propi submission_id (un UUID v7) al cos:

curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197b1c2-89ab-7def-8123-456789abcdef/face-submissions \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "submission_id": "0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d" }'
  • Un submission_id nou crea un intent nou: 201.
  • Un d'existent d'aquella factura el continua: 200, amb el mateix XML conservat i el mateix certificat, sense tornar a mirar el certificat actual ni el contacte. Si FACe ja l'havia acceptat, reps el resultat desat i no s'envia res dues vegades.
  • submission_id: null es rebutja, i un id d'una altra factura o d'una altra empresa és un 404.
  • L'Idempotency-Key no substitueix el submission_id: la clau reprodueix una petició HTTP; l'id identifica l'intent durador. Les operacions d'enviament i cancel·lació estan declarades com a no reintentables automàticament (x-no-retry): els SDK no les reintenten, així que gestiona els errors com es descriu a continuació en lloc d'embolicar la crida en un bucle de reintents a cegues.

Si la crida acaba amb 502 face_transmission_failed (FACe caigut, timeout, resposta mal formada) o 500 face_submission_completion_failed, l'intent existeix i error.details.attempt_id et dona el seu id. No enviïs mai un enviament nou a cegues: llista els intents de la factura (historial) o recupera aquell, i mira el seu status:

status després de l'errorQuè significaQuè fas
preparedCongelat i signat, mai transmès.Reintenta amb el mateix submission_id.
transmission_uncertainLa petició ha sortit cap a FACe i es desconeix el resultat. Un timeout no demostra que FACe no l'hagi rebuda.No tornis a enviar. Les crides responen 409 face_transmission_uncertain amb el mateix attempt_id fins que l'intent es concilii, cosa que Factuarea fa amb evidència auditada (requires_reconciliation: true); contacta amb suport.
submitted i posteriorsFACe ja el té.Segueix-lo com qualsevol enviament.
errorL'intent ha fallat. Només s'allibera si FACe l'ha rebutjat explícitament (error_code: face_rejected) o s'ha confirmat la no recepció (confirmed_not_received).En aquests casos corregeix la causa i envia de nou amb una identitat nova; si no, continua bloquejat.

Un intent prepared o en qualsevol estat de tramitació no final en bloqueja un de nou per a la mateixa factura (409 face_submission_already_exists), i un d'incert respon 409 face_transmission_uncertain; rejected i cancelled l'alliberen. Un 409 face_submission_attempt_conflict vol dir que una altra petició ja té o ha acabat aquell intent: torna a llegir-lo.

Seguir l'estat de tramitació

FACe informa de com l'administració tramita la factura. Factuarea consulta FACe periòdicament i actualitza cada enviament — recuperar el detall de l'enviament (o l'historial d'enviaments de la factura) és la manera de seguir el progrés; no hi ha endpoint de refresc a v1:

curl https://api.factuarea.com/v1/companies/$COMPANY_ID/face-submissions/0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"
statusSignificat
preparedXML signat conservat, encara sense transmetre. Continua'l amb el seu submission_id.
transmission_uncertainLa transmissió ha començat i es desconeix el resultat. Bloqueja nous enviaments fins que es concilii.
submittedPresentada a FACe; número de registre assignat.
registered_rcfRegistrada al RCF (el registre comptable de factures de l'administració).
accountedReconeguda com a obligació comptable per l'administració.
paidL'administració informa de la factura com a pagada.
rejectedRebutjada per l'administració — consulta el motiu a FACe i emet una factura corregida.
cancellation_requestedHas sol·licitat l'anul·lació; pendent de confirmació de FACe.
cancelledAnul·lació confirmada per FACe.
errorError local de transmissió — error_code i error_message porten el detall.

Prefereixes push a polling? Subscriu-te als esdeveniments de webhook facturae.face_submitted, facturae.face_status_changed i facturae.face_cancellation_requested.

Sol·licitar l'anul·lació

Mentre la factura no s'hagi pagat ni rebutjat pots sol·licitar-ne l'anul·lació (anul·lació 4200). El reason és obligatori i viatja a FACe:

curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/face-submissions/0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/cancel \
  -H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Factura emitida por error al organismo equivocado." }'

L'anul·lació només es permet en un estat anul·lable (submitted, registered_rcf, accounted); en cas contrari la crida respon face_submission_not_cancellable. L'enviament passa a cancellation_requested fins que FACe confirma l'estat final cancelled.

Mode de prova

Amb una clau de prova (fact_test_) tot el flux es simula: cap crida SOAP arriba a FACe i l'enviament rep un número de registre sintètic amb prefix FACE-SANDBOX-*. Les validacions de signatura i DIR3 segueixen aplicant, així que el sandbox exercita els mateixos camins d'error que producció. Consulta el mode de prova.

Errors

HTTPcode / subcodeQuan
404resource_not_foundLa factura o l'enviament no existeix o pertany a una altra empresa.
422business_rule_violation / invoice_not_emittable_for_facturaeLa factura està en esborrany o programada, així que no té número fiscal — emet-la primer.
422business_rule_violation / client_missing_dir3_codesAl client li falta un o més codis DIR3.
422business_rule_violation / signing_certificate_requiredSense certificat de signatura actiu — puja'n un via POST /v1/companies/{company}/verifactu/certificates.
422business_rule_violation / face_submission_not_cancellableL'enviament no està en un estat anul·lable.
409resource_already_exists / face_submission_already_existsJa existeix un enviament actiu per a la factura.
422face_submission_rejectedFACe ha analitzat l'enviament i l'ha rebutjat amb el seu propi codi (codi DIR3 erroni, signatura no vàlida, duplicat); no ha registrat la factura. details.attempt_id identifica l'intent (el seu error_code és face_rejected): corregeix les dades i envia de nou amb una identitat nova.
409face_transmission_uncertainUn intent anterior té un resultat desconegut. No es transmet res; details.attempt_id és l'intent que has de revisar.
409face_submission_attempt_conflictUna altra petició té o ja ha completat aquell intent. Torna a llegir-lo.
500face_submission_completion_failedNo s'ha registrat el resultat; l'intent es conserva (details.attempt_id) i continua bloquejat.
500facturae_artifact_unavailableL'XML conservat de l'intent falta o està corrupte; no es regenera.
403facturae_operation_forbiddenL'autoritat vigent de l'emissor no permet l'operació (enviar exigeix autoritat d'enviament; cancel·lar exigeix accés d'edició al mòdul).
403insufficient_scopeLa clau no té l'scope facturae:write.
502face_transmission_failedEl web service de FACe ha fallat o ha esgotat el temps. L'intent es conserva i details.attempt_id l'identifica: mira el seu status abans de fer res més.

En aquesta pàgina

Et donem un cop de mà?Contactar amb suport