Configuring your server

Once you’ve created the webhook you’ll need to set up your server to receive the HTTP POST requests at the endpoint you specified. There are just a few basic things that we expect from your endpoint

  1. It uses HTTPS on the standard 443 port
  2. It responds within 5 seconds with a 200 O.K status code
  3. There is no body in the response
  4. There are no cookies in the response headers
  5. If the signature is invalid a 401 Unauthorised status code is returned

If we don’t receive an acceptable response when sending events we will continue retrying the request, with decreasing frequency for up to 24 hours. After 24 hours the webhook will be disabled and needs to be re-enabled.

If you want to test webhooks in your local dev environment, Github have a handy guide using Sinatra and ngrok.

Intent to receive

To ensure the requests you receive are coming from Xero you need to verify the signature provided in the x-xero-signature header. When creating or re-enabling a webhook subscription (or updating the subscription url) the user will be prompted to start an 'Intent to receive' validation. This validation process will be a series of HTTPS POST requests to the url provided in the subscription.

All validation requests will look like this:

   "x-xero-signature" : HASH_VALUE
     "events": [],
     "lastEventSequence": 0,
     "firstEventSequence": 0,
     "entropy": "S0m3r4Nd0mt3xt"

If the payload is hashed using HMACSHA256 with your webhook signing key and base64 encoded, it should match the signature in the header. This is a correctly signed payload. If the signature does not match the hashed payload it is an incorrectly signed payload.

To gain Intent to receive validation, the receiving url must respond with status: 200 Ok for all correctly signed payloads and respond with status: 401 Unauthorized for all incorrectly signed payloads.

It must also respond within the guidelines of all webhook requests listed above.

If the validation is passed, the status displayed in the console will change from Intent to receive in progress to OK. If the validation fails, the status will return to Intent to receive required and the last delivery attempt time and fail reason is displayed in the console. Another intent to receive validation can be requested in the console.