/webhooks/xero
auth: hmac (x-xero-signature)Xero-initiated webhook delivery. Verifies HMAC-SHA256 over the raw request body using `XERO_WEBHOOK_SIGNING_KEY` (constant-time compared to the base64 `x-xero-signature` header). Valid signature → fan each event to the `xero:webhook:events` Redis Stream and respond `200` within Xero's 5-second ack budget. Xero's intent-to-receive handshake (`events: []`) flows through the same code path. NOT mounted under `/api/v1`.
handlers: XeroWebhookController.handle
| name | required | default | description |
|---|---|---|---|
x-xero-signature headerstring | yes | — | Base64-encoded HMAC-SHA256 of the raw request body. |
events bodyXeroWebhookEvent[] | no | — | Array of event objects (`tenantId`, `tenantType`, `eventCategory`, `eventType`, `resourceId`, `resourceUrl`, `eventDateUtc`, `eventSequence`). Empty array is the intent-to-receive ping. |
firstEventSequence bodyinteger | no | — | Sequence number of the first event in the batch. |
lastEventSequence bodyinteger | no | — | Sequence number of the last event in the batch. |
entropy bodystring | no | — | Random salt included by Xero. |
emptyAPIErrorAPIError