In the Xero Developer portal, register your webhook endpoint URL and record the webhook key provided for your app.
When a POST request arrives at your endpoint, capture the raw request body bytes before any parsing.
Compute an HMAC-SHA256 of the raw body using your webhook key as the secret.
Base64-encode the resulting HMAC digest and compare it to the value in the x-xero-signature header of the incoming request.
If the values match, the payload is authentic; respond with HTTP 200. If they do not match, respond with HTTP 401.
Parse the verified payload to extract the array of events, each containing tenantId, eventType, and resourceId for further processing.
Known gotchas
Xero sends an initial validation request (an intent-to-receive check) when you first register a webhook; your endpoint must correctly validate the signature and return 200 to complete registration.
Using the string representation of the body rather than the raw bytes for HMAC computation will cause signature mismatches due to encoding differences.
Webhook payloads do not include the changed data itself; you must use the resourceId to fetch the updated record from the Xero API.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp