Webhooks
Webhooks allow Blueink to notify your application when specific events occur, such as a signer viewing a packet, completing a signing session, or a packet being sent. Rather than polling our API for updates, webhooks allow your system to respond in real-time to events as they happen.
You can configure webhook endpoints and view your secret key (which can be used for verifying the webhook) in the Blueink dashboard in the API Section.
You can also configure webhooks via the Blueink API. See the API Documentation for details.
We suggest using HTTPS URLs for your webhook endpoints, but HTTP URLs are also supported.
Webhook Event Types
Blueink supports the following event types for webhooks:
bundle_sent
- Bundle has been sent to signersbundle_complete
- All signers have completed the bundlebundle_docs_ready
- Documents are ready for downloadbundle_error
- An error occurred with the bundlebundle_cancelled
- Bundle was cancelledpacket_viewed
- A signer has viewed their packetpacket_complete
- A signer has completed their packet
Receiving Webhooks
Upon receiving a Webhook HTTP Request from Blueink, your Webhook receiver should return an HTTP Response with a status of 200, 201, 202 or 204 to indicate successful receipt of the webhook. If any other status code is returned, or if no response is received within 10 seconds, the HTTP Request is deemed to have failed.
After an initial failed request, Blueink will retry the request with exponential backoff, on the following schedule:
- 4 minutes
- 12 minutes
- 36 minutes
- 108 minutes
- 324 minutes
If any of the retry attempts results in a status of 200, 201, 202 or 204, the webhook event is deemed to have been successfully delivered, and no additional delivery attempts are made.
You can view error codes for failed webhook deliveries in the Blueink dashboard in the API Section.
If all webhook delivery attempts fail for enough consecutive events for a particular webhook, Blueink will
disable the webhookand the Webhook status will be set to DISABLED_DUE_TO_FAILED_DELIVERIES
(or df
).
Admins on the accountare notified via email when a Webhook is disabled due to failed deliveries.
The webhook can be re-enabled by an admin in the Blueink dashboard. The Webhook can also be re-enabled
via updating the status
can also be set updated
via the API witha PUT request to /webhooks/[webhookId]/
to re-enable the Webhook
Payload structure
Each Blueink event will have the following fields:
event_id
: A unique UUID identifying the webhook event.event_type
: The type of event that occurred (e.g.,bundle_sent
,bundle_complete
,packet_viewed
).event_date
: The ISO 8601 timestamp indicating when the event occurred in Blueink.account_id
: The UUID of the Blueink account associated with the event.payload
: An object containing additional metadata related to the event. The contents ofpayload
vary depending on theevent_type
.
// Example packet_viewed
{
"event_id": "c163d38f-e7ff-4e1b-b7dc-1fc027bf35ae",
"event_type": "packet_viewed",
"event_date": "2025-04-07 15:43:08.646752+00:00",
"account_id": "1b837b55-b16a-4d34-b422-f43a67d886d7",
"payload": {
"bundle_id": "HMXKQ0jhdJ",
"packet_id": "dtipO7RrCw"
}
}
// Example bundle_complete
{
"event_id": "f413734e-e832-49f2-a09e-a89c5cf4aa39",
"event_type": "bundle_complete",
"event_date": "2025-04-04 00:31:28.824236+00:00",
"account_id": "1b837b55-b16a-4d34-b422-f43a67d886d7",
"payload": {
"bundle_id": "plHoBZRHwM"
}
}
Verifying Webhooks
To ensure that webhook requests come from Blueink and haven't been tampered with, you should verify the webhook signature on every request. Blueink includes the following headers in each webhook request:
x-blueink-signature
: The HMAC SHA-256 signature of the requestx-blueink-request-timestamp
: The UNIX timestamp when the request was sent
In addition, you can configure a Webhook to include additional headers, e.g. to bypass firewall rules or for custom verification.
Here’s an example of how to verify the webhook in Python:
import hmac
import hashlib
WEBHOOK_SIGNATURE_VERSION = "v0"
WEBHOOK_SIGNATURE_ENCODING = "utf-8"
def verify_webhook_signature(body, secret, timestamp, webhook_signature, version="v0"):
"""
Computes the HMAC SHA-256 signature for verifying the authenticity of a webhook request.
Parameters:
- body (str): The JSON-encoded request body.
- secret (str): The webhook secret (found on the API screen).
- timestamp (str): The timestamp of the request (from the `x-blueink-request-timestamp` header).
- version (str, optional): The version of the signature format. Defaults to "v0".
"""
msg = f"{version}:{timestamp}:{body}"
signature = (
f"{WEBHOOK_SIGNATURE_VERSION}="
+ hmac.new(
key=bytes(secret, WEBHOOK_SIGNATURE_ENCODING),
msg=bytes(msg, WEBHOOK_SIGNATURE_ENCODING),
digestmod=hashlib.sha256,
).hexdigest()
)
return hmac.compare_digest(signature, webhook_signature)
body = json.dumps({
"event_id": "98cc7914-85f1-4695-83db-7cb81c575b85",
"event_type": "packet_viewed",
"event_date": "2025-03-30 19:48:27.123181+00:00",
"account_id": "1b837b55-b16a-4d34-b422-f43a67d886d7",
"payload": {"bundle_id": "TYkytOOwtN", "packet_id": "RmJIHGem3k"}
})
secret = "your_webhook_secret"
timestamp = "1711822107"
valid = verify_webhook_signature(body, secret, timestamp, webhook_signature)