Webhooks
Efficiently integrate Gusto's real-time event data into your application
Overview
A webhook is an HTTP request that delivers information about an event as it happens. We recommend that you integrate with Gusto’s webhooks infrastructure so that your application can perform subsequent business logic after it receives a webhook event.
See a list of all webhook event types that Gusto offers here.
You can only create a webhook subscription if you have one application under your organization. Having more than one application will return an error.
Event payload
It’s possible that a single API request will generate multiple webhook events. For example, when a partner-managed company is created, we may push multiple events to your application.
Here is an example of a webhook event payload:
{
"event_type": "company.provisioned",
"resource_type": "Company",
"resource_id": 7756341741171842,
"resource_uuid": "5df911a0-e8e9-412d-8aaf-a46ad193dd96",
"entity_type": "Company",
"entity_id": 7756341741171842,
"entity_uuid": "5df911a0-e8e9-412d-8aaf-a46ad193dd96",
"timestamp": 1671058841,
}
The company.provisioned
event indicates that an OAuth connection has been established between the company and the partner. Note that this event is always fired, regardless of whether your application has a subscription to the Company entity type.
For all webhook events, the resource_type
will be Company. The field entity_type
refers to the underlying API resource with the state change.
Getting started
Before setting up your first webhook subscription, please review the best practices section located at the bottom of this page.
The easiest way to get started with webhooks is by using our Developer Portal. If you would prefer to set up via the API instead, please see the Setting up via the API section below.
Setting up via the Developer Portal
To get started, sign into your Developer Portal account. Click into the Application that your webhook will belong to, and select the “Webhook subscriptions” tab. This tab will allow you to add, verify, edit, and view your webhook subscriptions.
Once your verified subscription starts receiving events, you will be able to view them in your subscription’s details page, accessible via the Actions menu for a given subscription.
You can use the Event activity table to view the last n events received and filter to specific subscription types using the Search by event bar.
Please note: Your subscription must be subscribed to the subscription type of interest in order to be notified of those events. To access all events, regardless of your subscription status, you can call our Events endpoint.
Setting up via the API
1. Set up an HTTPS endpoint in your application that can accept webhook requests via a POST method.
Set up an HTTPS endpoint in your application that can accept webhook requests via a POST method.
Your endpoint should be able to handle POST requests with a JSON payload, and should quickly return a 2xx successful response within 10 seconds.
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.
2. Create a webhook subscription
When you create a webhook subscription, you should provide an initial set of subscription types that you’d like your application to receive. You may update this subscription at a later time. See all webhook event types here.
The url
noted here should be your application’s webhook URL. Once created, the webhook subscription should be in pending
status.
curl --request POST \
--url https://api.gusto-demo.com/v1/webhook_subscriptions \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'Authorization: Token API_TOKEN'\
--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));
3. Verify your new webhook subscription
Once the subscription has been created, we will send a POST request to your webhooks URL with a verification_token
. This step helps Gusto validate that webhook events are reaching its intended destination, and helps you troubleshoot any issues with webhook delivery.
If your endpoint does not receive a verification_token
, please ensure that your webhooks endpoint is set up correctly and actively listening.
Once you receive a verification_token
, call the PUT webhook_subscriptions/{webhook_subscription_uuid}/verify endpoint to verify the endpoint and begin receiving webhook events.
We recommend that you save this verification_token
for the next step. This token is used to help you verify that events were sent by Gusto.
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));
Best Practices
We recommend following these best practices to ensure the security and performance of your application.
Subscribe to only the webhook events that your application needs
This can help reduce the amount of events that your server needs to process.
Secure your webhook endpoint
We highly recommend that your application verify the source of incoming webhook requests before processing events. This step is optional but highly recommended to help prevent bad actors from engaging in unauthorized activities on your server.
Gusto computes a hash message authentication code (HMAC) of the event payload using the verification_token provided in the verification step as the secret and SHA256 as the hash function. Webhook event payloads 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.
Ensure that your event handlers are idempotent
Duplicate events may occur as a result of concurrent processing within our system, so your application’s webhook endpoint may occasionally receive the same event multiple times.
Achieving idempotency can be accomplished by monitoring the processing status of webhook events in your application. In each event payload, Gusto provides a uuid, a unique identifier for the webhook event. Storing these UUIDs in a table enables your application to determine whether an event has already been processed.
Return a 2xx response promptly
Your server should respond with a 2xx response to confirm successful receipt of a webhook event delivery. Without it, Gusto will continue to retry sending the webhook to your application. This may impact your future webhook deliveries, and Gusto may deactivate your webhook subscription.
Handle events asynchronously
Because delivery order is not guaranteed, we recommend using the event payload's timestamp field, which indicates when the event occurred, to reorder the events in your system.
We also recommend that you set up a queue to help process your event payloads asynchronously. When your application receives a webhook, it should still first respond 2xx to confirm receipt of the event delivery, and then queue the event to be processed asynchronously by your application.
This is beneficial to your application so that you can process events at a rate that your server can handle. It’s possible that Gusto sends a large volume of events in a short amount of time, especially if bulk actions have recently been taken. Implementing asynchronous event processing will ensure that your application can handle such volume spikes and reliably process all incoming webhook requests. It also gives your application more flexibility to manage resources more efficiently.
Updated 5 months ago