BoloSign Webhooks API Documentation
Overview
BoloSign provides a webhook API that allows you to receive real-time notifications when specific events occur within the BoloSign system. With webhooks, you can automate actions like form submission handling, signature tracking, and template responses by receiving data sent directly to your webhook URL when these events happen.
How It Works:
-
Add a Webhook URL: You need to provide a URL where BoloSign will send webhook events. This is the endpoint that listens for incoming webhook data.
-
Choose the Event Type: Select the event type for which you want to receive notifications. BoloSign supports the following events:
- Form Response
- Signature Completed
- Template Response
-
Select Documents: You can select a specific form, PDF, or template for which you want to track events. Multiple documents can be selected if needed.
-
Receive Webhook Notifications: When the chosen event occurs, BoloSign will send an HTTP POST request to the webhook URL you provided with the event details in JSON format.
Testing Each Webhook Event
After adding a webhook for any event, you can test whether your webhook URL is working. To do this, BoloSign will send sample data to your URL. When you click on “Test Webhook,” a modal will appear with the sample data that was sent to your URL, confirming the successful transmission of data.
The Data Format:
While testing, you will receive the data as an array of objects, where each element of the array represents sample data for each document you have selected for that particular webhook and event.
For example, if you have chosen two forms (e.g., 'Test' and 'Zapier') for the "New Form Response" event, you will receive two objects inside the array, where each object represents each form’s sample data. This mirrors the actual data that will be sent when the event triggers in real scenarios.
You should keep this in mind when testing your URL. It might be helpful to test your API (webhook URL) with one element at a time from the test response data.
Event Types and Webhook Payloads
1. Form Response
Event Description: This event is triggered when a user completes and submits a form. You will receive a payload with details about the form response, including the form fields and responses provided by the user.
Webhook Payload Structure:
{
"webhookEvent": "new_form_response",
"formId": "5a5b7b2b-8932-4cf7-a854-89e52e2552e1",
"formResponseId": "3e7d9b4a-08c5-4f7e-b5e6-23a1b5190e68",
"formTitle": "User Feedback Form",
"finishedPdfUrl": "https://example.com/pdf/formresponse.pdf",
"respondentEmail": "[email protected]",
"response": [
{
"id": "field1",
"question": "What is your name?",
"answer": "John Doe"
},
{
"id": "field2",
"question": "How would you rate our service?",
"answer": "Excellent"
}
]
}
2. Individual Document Viewed
Event Description: This event is triggered when an individual signer views a signature PDF document.
Webhook Payload Structure:
{
"webhookEvent": "new_signature_pdf_individual_viewed",
"documentName": "contract.pdf",
"documentId": "256ad6c8-2fd1-4b1f-ad88-140e617ed450",
"documentUrl": "https://example.com/documents/contract.pdf",
"authorEmail": "[email protected]",
"signers": [
{
"email": "[email protected]",
"name": "Jane Doe",
"status": "VIEWED",
"signerIp": "192.168.1.1",
"hasDeclined": false
}
],
"viewedBy": {
"email": "[email protected]",
"name": "Jane Doe",
"status": "VIEWED",
"signerIp": "192.168.1.1",
"hasDeclined": false,
"viewedAt": "2024-12-17T10:30:00.000Z"
}
}
3. Individual Document Signed
Event Description: This event is triggered when an individual signer completes their signature on a PDF document.
Webhook Payload Structure:
{
"webhookEvent": "new_signature_pdf_individual_signed",
"documentName": "contract.pdf",
"documentId": "256ad6c8-2fd1-4b1f-ad88-140e617ed450",
"documentUrl": "https://example.com/documents/contract.pdf",
"authorEmail": "[email protected]",
"isSigningOrder": true,
"signers": [
{
"email": "[email protected]",
"name": "Jane Doe",
"status": "SIGNED",
"signerIp": "192.168.1.1",
"hasDeclined": false,
"signingOrderNo": 1
}
],
"signedBy": {
"email": "[email protected]",
"name": "Jane Doe",
"status": "SIGNED",
"signerIp": "192.168.1.1",
"hasDeclined": false,
"signingOrderNo": 1,
"signedAt": "2024-12-17T10:30:00.000Z"
}
}
4. Signature Completed
Event Description: This event is triggered when a signer completes and submits a signature on a document. You will receive a payload with information about the document, the signer, and the signature status.
Webhook Payload Structure:
{
"webhookEvent": "new_signature_pdf_completed",
"documentName": "agreement.pdf",
"documentId": "f32c9f9e-12a8-4a09-91d8-ea1325830d25",
"documentUrl": "https://example.com/documents/agreement.pdf",
"authorEmail": "[email protected]",
"finishedPdfUrl": "https://example.com/finished/agreement.pdf",
"signers": [
{
"email": "[email protected]",
"name": "John Doe",
"status": "SIGNED",
"signerIp": "192.168.1.1",
"hasDeclined": false
}
]
}
5. Individual Template Viewed
Event Description: This event is triggered when an individual signer views a template-based document.
Webhook Payload Structure:
{
"webhookEvent": "new_template_response_individual_viewed",
"documentName": "template.pdf",
"documentId": "256ad6c8-2fd1-4b1f-ad88-140e617ed450",
"documentUrl": "https://example.com/documents/template.pdf",
"authorEmail": "[email protected]",
"signers": [
{
"roleTitle": "Manager",
"email": "[email protected]",
"name": "John Manager",
"status": "VIEWED",
"signerId": "1234abcd-5678-efgh-9101-ijklmnopq234",
"hasDeclined": false
}
],
"viewedBy": {
"roleTitle": "Manager",
"email": "[email protected]",
"name": "John Manager",
"status": "VIEWED",
"signerId": "1234abcd-5678-efgh-9101-ijklmnopq234",
"hasDeclined": false,
"viewedAt": "2024-12-17T10:30:00.000Z"
}
}
6. Individual Template Signed
Event Description: This event is triggered when an individual signer completes their signature on a template-based document.
Webhook Payload Structure:
{
"webhookEvent": "new_template_response_individual_signed",
"documentName": "template.pdf",
"documentId": "256ad6c8-2fd1-4b1f-ad88-140e617ed450",
"documentUrl": "https://example.com/documents/template.pdf",
"authorEmail": "[email protected]",
"isSigningOrder": true,
"signers": [
{
"roleTitle": "Manager",
"email": "[email protected]",
"name": "John Manager",
"status": "SIGNED",
"signerId": "1234abcd-5678-efgh-9101-ijklmnopq234",
"hasDeclined": false,
"signingOrderNo": 1
}
],
"signedBy": {
"roleTitle": "Manager",
"email": "[email protected]",
"name": "John Manager",
"status": "SIGNED",
"signerId": "1234abcd-5678-efgh-9101-ijklmnopq234",
"hasDeclined": false,
"signingOrderNo": 1,
"signedAt": "2024-12-17T10:30:00.000Z"
}
}
7. Template Response
Event Description: This event is triggered when a response is received for a template-based document (like a contract or agreement). You will receive a payload with details about the document, its ID, and the signers involved.
Webhook Payload Structure:
{
"webhookEvent": "new_template_response",
"documentName": "contract.pdf",
"documentId": "256ad6c8-2fd1-4b1f-ad88-140e617ed450",
"documentUrl": "https://example.com/documents/contract.pdf",
"authorEmail": "[email protected]",
"finishedPdfUrl": "https://example.com/finished/contract.pdf",
"signers": [
{
"roleTitle": "Manager",
"email": "[email protected]",
"name": "Jane Doe",
"status": "PENDING",
"signerId": "1234abcd-5678-efgh-9101-ijklmnopq234",
"hasDeclined": false
}
],
"contact_field(page1)[Manager]": "Contact Info"
}
Handling Webhook Requests
When BoloSign sends an event notification, it makes an HTTP POST request to your webhook URL. You will need to configure your server to listen for incoming webhook events and handle the data appropriately.
Example Request:
POST /webhook HTTP/1.1
Host: your-server.com
Content-Type: application/json
[
{
"documentName": "agreement.pdf",
"documentId": "f32c9f9e-12a8-4a09-91d8-ea1325830d25",
"documentUrl": "https://example.com/documents/agreement.pdf",
"authorEmail": "[email protected]",
"finishedPdfUrl": "https://example.com/finished/agreement.pdf",
"signers": [
{
"email": "[email protected]",
"name": "John Doe",
"status": "SIGNED",
"signerIp": "192.168.1.1",
"hasDeclined": false
}
]
}
]
Example Response (from your server):
Your server should respond with a 200 OK
status when the webhook is received successfully.
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "Webhook received successfully"
}
Webhook Event Validation
To ensure that the data received is from BoloSign, you should validate the webhook signature using HMAC authentication. Here's how you can do that:
Signature Verification:
BoloSign sends a custom x-signature
header along with the webhook request, which contains the HMAC SHA-256 signature of the payload. You need to verify this signature by recreating the signature on your server using the payload, timestamp, and the secret key provided by BoloSign.
Steps for Verifying Webhook Signature:
- Extract the Webhook Data: Extract the
payload
,timestamp
, andx-signature
from the incoming request. - Recreate the HMAC Signature: Using the payload and the timestamp, recreate the signature on your server using your secret key.
- Compare the Signatures: Compare the recreated signature with the
x-signature
in the request header. If they match, the request is valid; if they don't, the request is invalid.
Example of Verifying the Webhook Signature:
const crypto = require("crypto");
function verifyWebhookSignature(payload, timestamp, receivedSignature, secret) {
const recreatedSignature = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${JSON.stringify(payload)}`)
.digest("hex");
return recreatedSignature === receivedSignature;
}
// Controller function
const webhookController = (req, res) => {
const payload = req.body; // Extract the payload from the request
const timestamp = req.headers["x-timestamp"]; // Get the timestamp from headers
const receivedSignature = req.headers["x-signature"]; // Get the signature from headers
const secret = "customer-specific-secret"; // Replace with the actual secret for verification
const isValid = verifyWebhookSignature(payload, timestamp, receivedSignature, secret);
if (isValid) {
console.log("Webhook request is verified and authentic.");
} else {
console.log("Invalid signature. Webhook request not authentic.");
}
res.status(isValid ? 200 : 401).send(isValid ? "Verified" : "Unauthorized");
};
module.exports = webhookController;
Best Practices:
- Security: Ensure your webhook URL is secured using HTTPS to prevent unauthorized access.
- HMAC Authentication: Always verify the authenticity of the request using the HMAC signature before processing the data.
- Error Handling: If the signature verification fails, respond with an HTTP 401 status code to indicate that the request is unauthorized.