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 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 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 section of this walkthrough.
App Callbacks
App Callbacks 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 aclient_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 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 with to verify it was received.
Set Account Callback Url
- Using Dropbox Sign API to set account callback url
callback_url
. curl -X POST 'https://api.hellosign.com/v3/account' \
-u '5b2a72b84c3037711d0578e9f93589a38661f093aa4ea48bd8324c16203364eb:' \
-F 'callback_url=http://example.com/hs-account-events
-X POST
- Using Dropbox Sign Web UI to set account callback url

Set App Callback Url
- Configuring app callback url with the Dropbox Sign API
callback_url
parameter in a PUT request to /api_app/{client_id}. curl -X POST 'https://api.hellosign.com/v3/api_app/0dd3b823a682527788c4e40cb7b6f7e9' \
-u '5b2a72b84c3037711d0578e9f93589a38661f093aa4ea48bd8324c16203364eb:' \
-F 'name=Your Awesome App' \
-F 'callback_url=http://example.com/hs-app-events' \
- Configuring app callback url with the Dropbox Sign Web UI

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 HTTP200
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 Failures and Retries section.
Here's a basic example in Nodejs:
// 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.


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 asmultipart/form-data
with the event details in a field named json
.The Java SDK includes an event parsing class, and you can access this field in the $_POST array on PHP. For other platforms, either a library function, such as cgi.parse_multipart (for python) or ActionDispatch::Http::UploadedFile for Rails, or third party options, such as multer for node, may be useful.
SDK helper methods
The new Dropbox Sign SDKs all contain an event callback helper to make it easier to parse event data. This section will be updated when those are released.
Event Payload
Event payloads always include anevent
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:{- "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": {
- "signature_request_id": "fa5c8a0b0f492d768749333ad6fcc214c111e967",
- "title": "Purchase Agreement",
- "original_title": "Purchase Agreement",
- "subject": "Purchase Agreement we talked about",
- "message": "Please sign and return.",
- "metadata": { },
- "created_at": 1570471067,
- "is_complete": false,
- "is_declined": false,
- "has_error": false,
- "custom_fields": [ ],
- "response_data": [ ],
- "signing_url": null,
- "signing_redirect_url": null,
- "requester_email_address": "me@dropboxsign.com",
- "signatures": [
- {
- "signature_id": "78caf2a1d01cd39cea2bc1cbb340dac3",
- "signer_email_address": "john@example.com",
- "signer_name": "John Doe",
- "signer_role": null,
- "order": null,
- "status_code": "signed",
- "signed_at": 1346521550,
- "last_viewed_at": 1346521483,
- "last_reminded_at": null,
- "has_pin": false,
- "has_sms_auth": false
}
], - "cc_email_addresses": [ ],
- "template_ids": null,
- "client_id": null
}
}
Event Type
Every event payload contains anevent_type
parameter that provides the name of the specific event that occurred:{
"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": {
...
}
}
event_type
is the best approach to filtering for specific events and automating your integration with the Dropbox Sign API. For example, we recommend using signature_request_all_signed
as the best indicator that a signature request has been fully completed and can be downloaded using /signature_request/file:if (event.event_type === "signature_request_all_signed") {
// download completed signature request
}
You can see a complete list of possible events in the Event Names section of the overview page. This list will be updated as new events are added.
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. bash base64_encode(hash_hmac('sha256', $json, $api_key)) | Example value: Y2Y2MzVhOTdiZDVhZmVhNWRiYWJmMmRiZGRhOGQzYWE3OGU1NWIxNDkzMzgzNzdjMWI5M2Y1OGEzYzEyNzZjMg= |
Event Hash Verification
Every event payload contains anevent_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.The mechanism being used here is called 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 page) as well as the event_type
and event_time
from the event payload.Calculating an event_hash
Theevent_hash
is generated using the HMAC algorithm with your API key as a key and SHA256 digest mode. Below are examples in each of our officially supported languages:echo -n "${event_time}${event_type}" | openssl dgst -sha256 -hmac "${apikey}"
hash_hmac("sha256", $event_time . $event_type, $apikey);
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(apiKey.getBytes(), "HmacSHA256");
sha256HMAC.init(secretKey);
String data = String.valueOf(event_time) + event_type;
String computedHash = bytesToHex(sha256HMAC.doFinal(data.getBytes()));
import hashlib, hmac
hmac.new(apikey, (event_time + event_type), hashlib.sha256).hexdigest()
require 'openssl'
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha256'), apikey, (event_time + event_type))
const crypto = require('crypto');
const hash = crypto.createHmac('sha256', apiKey).update(event_time + event_type).digest('hex').toString();
var client = new Client(apiKey);
// The following will throw an EventHashException if the hash is missing or invalid
var event = client.ParseEvent("Callback JSON data here");
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 exponentially longer than the previous one. If the sixth retry fails, we will clear your callback url and you must enter a new one to receive future callback events.
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, an alert email will be sent to you after POSTing has failed several times.
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 |