E-Signature Webhook Setup Guide (PandaDoc)
Same for PandaDoc.
E-Signature Webhook Setup Guide (PandaDoc)
PandaDoc webhooks
This guide covers the complete setup: creating the webhook
What You Need Before Starting
PandaDoc Account with API Access
Business or Enterprise plans include webhook
Webhook
You need a publicly accessible HTTPS endpoint that accepts POST requests. Three options:
- Zapier: No coding required. $20/month for the Starter plan gets you webhooktriggers.webhookClick to read the full definition in our AI & Automation Glossary.
- Make (formerly Integromat): Similar to Zapier. Free tier includes webhooks.webhooksClick to read the full definition in our AI & Automation Glossary.
- Custom endpoint: Your own server or serverless function (AWS Lambda, Azure Functions, Cloudflare Workers).
System to Update
Identify where signed document data should flow: Salesforce, HubSpot, Clio, practice management system, or a database. You'll need API
Step 1: Create the Webhook WebhookClick to read the full definition in our AI & Automation Glossary. in PandaDoc
- Log into PandaDoc and go to Settings > Integrations > Webhooks.WebhooksClick to read the full definition in our AI & Automation Glossary.
- Click Create Webhook.WebhookClick to read the full definition in our AI & Automation Glossary.
- Enter a name: "Client Onboarding - Document Signed".
- Paste your webhookURL. For Zapier, you'll get this in Step 2. For custom endpoints, use your server URL (must start withwebhookClick to read the full definition in our AI & Automation Glossary.
https://). - Select events to monitor:
document_state_changed: Fires when status changes (sent, viewed, completed, voided).recipient_completed: Fires when a specific recipient finishes signing.document_completed: Fires when all recipients sign.
For client onboarding, use document_completed. This ensures you only trigger downstream actions after everyone signs.
- Under Authentication, choose Shared Secret.
- Generate a random 32-character string (use a password manager or
openssl rand -hex 16). Save this - you'll use it to verify webhookauthenticity.webhookClick to read the full definition in our AI & Automation Glossary. - Paste the secret into the Shared Secret field.
- Click Save.
Do not click "Test Webhook
Step 2: Build Your Webhook WebhookClick to read the full definition in our AI & Automation Glossary. Endpoint
Option A: Zapier (No-Code)
- In Zapier, create a new Zap.
- For the trigger, search for Webhooksby Zapier and select Catch Hook.WebhooksClick to read the full definition in our AI & Automation Glossary.
- Copy the webhookURL Zapier provides.webhookClick to read the full definition in our AI & Automation Glossary.
- Return to Zapier and click Test Trigger. In PandaDoc, send a test document to yourself and complete it. Zapier should catch the payload.
- Add an action step. Search for your CRM(Salesforce, HubSpot, etc.) and select Update Record or Create Record.CRMClick to read the full definition in our AI & Automation Glossary.
- Map fields:
data.name→ Document Titledata.recipients[0].email→ Contact Emaildata.status→ Status Fielddata.id→ PandaDoc Document ID (store this for reference)
- Add a second action: Gmail or SendGrid to send a welcome email.
- Test the Zap end-to-end. Turn it on.
Zapier Limitation: You cannot verify the shared secret in Zapier's free webhook
Option B: Custom Endpoint (Node.js Example)
This example uses Express.js and runs on any Node server or AWS Lambda.
Install dependencies:
npm install express body-parser crypto
Create webhook-handler.js:
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const app = express();
app.use(bodyParser.json());
const PANDADOC_SECRET = 'your_32_char_secret_here';
const PORT = process.env.PORT || 3000;
// Verify PandaDoc signature
function verifySignature(payload, signature) {
const hash = crypto
.createHmac('sha256', PANDADOC_SECRET)
.update(JSON.stringify(payload))
.digest('hex');
return hash === signature;
}
app.post('/webhooks/pandadoc', async (req, res) => {
const signature = req.headers['x-pandadoc-signature'];
if (!signature || !verifySignature(req.body, signature)) {
console.error('Invalid signature');
return res.status(401).send('Unauthorized');
}
const event = req.body;
const eventType = event.event;
const document = event.data;
console.log(`Received event: ${eventType} for document ${document.id}`);
if (eventType === 'document_completed') {
const recipientEmail = document.recipients[0].email;
const documentName = document.name;
// Update CRM
await updateCRM(recipientEmail, {
engagement_letter_signed: true,
pandadoc_document_id: document.id,
signed_date: new Date().toISOString()
});
// Send welcome email
await sendWelcomeEmail(recipientEmail, documentName);
// Provision client portal access
await provisionPortalAccess(recipientEmail);
}
res.status(200).send('OK');
});
async function updateCRM(email, data) {
// Replace with your CRM API call
// Example: Salesforce REST API, HubSpot API, etc.
console.log(`Updating CRM for ${email}:`, data);
}
async function sendWelcomeEmail(email, documentName) {
// Replace with your email service
// Example: SendGrid, AWS SES, Postmark
console.log(`Sending welcome email to ${email}`);
}
async function provisionPortalAccess(email) {
// Replace with your portal provisioning logic
console.log(`Provisioning portal access for ${email}`);
}
app.listen(PORT, () => {
console.log(`Webhook server running on port ${PORT}`);
});
Deploy this code:
- AWS Lambda: Use the Serverless Framework or AWS SAM. Add APIGateway to expose the endpoint.APIClick to read the full definition in our AI & Automation Glossary.
- Azure Functions: Use the Azure Functions Core Tools.
- Heroku: Push to a Git repo and deploy.
- Your own server: Run with
node webhook-handler.jsbehind Nginx with SSL.
Critical: Your endpoint must use HTTPS. PandaDoc rejects HTTP URLs. Use Let's Encrypt for free SSL certificates or deploy to a platform that provides HTTPS by default.
Step 3: Configure Webhook WebhookClick to read the full definition in our AI & Automation Glossary. Security
PandaDoc includes an x-pandadoc-signature header in every webhook
Verification logic (already in the code above):
const hash = crypto
.createHmac('sha256', PANDADOC_SECRET)
.update(JSON.stringify(req.body))
.digest('hex');
return hash === signature;
If the signature doesn't match, reject the request with a 401 status. This prevents attackers from sending fake webhook
Additional security measures:
- Whitelist PandaDoc's IP addresses in your firewall (contact PandaDoc support for the current list).
- Rate-limit the endpoint to 100 requests per minute.
- Log all webhookattempts (successful and failed) for audit purposes.webhookClick to read the full definition in our AI & Automation Glossary.
Step 4: Handle Webhook WebhookClick to read the full definition in our AI & Automation Glossary. Payload
PandaDoc sends a JSON payload. Here's a sample document_completed event:
{
"event": "document_completed",
"data": {
"id": "AbCdEfGh123456",
"name": "Engagement Letter - Smith & Associates",
"status": "document.completed",
"date_created": "2025-01-15T10:30:00Z",
"date_completed": "2025-01-15T14:22:00Z",
"recipients": [
{
"email": "john.smith@smithassociates.com",
"first_name": "John",
"last_name": "Smith",
"has_completed": true
}
],
"metadata": {
"client_id": "12345",
"matter_type": "Tax Preparation"
}
}
}
Key fields to extract:
data.id: PandaDoc document ID (store this in your CRMfor reference).CRMClick to read the full definition in our AI & Automation Glossary.data.name: Document title.data.recipients[0].email: Signer's email (use this to look up the contact in your CRM).CRMClick to read the full definition in our AI & Automation Glossary.data.metadata: Custom fields you added when creating the document. Use these to pass client ID, matter type, or other identifiers.
Handling multiple recipients:
If your engagement letter requires two signatures (e.g., managing partner and client), loop through data.recipients and check has_completed for each. Only proceed when all recipients have has_completed: true.
Step 5: Test the Integration
Test 1: Send a Test Webhook
- In PandaDoc, go to Settings > Integrations > Webhooks.WebhooksClick to read the full definition in our AI & Automation Glossary.
- Click the three dots next to your webhookand select Send Test Event.webhookClick to read the full definition in our AI & Automation Glossary.
- Choose
document_completed. - Check your endpoint logs. You should see the test payload arrive.
Test 2: Complete a Real Document
- Create a new document in PandaDoc using a test template.
- Send it to your own email address.
- Open the email and sign the document.
- Within 30 seconds, check your endpoint logs. You should see the
document_completedevent. - Verify that your CRMupdated correctly and the welcome email sent.CRMClick to read the full definition in our AI & Automation Glossary.
Test 3: Simulate a Signature Mismatch
- Modify your endpoint code to use a wrong secret.
- Send another test webhookfrom PandaDoc.webhookClick to read the full definition in our AI & Automation Glossary.
- Confirm your endpoint rejects it with a 401 status.
- Restore the correct secret.
Test 4: Check PandaDoc's Webhook
- In PandaDoc, go to Settings > Integrations > Webhooks.WebhooksClick to read the full definition in our AI & Automation Glossary.
- Click your webhookname.webhookClick to read the full definition in our AI & Automation Glossary.
- View the Recent Deliveries tab.
- Confirm all deliveries show a 200 status. If you see 4xx or 5xx errors, click the delivery to see the response body and debug.
Troubleshooting Common Issues
Webhook
Check that you selected the correct event (document_completed, not document_state_changed). Verify your PandaDoc plan includes webhooks
401 Unauthorized errors:
Your signature verification is failing. Print the expected hash and the received signature to compare. Ensure you're hashing the raw request body, not a parsed object.
Duplicate events:
PandaDoc may retry webhooks
Webhook
PandaDoc typically delivers webhooks
Next Steps
Once your webhook
- Add a
document_viewedevent to log when clients open the engagement letter (useful for follow-up). - Store the signed PDF in your document management system (use PandaDoc's APIto download the file).APIClick to read the full definition in our AI & Automation Glossary.
- Trigger a Slack notification to the engagement team when a high-value client signs.
- Create a dashboard that shows signing velocity (time from send to completion).
PandaDoc webhooks

Reviewed by Revenue Institute
This guide is actively maintained and reviewed by the implementation experts at Revenue Institute. As the creators of The AI Workforce Playbook, we test and deploy these exact frameworks for professional services firms scaling without new headcount.
Revenue Institute
Need help turning this guide into reality? Revenue Institute builds and implements the AI workforce for professional services firms.