FACe invoicing (B2G)
Submit FacturaE 3.2.2 invoices to FACe — DIR3 codes, signed XAdES-EPES XML, processing states, cancellation, sandbox simulation and the facturae:write scope.
Invoicing a Spanish public administration (B2G) is mandatory through FACe, the general entry point for electronic invoices (Ley 25/2013). Factuarea generates the FacturaE 3.2.2 XML for any issued invoice, signs it XAdES-EPES with your company certificate and presents it to the FACe web service — then keeps tracking the processing status reported by FACe until the invoice is paid (or rejected).
The whole lifecycle is covered by the five operations of the FacturaE group in the API Reference:
- Download the FacturaE XML of an invoice — signed or unsigned, with or without FACe.
- Submit an invoice to FACe.
- List the submissions of an invoice.
- Retrieve a submission to track its processing status.
- Request the cancellation of a submission.
Reads use the facturae:read scope; submitting and cancelling require
facturae:write. The FacturaE module is included in the Empresario and
Enterprise plans.
Before you submit
Set the client's three DIR3 codes. Every public-administration client
carries three codes from the DIR3 directory, each matching
^[A-Z][A-Z0-9]{8,9}$ (e.g. L01280796). Set them when you create or
update the client:
curl -X PUT https://api.factuarea.com/v1/clients/0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42 \
-H "Authorization: Bearer fact_live_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Content-Type: application/json" \
-d '{
"dir3_accounting_office": "L01280796",
"dir3_managing_body": "L01280796",
"dir3_processing_unit": "L01280796"
}'| Field | DIR3 role |
|---|---|
dir3_accounting_office | Oficina contable (01) |
dir3_managing_body | Órgano gestor (02) |
dir3_processing_unit | Unidad tramitadora (03) |
The administration tells you the three codes (they often coincide); you can also look them up in the public DIR3 directory.
Upload an active signing certificate. FACe only accepts signed
invoices, so submission requires the FNMT (PKCS#12) certificate your company
already uses for VeriFactu (POST /v1/verifactu/certificates). Without an
active certificate the submission fails with signing_certificate_required.
Issue the invoice. Draft invoices cannot travel to FACe — sending or
emitting the invoice first is what freezes its legal content. Drafts answer
invoice_not_emittable_for_facturae.
Downloading the FacturaE XML
You can download the XML at any time — for manual presentation, archiving or validation — without involving FACe:
curl -OJ https://api.factuarea.com/v1/invoices/0197b1c2-89ab-7def-8123-456789abcdef/facturae \
-H "Authorization: Bearer fact_live_3pXnR2VbY7TcA9eFmN5z8KqW"With an active certificate the body is signed XAdES-EPES (Facturae v3.1
signature policy) and the file is named .xsig; without one, the XML comes
back unsigned as .xml. The X-Facturae-Signed: true|false response header
tells both cases apart. See the
endpoint reference.
Downloading tolerates a missing certificate (you get unsigned XML); submitting to FACe does not — FACe requires the signature.
Submitting to FACe
The submit operation takes no request body: the invoice travels in the path and the DIR3 codes are read from the client at submission time (and snapshotted on the submission):
curl -X POST https://api.factuarea.com/v1/invoices/0197b1c2-89ab-7def-8123-456789abcdef/face-submissions \
-H "Authorization: Bearer fact_live_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Idempotency-Key: $(uuidgen)"Response (201):
{
"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"
}
}registry_number is the FACe registry entry that proves the presentation —
keep it for any dispute with the administration.
Tracking the processing status
FACe reports how the administration processes the invoice. Factuarea polls FACe periodically and updates each submission — retrieving the submission detail (or the invoice's submission history) is the way to track progress; there is no refresh endpoint in v1:
curl https://api.factuarea.com/v1/face-submissions/0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d \
-H "Authorization: Bearer fact_live_3pXnR2VbY7TcA9eFmN5z8KqW"status | Meaning |
|---|---|
submitted | Presented to FACe; registry number assigned. |
registered_rcf | Registered in the RCF (the administration's accounting registry of invoices). |
accounted | Recognized as an accounting obligation by the administration. |
paid | The administration reports the invoice as paid. |
rejected | Rejected by the administration — check the reason in FACe and issue a corrected invoice. |
cancellation_requested | You requested cancellation; awaiting FACe confirmation. |
cancelled | Cancellation confirmed by FACe. |
error | Local transmission error — error_code and error_message carry the detail. |
Prefer push over polling? Subscribe to the
webhook events facturae.face_submitted,
facturae.face_status_changed and facturae.face_cancellation_requested.
Requesting cancellation
While the invoice has not been paid or rejected you can
request its cancellation
(anulación 4200). The reason is mandatory and travels to FACe:
curl -X POST https://api.factuarea.com/v1/face-submissions/0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/cancel \
-H "Authorization: Bearer fact_live_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Content-Type: application/json" \
-d '{ "reason": "Factura emitida por error al organismo equivocado." }'Cancellation is only allowed in a cancellable state (submitted,
registered_rcf, accounted); otherwise the call answers
face_submission_not_cancellable. The submission moves to
cancellation_requested until FACe confirms the final cancelled state.
Test mode
With a test key (fact_test_) the whole flow is simulated: no SOAP call
ever reaches FACe and the submission gets a synthetic registry number
prefixed FACE-SANDBOX-*. Signature and DIR3 validations still apply, so
the sandbox exercises the same error paths as production. See
test mode.
Errors
| HTTP | code / subcode | When |
|---|---|---|
| 404 | resource_not_found | The invoice or submission doesn't exist or belongs to another company. |
| 422 | business_rule_violation / invoice_not_emittable_for_facturae | The invoice is a draft — issue it first. |
| 422 | business_rule_violation / client_missing_dir3_codes | The client lacks one or more DIR3 codes. |
| 422 | business_rule_violation / signing_certificate_required | No active signing certificate — upload one via POST /v1/verifactu/certificates. |
| 422 | business_rule_violation / face_submission_not_cancellable | The submission is not in a cancellable state. |
| 409 | resource_already_exists / face_submission_already_exists | An active submission already exists for the invoice. |
| 403 | insufficient_scope | The key lacks the facturae:write scope. |
| 502 | face_transmission_failed | The FACe web service is down — nothing is persisted; retry later. |