Skip to main content

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 signers
  • bundle_complete - All signers have completed the bundle
  • bundle_docs_ready - Documents are ready for download
  • bundle_error - An error occurred with the bundle
  • bundle_cancelled - Bundle was cancelled
  • packet_viewed - A signer has viewed their packet
  • packet_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 of payload vary depending on the event_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 request
  • x-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)