Skip to main content

Webhooks setup

Webhooks notify your application when AEAT answers about an invoice, and when a VERI*FACTU incident starts or ends, so you don't have to poll the API. An event destination routes one event type to one target URL: create one for each event you handle. Destinations apply to your whole account, so they receive the events of all your legal entities.

See Event types for the events and their payloads.

1. Create an event destination​

Create a public HTTPS endpoint, then register it with POST /event-destinations:

{
"event": "invoice.sent",
"delivery": "webhook",
"target": "https://your-domain.example/webhook",
"authType": "header",
"authKey": "X-Auth",
"authToken": "my-secret-token"
}

webhook is the only delivery that sends events today. For sandbox testing you can use an external service like webhook.site to receive and inspect the events.

The response carries the uuid of the destination:

{
"uuid": "019ffeec-b9a7-7d3d-abac-2be663ec3de6",
"event": "invoice.sent",
"delivery": "webhook",
"target": "https://your-domain.example/webhook",
"authType": "header",
"authKey": "X-Auth",
"authToken": "my-secret-token"
}

You can read it back with GET /event-destinations/{uuid}.

2. Authenticate the requests​

Configure a secret token to verify that a request comes from A-Cube:

authTypeHow the token is sentDefault authKey
headerin the header named by authKeyAuthorization
queryas the authKey parameter of the URLtoken
nonenot sent

For example, authType header with authKey X-Auth sends X-Auth: my-secret-token, and authType query with authKey token calls https://your-domain.example/webhook?token=my-secret-token.

To change the token of an existing destination, use PUT /event-destinations/{uuid}. The default authKey only applies on creation, so always send it here:

{
"authType": "header",
"authKey": "X-Auth",
"authToken": "my-new-secret-token"
}

The event and the target of a destination cannot be changed: to change them, delete the destination with DELETE /event-destinations/{uuid} and create a new one.

3. Handle the delivery​

Each event is delivered with a POST request and a JSON body:

{
"eventId": "019ffeec-f799-7df7-a469-4824b2656b0e",
"eventType": "invoice.sent",
"invoiceUuid": "01a03e4a-ee3a-7e1f-b372-c8382bd4ec73",
"status": "accepted",
"errorReason": null
}

Answer with a 2xx status. If your endpoint answers with a 4xx or a 5xx, the webhook is retried 15 times, starting after 300 seconds with a back-off rate of 1.25, for a total of about 9 hours. A 404 is not retried.

  • Discard duplicates: the same event can reach you more than once. eventId is unique for each event, so use it to recognize the ones you have already handled.
  • Do not rely on the order: retries can deliver a later event first. Read the current state from the API if the order matters to you.
  • Keep a fallback: if a webhook is delayed or missing, read the invoice with GET /invoices/{uuid} or search with GET /invoices.