GuidesAPI ReferenceChangelogAPI PolicyAPI StatusGusto Security

Gusto Embedded offers webhooks for partners to receive Webhook Events.

1. Create a webhook subscription

You can register a webhook subscription URL using the POST webhook_subscriptions endpoint and a list of subscription types.

curl --request POST \
     --url https://api.gusto-demo.com/v1/webhook_subscriptions \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
     "subscription_types": [
          "Company",
          "Employee"
     ],
     "url": "https://leading-role-app.com/subscriber"
}
'
const fetch = require('node-fetch');

const url = 'https://api.gusto-demo.com/v1/webhook_subscriptions';
const options = {
  method: 'POST',
  headers: {accept: 'application/json', 'content-type': 'application/json'},
  body: JSON.stringify({
    subscription_types: ['Company', 'Employee'],
    url: 'https://leading-role-app.com/subscriber'
  })
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));

🚧

You can only create a webhook subscription if you have one application under your organization. Having more than one application will return an error.

2. Verify the Subscription

Before the subscription URL receives any event updates, it will first receive a verification_token .

{"verification_token": "6590f590-3dba-495e-9bea-c361e1e2efc0"}

Use this token with the PUT webhook_subscriptions/{webhook_subscription_uuid}/verify endpoint to verify the endpoint and begin receiving webhook events.

curl --request PUT \
     --url https://api.gusto-demo.com/v1/webhook_subscriptions/{webhook_subscription_uuid}/verify \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
     "verification_token": "asefasedfe23e234easd"
}
'
const fetch = require('node-fetch');

const url = 'https://api.gusto-demo.com/v1/webhook_subscriptions/{webhook_subscription_uuid}/verify';
const options = {
  method: 'PUT',
  headers: {accept: 'application/json', 'content-type': 'application/json'},
  body: JSON.stringify({verification_token: 'asefasedfe23e234easd'})
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));

3. Handling Webhooks events

Upon receiving a webhook event, you must acknowledge receipt of the successful notification by responding with a 2xx status. In absence of this acknowledgement, our system will assume delivery failure and continue to retry up to 16 times over the course of 3 days using an exponential backoff scheme.

Duplicate events may occur as a result of concurrent processings within our system. Please ensure your webhook event handlers are idempotent.

Additionally, asynchronous processes and network delays may result in events getting sent or received out of order. We recommend using the event payload's timestamp field, which indicates when the event occurred, to reorder the events in your system.

4. (Optional) Verifying event integrity

Gusto computes a hash message authenticate code (HMAC) of the event payload using the verification_tokenprovided in the verification step as the secret and SHA256 as the hash function. Webhook Events include a X-Gusto-Signature header, which is set to the computed HMAC.

Event payload integrity can be verified by the subscriber by computing the event payload HMAC and checking that it is equal to the HMAC in the X-Gusto-Signature header.

verification_token = '6590f590-3dba-495e-9bea-c361e1e2efc0'

hmac = OpenSSL::HMAC.hexdigest("SHA256", verification_token, request.body)

if hmac == request.headers['X-Gusto-Signature']
  puts "the event was sent by Gusto"
else
  puts 'do not trust the source'
end