Learn how to subscribe to events in Bob and be notified whenever a change occurs.
Bob webhooks allow you to subscribe to system events and receive programmatic notifications about changes as they occur. When adding a webhook, you should provide a webhook URL, which you will use whenever an event occurs. Each event will send information about the event in the event's payload.
When one of those events is triggered (for example, a new employee is added), Bob will send this notification as an HTTP POST request, with a JSON body, to the endpoint you specify.
If you’re new to the concept of webhooks, read this guide to learn more..
Webhook versions
Starting January 21, 2025, Bob Webhooks v2 will be open for use.
Bob Webhooks v2 adds reliability and stability by reducing the data sent on the payload, ensuring the events will be sent in the right order, and better handling of retries when a webhook fails to send the event.
Note: Webhooks v2 will eventually replace Webhooks v1, so we recommend using v2 for your current and future implementations. For additional details, see Migrating to webhooks v2.
Webhook payload structure (v2)
Bob's webhooks v2 events payload have a unified structure that contains metadata about the event, and about the fields that have changed. Additionally, it includes the identifier of the entity that has triggered the event(e.g., employeeId
, documentId
). To pull the data itself, please use our API.
Event payload data includes:
Property | Description |
---|---|
version | The webhook version v2 (included only for v2 webhooks). |
type | The event type is based on Bob’s supported events. |
triggeredBy | the backend-id of the employee that triggered the event or ‘system’ for events triggered automatically by the system. |
triggeredAt | The timestamp when the event occurred. |
data section | Contains the actual data and differs for each event type. Click the links below to learn about the available event types and their payload in v2: - Employee event payload - Time off event payload - Task event paylaod - Docs event payload |
Retry policy (v2)
With Webhooks v2, Bob attempts to deliver a given event to your webhook endpoint for up to 3 days with an exponential backoff. We expect the webhook endpoint's queue to always respond with a 200 (OK) status. Repeated failures will trigger retries.
Failure to deliver will be visible on the webhooks page, showing delivery errors. Additionally, email notifications will be sent to Bob Admins and other people selected to get notifications.
Bob webhooks’ retry policy is as follows:
- In case the original notification-sending attempt fails (due to receiving an error response code or exceeding the timeout of 10 seconds), we will retry to send the event in progressively increasing time intervals.
- If it fails in any of these attempts, we will send an email notification as follows:
- After 1 hour (webhook status: Delivery error)
- After 24 hours (webhook status: Delivery error)
- After 48 hours (webhook status: Delivery error)
- After 72 hours (webhook status: Inactive) - notifying about webhook deactivation
- If there are no successful deliveries on 3 consecutive days, we will deactivate this specific webhook.
Note: Webhook events are saved for at least two working days. So, if the a webhook becomes deactivated on a non-working day, it will still keep events that occur during the these days, to let your team a chance to fix the issue in the next working day, without data loss. Non-working days include Friday, Saturday, and Sunday.
Email notifications (v2)
As part of the retry mechanism, when a webhook fails, the server emails Bob Admins to let them know they should fix the problem on the webhook listener side and provide suggested resolutions whenever possible.
Additionally, you can configure specific users to be notified of delivery issues. To learn more, see How to add people to the email notification ↗.
How to develop a webhooks listener
Developing your event listener includes the following steps:
# | Step | Description | Additional links |
---|---|---|---|
1 | Configure a publicly accessible URL | To start working with Webhooks you should configure a publicly accessible URL (endpoint), to which Bob can send HTTP requests. This is where you develop your listener's code. | See how to add the webhook in Bob ↗ and provide the URL. |
2 | Validate your connection | Bob sends an initial POST request with the text "Ping test" or a JSON with: {"text":"Ping test"}. The listener must process these events and immediately return a 200 status code. | |
3 | Authenticate your events | Requests from Bob to your system will be signed, and the secret signature can be grabbed from the Bob UI. | 1. See how does Bob calculate the signature. 2. For increased security, you can also whitelist Bob's IPs ↗. |
4 | Process event payload | The event Payload includes metadata about the event, such as the identifier of the entitiy that was updated. | 1. Process the events payload coming from Bob. 2. Call Bob's Public API to fetch the full details. 3. View webhook activity logs in Bob ↗. |
How does Bob calculate the signature
Requests from Bob to your system will be signed, and the secret signature can be grabbed from the Bob UI as part of the Webhook configuration.
The algorithm used for creating the signature is HMAC SHA512. The example below shows that the signature is created by employing HMAC SHA512 on the request payload and the secret token given. The signature itself is sent as the header attribute - Bob-Signature.
Here is an example of how you can calculate the signature.
import java.nio.charset.StandardCharsets._
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
import org.apache.commons.codec.binary.Base64
private def getSignature(secret: String, content: Array[Byte]) = {
val mac = Mac.getInstance("HmacSHA512")
val key = new SecretKeySpec(secret.getBytes(UTF_8), "HmacSHA512")
mac.init(key)
val signature = mac.doFinal(content)
Base64.encodeBase64String(signature)
}
digest = OpenSSL::Digest.new('sha512')
Base64.encode64(OpenSSL::HMAC.digest(digest, secret_key, body))
<?php
// Requires PHP >= 5.1.2 and PECL hash >= 1.1
$signature = base64_encode(hash_hmac('sha512', $body, $secret_key, true));
?>
$token = "THE_TOKEN_THAT_WAS_PROVIDED"
$payload = "THE PAYLOAD"
$encodedToken = [Text.Encoding]::UTF8.GetBytes($token)
$hmacsha = New-Object System.Security.Cryptography.HMACSHA512 (,$encodedToken)
$signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($payload))
$signature = [Convert]::ToBase64String($signature)
import crypto from 'crypto';
var hmac = crypto.createHmac("sha512", secret);
var signature = hmac.update(new Buffer(json, 'utf-8')).digest("base64");
Testing webhooks
You can use webhook testing tools to listen to the events and review the payload before you start coding the listener or code the listener and test the workflow in your environment.
Note: For testing, consider using event listeners. These are online services that allow users to create and manage custom webhook endpoints for testing webhooks. This will enable you to see the events Bob sends when you subscribe, even before you develop your own event listener.
Disclaimer: Sending events to an external tool means you may expose your data. Make sure you trust the tool with your data.