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:
authType | How the token is sent | Default authKey |
|---|---|---|
header | in the header named by authKey | Authorization |
query | as the authKey parameter of the URL | token |
none | not 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.
eventIdis 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 withGET /invoices.