# Webhook callbacks A callback is the notification that Smartsheet sends to a webhook's `callbackUrl`. There are two types of callbacks: * [Event Callback](#event-callbacks): Alerts the subscriber when specified events have occurred. This is the most common type of callback. * [Status Change Callback](#status-change-callbacks): Alerts the subscriber that a webhook has been automatically disabled or automatically re-enabled. As an event subscriber, you can verify callback payload integrity (that is, you can ensure that the message wasn't tampered with enroute) and authenticate the sender identity (that is, you can ensure that the callback originated from Smartsheet). For more information, see [Authenticating callbacks](#authenticating-callbacks-optional). **Notes:** * Smartsheet webhooks don't support callbacks to servers using self-signed certificates. The callback server must use a signed certificate from a certificate authority. * The `callbackURL` can't be to a private IP address. * The `callbackURL` must use one of the following ports: `443` (default for HTTPS), `8000`, `8008`, `8080`, or `8443`. * If a callback is running for a webhook, that webhook waits on sending sending subsequent callbacks until its current callback finishes. ## Event Callbacks Smartsheet sends an event callback to subscribers when specified events occur. The callback payload is a *skinny* payload -- it indicates the changed objects and the event type that occurred in each object, but it doesn't contain any substantial object data. You can use information and references from the callback's *skinny* payload and then use the information and references in Smartsheet API requests to retrieve object data associated with the events. > **Important:** While a webhook is disabled, Smartsheet doesn't send any callbacks for it. > **Important:** For Smartsheet Commercial, a one-minute debounce optimizes event trigger handling. It reduces traffic and prevents workflows from acting on incomplete or transitional data. ## Status Change Callbacks If a webhook's owner loses access to the object that the webhook monitors (for example, the object was deleted or the webhook owner's access to the object was revoked in Smartsheet), Smartsheet automatically disables the webhook and sends a status change callback to alert the subscriber of the status change. The callback's `newWebhookStatus` attribute indicates that the webhook is now disabled (because the scope is inaccessible). If a webhook owner's access to the object is subsequently restored, Smartsheet automatically re-enables the webhook and sends a status change callback to alert the subscriber. The callback's `newWebhookStatus` attribute indicates that the webhook is now enabled. ## Callback acknowledgement The subscriber must respond to an event callback with a `200` HTTP status code to acknowledge that the callback was received. ### Callback delivery retry logic If a subscriber's response isn't a `200` status, Smartsheet retries delivery up to 14 times. The first seven retries use an exponential backoff schedule. After that, remaining retries occur once every three hours until they're all exhausted. The subscriber's response and the webhook scope determine whether to retry callback delivery. #### Sheet webhook callback retry logic | Subscriber response | Is retried? | | --- | --- | | HTTP `201` through `299` | No | | HTTP `309` through `399` | No | | HTTP `400` through `499` (except `410`) | Yes | | HTTP `410` | No | | HTTP `500` through `599` | Yes | | Any other HTTP status | No | | Request timeout | Yes | #### Plan webhook callback retry logic | Subscriber response | Is retried? | | --- | --- | | HTTP `408` | Yes | | HTTP `429` | Yes | | HTTP `502` | Yes | | HTTP `503` | Yes | | HTTP `504` | Yes | | Any other HTTP status | No | | Request timeout | Yes | If the subscriber's response disqualifies webhook retries or all retry attempts are exhausted, Smartsheet disables the webhook. This sets `enabled` to `false` and `status` to `"DISABLED_CALLBACK_FAILED"` > **Note:** A disabled webhook that has a `status` of `"DISABLED_CALLBACK_FAILED"` can be re-enabled if the subscriber successfully completes the verification process. For details, see [Launch a webhook](/api/smartsheet/guides/webhooks/launch-a-webhook#enable-your-webhook). ## Authenticating callbacks (optional) As a subscriber you can verify callback payload integrity (that is, you can ensure that the message wasn't tampered with enroute) and and authenticate the sender identity (that is, you can ensure that the callback originated from Smartsheet). When you create a new [webhook](/api/smartsheet/openapi/webhooks/webhook), Smartsheet assigns it a randomly generated `sharedSecret` value. Smartsheet uses the shared secret to sign callback payloads -- don't share the secret with third parties. Here's how you can authenticate a callback request: 1. Calculate the HMAC of the webhook's `sharedSecret` and the request body. > **Important:** You must use the SHA-256 cryptographic hash algorithm. 1. Format the calculated value as a string in base 16. 2. Compare your result with the value of the request's **Smartsheet-Hmac-SHA256** header. If the values match, you the request originated from Smartsheet and that the data hasn't been tampered with. > **Note:** To improve security, you can [reset your webhook's shared secret](/api/smartsheet/openapi/webhooks/resetsharedsecret) at periodic intervals.