> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.hellosign.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.hellosign.com/_mcp/server.

> Click here to learn about Dropbox Sign Events how to use webhooks to automate your integration with the Dropbox Sign API.

# Events Walkthrough

This walkthrough covers how to build with Dropbox Sign Events and Callbacks (aka "webhooks"), which are payloads of event metadata automatically sent to your app when something happens in Dropbox Sign.

This resource centers implementation details, examples, and building with webhooks. For a higher-level overview of Dropbox Sign Events, please refer to the [Events Overview](/docs/guides/events-and-callbacks/overview) section of the documentation.

## Event Scoping

When using the Dropbox Sign API, events can occur in two contexts: at the Account level and at the App level. Events that are scoped to an Account are called Account Callbacks while events scoped to an App are called App Callbacks. We recommend referring to their respective pages for more detailed information.

### Account Callbacks

[Account Callbacks](/api/events/account-update-event-callback) notify your app when an event happens involving your account by sending the event payload to your *account callback url*. The account callback url can be configured on the Dropbox Sign website or by calling the Dropbox Sign API. You can see examples of both in the [Set Account Callback Url](#set-account-callback-url) section of this walkthrough.

### App Callbacks

[App Callbacks](/api/events/api-app-create-event-callback) are triggered when an event happens that is associated with a specific app. When these events occur, Dropbox Sign sends the event to the *app callback url*. Your Dropbox Sign account can have multiple API apps that each have their own app callback url. When an event is triggered by an API request that includes a `client_id`, the event payload is sent to that specific app's callback url.
You can change an app callback url through the Dropbox Sign website or Dropbox Sign API. There are examples of both in the [Set App Callback Url](#set-account-callback-url) section of this walkthrough.

## Setting Up Dropbox Sign Events

Enabling Dropbox Sign Events (webhooks) requires two distinct steps:

1. Setting the callback url at the account or app level, which are both covered in the sections directly below.
2. Responding to the event to verify it was received.

#### Warning

In order to help protect sensitive data passed through your callback events, we will require callback URLs to use <b>HTTPS</b> starting <b>November 30, 2024</b>. Please use the sections below to update your account and app callback URLs. <b>Any callback URL not using HTTPS on December 1, 2024, will stop receiving Sign callback events.</b>

### Set Account Callback Url

* You can change your account callback url with the Dropbox Sign API by sending a PUT request to [/account](/api/account/update) and passing a `callback_url`.

  ```bash
    curl -X POST 'https://api.hellosign.com/v3/account' \
      -u 'YOUR_API_KEY:' \
      -F 'callback_url=https://example.com/hs-account-events'
  ```

* Alternatively, your account callback url can be changed from your [API settings](https://app.hellosign.com/home/myAccount?current_tab=integrations#api) page.

  <img src="https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/dropbox123432.docs.buildwithfern.com/2ab04a92c64cb6e8d163479e6847b68f7baa47faf97880447c1b6a28bd6a7f33/docs/events/account-callback-url-settings.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260814%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260814T213744Z&X-Amz-Expires=604800&X-Amz-Signature=6f897cadaa6d16886244def00e6e7326525c77a1968d3ca64750507da18e629e&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" alt="Screenshot of account callback url in Dropbox Sign account settings page" />

### Set App Callback Url

* Your app callback url can be changed by sending a `callback_url` parameter in a PUT request to [/api\_app/\{client\_id}](/api/api-app/update).

  ```bash
    curl -X POST 'https://api.hellosign.com/v3/api_app/0dd3b823a682527788c4e40cb7b6f7e9' \
      -u 'YOUR_API_KEY:' \
      -F 'name=Your Awesome App' \
      -F 'callback_url=https://example.com/hs-app-events'
  ```

* In the Dropbox Sign web app, you can change your app callback url from the API app's setting page, which you can navigate to from the [API settings](https://app.hellosign.com/home/myAccount?current_tab=integrations#api) page.

  <img src="https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/dropbox123432.docs.buildwithfern.com/29fc9bc73c8987387c1e9ee6eda0f652678cf3479effe648362079b6e57a427d/docs/events/app-callback-url-settings.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260814%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260814T213744Z&X-Amz-Expires=604800&X-Amz-Signature=1bc2fe4c60a4e8d7513a4cfd6a4451429ef1889efb84179bcab482b4b5983fbd&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" alt="Screenshot of app callback url in api app settings page" />

### Responding to Events

Dropbox Sign sends events to a callback url and expects a specific response in order to verify that events are being sent to a live server. Once an event is sent, the callback url must return an HTTP `200` with a response body that contains the string `Hello API Event Received`. If no response is received, Dropbox Sign considers that a failed callback and the event will be sent again later.

#### Failed Callbacks

Too many consecutive failed callbacks will result in Dropbox Sign deactivating webhooks for a callback url. Once deactivated, Dropbox Sign will stop sending events until a new callback url is added. Read more about this behavior in the <a href="#failures-and-retries">Failures and Retries</a> section.

Here's a basic example in Nodejs:

```javascript
// This sample is stripped down
// Use for reference only
const express = require('express');
const app = express();

app.post('/hs-events', (req, res) => {
    res.set('content-Type', 'text/plain');
    res.status(200).send('Hello API Event Received');
});
```

### Testing your Callback Url

When setting the callback url for your app or account in the Dropbox Sign web UI, you can trigger a test event by clicking the **test** button next to the field. This is a great way to verify that your webhook handler is responding to events successfully.

<b>
  Successful response
</b>

<img src="https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/dropbox123432.docs.buildwithfern.com/bab3a41f6e6d57f7400e8c3e2cdb165f523229a27041098ea294d26399e20bbc/docs/events/success-callback-test.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260814%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260814T213744Z&X-Amz-Expires=604800&X-Amz-Signature=8615c719cc9a50c1b3f650f68ed31f171ec303b3f4702752f3e11094c90ae6bc&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" alt="Screenshot of OAuth billing and scopes being selected" />

<b>
  Failed response
</b>

<img src="https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/dropbox123432.docs.buildwithfern.com/19cea1fb2abd16a415071330d8eeb9ccff1adec2b8c94736522e25879b4d0483/docs/events/fail-callback-test.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260814%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260814T213744Z&X-Amz-Expires=604800&X-Amz-Signature=dab8e655d8dbf7af9bbe5ef5af01d3b10aeac39e6bc40ba6abd28dd298990fb1&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" alt="Screenshot of OAuth billing and scopes being selected" />

## Callback Request Format

Once you've setup a callback url, Dropbox Sign sends event data to that URL in the form of POST requests. This section contains information about how those requests are formatted so you can better understand how to interact with the event data.

### Content Type

By default, the POST requests are sent as `multipart/form-data` with the event details in a field named `json`.

All of our current SDKs include an [Event Callback Helper](#sdk-event-callback-helper) to facilitate parsing event data.

### Event Payload

Event payloads always include an `event` field, which contains basic information about the event that occurred (such as time and type). Event payloads may include an `account`, `signature_request`, or `template` depending on what event took place.

Here's an example of an event payload for a `signature_request_sent` event:

```json
null
```

### Event Type

Every event payload contains an `event_type` parameter that provides the name of the specific event that occurred:

```json
{
    "event": {
        "event_time": "1348177752",
        "event_type": "signature_request_sent",
        "event_hash": "3a31324d1919d7cdc849ff407adf38fc01e01107d9400b028ff8c892469ca947",
        "event_metadata": {
            "related_signature_id": "ad4d8a769b555fa5ef38691465d426682bf2c992",
            "reported_for_account_id": "63522885f9261e2b04eea043933ee7313eb674fd",
            "reported_for_app_id": null
        }
    },
    "signature_request": {
        ...
    }
}
```

Generally speaking, checking the `event_type` is the best approach to filtering for specific events and automating your integration with the Dropbox Sign API. For example, `signature_request_all_signed` indicates that all required signers have finished. If you plan to download the final files, wait for `signature_request_downloadable`, because final document generation can take additional time after signing completes. See the [event timing glossary](/api/manual-reference-pages/glossary/callbacks-events#event-types) for details.

```javascript
if (event.event_type === "signature_request_downloadable") {
  // download completed signature request
}
```

You can see a complete list of possible events in the [Event Names](/docs/guides/events-and-callbacks/overview#event-names) section of the overview page. This list will be updated as new events are added.

## Securing your Callback Handler

Make sure that webhook events are originating from Dropbox Sign by using the following recommended methods.

### IP Address Whitelisting

We have made a JSON file containing the full list of IP addresses that webhook events may come from available for [download](https://dropbox-sign-api-config.s3.amazonaws.com/ip-ranges.json).

**Note:** This list will be automatically updated if the IP addresses change. We recommend checking this list periodically to ensure your callback handler is secure.

### HTTP Headers

We provide a couple of headers on callback requests to help you identify them.

| Name           | Description                                                                                                                                                                      | Value                                                                                                                             |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| User-Agent     | A token identifying us                                                                                                                                                           | Dropbox Sign API                                                                                                                  |
| Content-Sha256 | A base64 encoded SHA256 signature of the request's JSON payload, generated using your API key. <br /><br /> <code>echo -n $json &#124; openssl dgst -sha256 -hmac $apiKey</code> | Example value: <br /><br /> <code>Y2Y2MzVhOTdiZDVhZmVhNWRiYWJmMmRiZGRhOGQzYWE3OGU1NWIxNDkzMzgzNzdjMWI5M2Y1OGEzYzEyNzZjMg==</code> |

### Event Hash Verification

Every event payload contains an `event_hash` that can be used to verify the event is coming from Dropbox Sign. By generating your own hash and comparing that against the one sent with the Dropbox Sign event, you can ensure you're only processing events that you know were sent by Dropbox Sign.

<br />

<br />

The mechanism being used here is called [HMAC](https://www.okta.com/identity-101/hmac/), which stands for "hash-based message authentication code". To generate your own hash, you'll need to use your API key (on your [API settings](https://app.hellosign.com/home/myAccount/current_tab/api) page) as well as the `event_type` and `event_time` from the event payload:

```curl
echo -n $event_time$event_type | openssl dgst -sha256 -hmac $apikey
```

#### SDK Event Callback Helper

Our current SDKs have helper methods which can help verify callbacks came from Dropbox Sign.

Below are examples on how to implement these for each of our official SDKs:

```php
<?php

require_once __DIR__ . "/vendor/autoload.php";

// use your API key
$api_key = "YOUR_API_KEY";

// $callback_data represents data we send to you
$callback_data = json_decode($_POST["json"] ?? [], true);

$callback_event = Dropbox\Sign\Model\EventCallbackRequest::init($callback_data);

// verify that a callback came from HelloSign.com
if (Dropbox\Sign\EventCallbackHelper::isValid($api_key, $callback_event)) {
    // one of "account_callback" or "api_app_callback"
    $callback_type = Dropbox\Sign\EventCallbackHelper::getCallbackType($callback_event);

    // do your magic below!
}
```

```java
import com.dropbox.sign.EventCallbackHelper;
import com.dropbox.sign.model.EventCallbackRequest;

public class Example {
    public static void main(String[] args) throws Exception {
        // use your API key
        var apiKey = "YOUR_API_KEY";

        // callbackData represents data we send to you
        var callbackData  = request.getParameter("json");

        var callbackEvent = EventCallbackRequest.init(callbackData);

        // verify that a callback came from HelloSign.com
        if (EventCallbackHelper.isValid(apiKey, callbackEvent)) {
            // one of "account_callback" or "api_app_callback"
            var callbackType = EventCallbackHelper.getCallbackType(callbackEvent);

            // do your magic below!
        }
    }
}
```

```python

from dropbox_sign import EventCallbackHelper
from dropbox_sign.models import EventCallbackRequest

import json

# use your API key
api_key = "YOUR_API_KEY"

# callback_data represents data we send to you
callback_data = json.loads(request.POST.get('json', ''))

callback_event = EventCallbackRequest.init(callback_data)

# verify that a callback came from HelloSign.com
if EventCallbackHelper.is_valid(api_key, callback_event):
    # one of "account_callback" or "api_app_callback"
    callback_type = EventCallbackHelper.get_callback_type(callback_event)

    # do your magic below!

```

```ruby
require "dropbox-sign"

# use your API key
api_key = "YOUR_API_KEY"

# callback_data represents data we send to you
callback_data = JSON.parse(req.POST.json, :symbolize_names => true)

callback_event = Dropbox::Sign::EventCallbackRequest.init(callback_data)

# verify that a callback came from HelloSign.com
if Dropbox::Sign::EventCallbackHelper.is_valid(api_key, callback_event)
  # one of "account_callback" or "api_app_callback"
  callback_type = Dropbox::Sign::EventCallbackHelper.get_callback_type(callback_event)

  # do your magic below!
end
```

```javascript
import { EventCallbackRequest, EventCallbackHelper } from "@dropbox/sign";

// use your API key
const api_key = 'YOUR_API_KEY';

// callback_data represents data we send to you
const callback_data = JSON.parse(req.body.json);

const callback_event = EventCallbackRequest.init(callback_data);

// verify that a callback came from HelloSign.com
if (EventCallbackHelper.isValid(api_key, callback_event)) {
  // one of "account_callback" or "api_app_callback"
  const callback_type = EventCallbackHelper.getCallbackType(callback_event);

  // do your magic below!
}
```

```csharp Dotnet

using Newtonsoft.Json;
using Dropbox.Sign.Model;
using Dropbox.Sign;

public class Example
{
    public static void Main()
    {
        // use your API key
        var apiKey = "YOUR_API_KEY";

        // callbackData represents data we send to you
        var callbackData = Request.Form["json"];;

        var callbackEvent = EventCallbackRequest.Init(callbackData);

        // verify that a callback came from HelloSign.com
        if (EventCallbackHelper.IsValid(apiKey, callbackEvent))
        {
            // one of "account_callback" or "api_app_callback"
            var callbackType = EventCallbackHelper.GetCallbackType(callbackEvent);

            // do your magic below!
        }
    }
}

```

## Failures and Retries

If your callback url is not reachable or returns a non-successful response, we will retry POSTing the event up to **6 times**, with each retry interval being longer than the previous one. If the **sixth retry** fails, you will begin receiving notifications by email.

After **10 consecutive failures**, your callback URL will be automatically cleared.

Please note that our requests will timeout after **30 seconds**, so callbacks will fail if your server takes longer than that to respond. The retry pattern is described below.

| Retry  | Delay After Previous Attempt |
| ------ | ---------------------------- |
| First  | 5 minutes                    |
| Second | 15 minutes                   |
| Third  | 45 minutes                   |
| Fourth | 2 hours 15 minutes           |
| Fifth  | 6 hours 45 minutes           |
| Sixth  | 20 hours 15 minutes          |

The above retry pattern may not always be exact, but it is a good approximation of the retry pattern we use.

## Resources

* [https://sign.dropbox.com/blog/using-hellosign-api-callbacks](https://sign.dropbox.com/blog/using-hellosign-api-callbacks)