Webhook event types
| Category | event | Delivered when |
|---|---|---|
| Invoice | invoice.sent | AEAT registered the invoice |
| Invoice | invoice.rejected | AEAT rejected the invoice or a correction |
| Invoice | invoice.failed | AEAT returned a definitive negative outcome |
| Incident | verifactu.incident | a VERI*FACTU incident started or ended for an issuer |
invoice.received, legal_entity.onboarding_completed and
legal_entity.onboarding_failed can be configured but are not delivered yet.
Every body carries a unique eventId and the eventType. See
Webhooks setup to subscribe and to handle the delivery.
Invoice events
An invoice event is delivered once the new status of the invoice is saved, so a
GET /invoices/{uuid} made after it
returns that status.
{
"eventId": "019ffeec-f799-7df7-a469-4824b2656b0e",
"eventType": "invoice.rejected",
"invoiceUuid": "01a03e4a-ee3a-7e1f-b372-c8382bd4ec73",
"status": "rejected",
"errorReason": "INVALID_RECIPIENT_FISCAL_ID"
}
| Field | Type | Meaning |
|---|---|---|
eventId | string | unique identifier of the event, use it to discard duplicates |
eventType | string | the event type |
invoiceUuid | string | the uuid of the invoice |
status | string | the status of the invoice |
errorReason | string, nullable | the errorReason of the invoice, null when there is none |
The event type tells you the outcome, and status the state the invoice ended in:
eventType | status | When |
|---|---|---|
invoice.sent | accepted | AEAT accepted the invoice or its correction |
invoice.sent | accepted_with_errors | AEAT registered the invoice but flagged issues, see Correct an invoice |
invoice.rejected | rejected | AEAT rejected the invoice |
invoice.rejected | accepted_with_errors | AEAT rejected a correction: it keeps the record it already had, and you can correct it again |
invoice.failed | failed | AEAT returned a negative processing outcome |
The AEAT code and description are not part of the payload: read aeatErrorCode and
aeatErrorDescription with
GET /invoices/{uuid}, see
AEAT response fields.
An invoice in status error does not produce an invoice event, because A-Cube sends it
again: you get the event when it reaches one of the outcomes above.
VERI*FACTU incident
An incident starts when a transient failure stops A-Cube from reporting the billing
records of an issuer to AEAT, for example when AEAT does not answer. The records stay
in the chain of the issuer, and A-Cube sends them again in order. While the incident is
open they are flagged as sent late (sentWithIncident), see
AEAT response fields.
verifactu.incident is delivered twice for each incident, when it starts and when it
ends. Further failures during an open incident do not produce new events.
When the incident starts:
{
"eventId": "019ffeec-f799-7df7-a469-4824b2656b0e",
"eventType": "verifactu.incident",
"fiscalId": "A58818501",
"incidentActive": true,
"incidentSince": "2026-11-06T13:38:13+00:00",
"pendingRecords": 3
}
When every pending record has been sent and the incident ends:
{
"eventId": "019ffeed-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"eventType": "verifactu.incident",
"fiscalId": "A58818501",
"incidentActive": false,
"incidentSince": null,
"pendingRecords": 0
}
| Field | Type | Meaning |
|---|---|---|
eventId | string | unique identifier of the event, use it to discard duplicates |
eventType | string | always verifactu.incident |
fiscalId | string | the tax ID of the issuer whose chain is affected |
incidentActive | boolean | true when the incident starts, false when it ends |
incidentSince | string, nullable | when the incident started (ISO 8601), null when it ends |
pendingRecords | integer | how many records of the issuer are still to send, 0 when the incident ends |
The event refers to the issuer, not to an invoice: each record still gets its own invoice event when it reaches its outcome.
You can trigger all of these events in the sandbox.