Cal.com Webhooks + Signbee: Auto-Send NDAs & Waivers on Booking (2026)
Nothing kills the momentum of a discovery call, M&A briefing, or clinical consultation faster than spending the first ten minutes of a video meeting chasing an unsigned NDA or intake waiver. Learn how to connect Cal.com booking webhooks directly to Signbee's REST API—and optionally hold calendar confirmation until the document is cryptographically signed.
Quick Answer (TL;DR)
Cal.com + Signbee Pre-Meeting Legal Automation • Production Reference
To automatically dispatch a Mutual NDA, client advisory agreement, or liability waiver whenever a meeting is scheduled in Cal.com, configure a Cal.com webhook listening for BOOKING_CREATED (or BOOKING_REQUESTED for gated confirmation flows). Verify the X-Cal-Signature-256 HMAC header in your Next.js endpoint, extract the attendee's identity and custom booking responses (payload.responses), render a CommonMark markdown agreement, and send a single JSON POST request to https://signb.ee/api/v1/send. When the attendee signs, Signbee fires document.signed so your server can auto-confirm the Cal.com booking via POST /v2/bookings/{uid}/confirm.
1. Why Pre-Meeting NDAs and Intake Waivers Fail When Handled Manually
Open-source scheduling infrastructure—led by Cal.com—has replaced static contact forms across M&A advisory firms, venture capital deal-flow portals, boutique law practices, user-research labs, and private healthcare clinics. Prospects pick an available 30-minute slot, answer two custom intake questions, and receive a calendar invite in seconds.
Yet in regulated or confidential workflows, booking the time slot is only half of the intake transaction. Before the meeting actually begins, the host requires a legally binding signature on a pre-meeting document:
- M&A Advisors, Private Equity & Venture Studios: Before sharing a Confidential Information Memorandum (CIM), proprietary deal metrics, or unannounced product roadmaps on a Zoom call, both parties must execute a Mutual Non-Disclosure Agreement (MNDA).
- Telehealth, Aesthetics & Private Clinics: Before a practitioner conducts a consultation or procedure, the patient must sign an Informed Consent & HIPAA/GDPR Telehealth Privacy Waiver containing their full legal name, date of birth, and disclosed medical history.
- User Research, Podcast Studios & Field Operations: Before recording an interview or granting physical facility access, the guest must sign a Media Appearance Release or Facility Liability Waiver.
When operations teams rely on manual follow-up emails—or expensive per-envelope legacy wrappers analyzed in our DocuSign API pricing breakdown—up to 41% of attendees arrive at the scheduled call without having signed the document. Worse, if 20% of top-of-funnel bookings cancel or no-show, paying $3.50 per dispatched DocuSign envelope means burning thousands of dollars on uncompleted meetings. By choosing from the best e-signature APIs for developers in 2026, you can wire Cal.com directly to Signbee with zero per-envelope penalty.
2. Two Architectural Patterns: Instant Dispatch vs. Signature-Gated Confirmation
Depending on how strict your compliance posture is, Cal.com and Signbee support two distinct orchestration patterns:
The calendar slot is confirmed immediately when the attendee books. Simultaneously, BOOKING_CREATED triggers your webhook, which dispatches the Signbee signing link. If the document remains unsigned 2 hours before startTime, your cron job sends a reminder or cancels the slot. Ideal for sales discovery calls and podcast guest releases.
Enable Requires Confirmation on your Cal.com Event Type. Selecting a slot holds the time in a pending state and fires BOOKING_REQUESTED. Signbee immediately emails the NDA/Waiver. Only when Signbee fires document.signed does your backend call Cal.com API v2 to confirm the booking and release the video URL.
Cal.com Webhook Event Mapping for Legal & Intake Workflows
| Cal.com triggerEvent | When It Fires | Key Payload Properties | Signbee Orchestration Action |
|---|---|---|---|
| BOOKING_CREATED | Attendee schedules a standard auto-confirmed event | payload.uid, attendees[0], responses | Generate CommonMark NDA/Waiver & call POST /api/v1/send |
| BOOKING_REQUESTED | Attendee requests a slot on an event requiring host confirmation | payload.uid, status: 'PENDING' | Dispatch NDA immediately; hold confirmation until document.signed |
| BOOKING_RESCHEDULED | Attendee moves meeting to a new date/time | payload.rescheduleUid, startTime | Keep signed NDA active; re-issue date-specific waiver if unsigned |
| BOOKING_CANCELLED | Attendee or host cancels the meeting | payload.uid, cancellationReason | Mark pending booking record as canceled in local DB |
3. Capturing Legal Entity & Intake Metadata in Cal.com Booking Questions
Cal.com lets you configure custom Booking Questions on any Event Type using human-readable field identifiers. For a B2B Mutual NDA, adding two required text inputs—company_legal_name and job_title—ensures that when the webhook fires, payload.responses contains the exact corporate entity name and signatory title needed to draft an enforceable contract.
Let's inspect the structure of the inbound Cal.com webhook payload and write the Next.js App Router endpoint (/api/webhooks/calcom) that verifies the X-Cal-Signature-256 header and dispatches a Mutual NDA through Signbee:
import { NextResponse } from "next/server";
import crypto from "crypto";
export async function POST(req: Request) {
const rawBody = await req.text();
const signature = req.headers.get("x-cal-signature-256") || "";
const secret = process.env.CALCOM_WEBHOOK_SECRET!;
// 1. Verify Cal.com X-Cal-Signature-256 HMAC-SHA256 signature
const expectedSig = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
const sigBuffer = Buffer.from(signature, "utf8");
const expectedBuffer = Buffer.from(expectedSig, "utf8");
if (
sigBuffer.length !== expectedBuffer.length ||
!crypto.timingSafeEqual(sigBuffer, expectedBuffer)
) {
return NextResponse.json({ error: "Invalid Cal.com signature" }, { status: 401 });
}
const body = JSON.parse(rawBody);
const { triggerEvent, payload } = body;
if (triggerEvent === "BOOKING_CREATED" || triggerEvent === "BOOKING_REQUESTED") {
const attendee = payload.attendees?.[0];
const organizer = payload.organizer;
if (!attendee?.email) {
return NextResponse.json({ error: "Missing attendee email" }, { status: 422 });
}
// 2. Extract custom Cal.com Booking Question responses
const companyLegalName =
payload.responses?.company_legal_name?.value ||
payload.responses?.company?.value ||
attendee.name;
const jobTitle =
payload.responses?.job_title?.value || "Authorized Representative";
const discussionTopic =
payload.responses?.notes?.value || payload.title || "Confidential Commercial Evaluation";
const bookingUid: string = payload.uid;
const meetingDate = new Date(payload.startTime).toUTCString();
const effectiveDate = new Date().toISOString().split("T")[0];
// 3. Synthesize Mutual Non-Disclosure Agreement in CommonMark Markdown
const ndaMarkdown = `# Mutual Non-Disclosure & Confidentiality Agreement
**Effective Date:** ${effectiveDate}
**Cal.com Booking Reference:** ${bookingUid}
**Scheduled Session:** ${meetingDate}
**Party A (Host):** Apex Ventures & Advisory LLP (${organizer?.email || "legal@apexventures.vc"})
**Party B (Participant):** ${companyLegalName}, represented by ${attendee.name}, ${jobTitle} (${attendee.email})
---
## 1. Purpose of Disclosure
In connection with the scheduled briefing on **${meetingDate}** regarding **${discussionTopic}** (the "Permitted Purpose"), each party ("Disclosing Party") may disclose certain non-public technical, financial, strategic, or commercial information ("Confidential Information") to the other party ("Receiving Party").
## 2. Summary of Key Confidentiality Terms
| Parameter | Agreed Legal Standard |
|---|---|
| Agreement Structure | Bilateral / Mutual Protection (Both Parties Protected) |
| Cal.com Session UID | ${bookingUid} |
| Protection Period | Three (3) Years from Effective Date (${effectiveDate}) |
| Standard Exclusions | Public domain, prior lawful possession, independent development |
| Governing Law | State of New York, USA |
## 3. Obligations of the Receiving Party
1. **Strict Non-Disclosure:** Receiving Party shall hold all Confidential Information in strict confidence and shall not disclose it to any third party without prior written consent.
2. **Permitted Internal Access:** Access shall be restricted solely to employees, partners, and professional advisors who have a strict need to know for the Permitted Purpose and are bound by written confidentiality obligations no less protective than this Agreement.
3. **Return or Destruction:** Upon written request by Disclosing Party, Receiving Party shall promptly destroy or return all tangible and electronic copies of Confidential Information.`;
// 4. Dispatch via Signbee REST API (Party A signed automatically via API key)
const signbeeRes = await fetch("https://signb.ee/api/v1/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SIGNBEE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
title: `Mutual NDA — ${companyLegalName} & Apex Ventures (${effectiveDate})`,
markdown: ndaMarkdown,
sender_name: organizer?.name || "Managing Partner — Apex Ventures",
sender_email: organizer?.email || "legal@apexventures.vc",
recipient_name: `${attendee.name} (${jobTitle})`,
recipient_email: attendee.email,
expires_in_days: 7,
webhook_url: `${process.env.NEXT_PUBLIC_APP_URL}/api/webhooks/signbee-calcom?booking_uid=${encodeURIComponent(bookingUid)}`,
}),
});
if (!signbeeRes.ok) {
const errText = await signbeeRes.text();
return NextResponse.json({ error: errText }, { status: 502 });
}
const signbeeData = await signbeeRes.json();
return NextResponse.json({
dispatched: true,
booking_uid: bookingUid,
signbee_document_id: signbeeData.document_id,
});
}
return NextResponse.json({ received: true });
}4. Closing the Loop: Auto-Confirming the Cal.com Meeting When document.signed Fires
Notice how in step 4 of the code block above, we appended ?booking_uid={bookingUid} to the webhook_url passed to Signbee. That single query parameter creates a stateless correlation link between the Signbee document and the pending Cal.com booking—meaning you do not even need an intermediate database table if you want a lightweight serverless deployment!
When the attendee opens their email, clicks the Signbee link, and completes the 15-second signing ceremony, Signbee sends a document.signed webhook to your callback endpoint. Your server immediately invokes Cal.com Platform API v2 (POST https://api.cal.com/v2/bookings/{bookingUid}/confirm) to confirm the slot and release the Google Meet or Zoom video room link:
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { searchParams } = new URL(req.url);
const bookingUid = searchParams.get("booking_uid");
const payload = await req.json();
if (payload.event === "document.signed" && bookingUid) {
const { document_id, sha256_hash, signed_at, recipient_email } = payload.data;
// Call Cal.com API v2 to confirm the pending booking and release video meeting URL
const calConfirmRes = await fetch(
`https://api.cal.com/v2/bookings/${bookingUid}/confirm`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.CALCOM_API_KEY}`,
"cal-api-version": "2024-08-13",
"Content-Type": "application/json",
},
body: JSON.stringify({
reason: `Mutual NDA cryptographically executed via Signbee (ID: ${document_id}, SHA-256: ${sha256_hash})`,
}),
}
);
if (!calConfirmRes.ok) {
const errText = await calConfirmRes.text();
console.error(`Failed to confirm Cal.com booking ${bookingUid}: ${errText}`);
return NextResponse.json({ error: errText }, { status: 500 });
}
console.log(
`[Cal.com + Signbee] Confirmed booking ${bookingUid} for ${recipient_email} at ${signed_at}`
);
return NextResponse.json({
confirmed: true,
booking_uid: bookingUid,
signbee_document_id: document_id,
sha256_hash,
});
}
return NextResponse.json({ received: true });
}5. Industry Adaptation: Telehealth Informed Consent & Liability Waivers
The exact same webhook pipeline adapts effortlessly to medical aesthetics clinics, physiotherapy practices, and telehealth providers using Cal.com for patient scheduling. Instead of a Mutual NDA, your handler maps patient intake responses (date_of_birth, allergies, emergency_contact) into a clinical Informed Consent & Treatment Waiver:
export function buildClinicalConsentMarkdown(params: {
patientName: string;
patientEmail: string;
dateOfBirth: string;
declaredAllergies: string;
practitionerName: string;
appointmentTime: string;
bookingUid: string;
}) {
return `# Patient Informed Consent & Telehealth Privacy Waiver
**Appointment Reference:** ${params.bookingUid}
**Scheduled Consultation:** ${params.appointmentTime}
**Attending Practitioner:** ${params.practitionerName}
## 1. Patient Intake Summary
| Field | Patient Declared Value |
|---|---|
| Full Legal Name | ${params.patientName} |
| Verified Email | ${params.patientEmail} |
| Date of Birth | ${params.dateOfBirth} |
| Disclosed Allergies / Contraindications | ${params.declaredAllergies || "None Disclosed"} |
## 2. Informed Consent for Consultation & Treatment
I, **${params.patientName}**, hereby voluntarily consent to diagnostic assessment and clinical consultation provided by **${params.practitionerName}**. I confirm that the medical history and allergy disclosures listed in Section 1 are accurate and complete to the best of my knowledge.
## 3. Electronic Signature & Cryptographic Audit Acknowlegment
By executing this document electronically via Signbee, I agree that my electronic signature carries the same legal validity and enforceability as a handwritten signature under the US ESIGN Act, UETA, and UK/EU eIDAS regulations.`;
}For clinics and advisory firms embedding Cal.com directly inside their own custom patient or client portal, combining this template with the patterns in our white-label e-signature API guide provides a cohesive, institutional experience from slot selection to signed PDF archive.
6. Unit Economics & Latency: Why High-Volume Booking Flows Break Legacy E-Sign Pricing
Scheduling workflows have a unique economic profile compared to bottom-of-funnel procurement contracts: top-of-funnel booking volume is high, and 15%–25% of scheduled calls either reschedule or no-show. If your organization processes 800 Cal.com bookings per month and triggers a legacy DocuSign or Adobe Sign envelope on every booking, you pay per-envelope fees on all 800 dispatches—even if 180 of those prospects cancel before the call.
As detailed in our 2026 e-signature API pricing comparison, affordable e-signature API integration guide, and open-source e-signature API comparison, eliminating per-envelope metering transforms pre-meeting legal automation from a costly luxury into a zero-friction default. You can even validate the entire Cal.com webhook loop today using Signbee's free e-signature API tier.
| Benchmark Metric | Cal.com + Signbee REST API | Cal.com + DocuSign API | Manual Email PDF Attachment |
|---|---|---|---|
| Dispatch Speed After Booking | < 250 ms (Instant while on booking page) | 1.8s – 3.2s (OAuth + Template merge) | 4 – 24 Hours (Human bottleneck) |
| Pre-Call Signature Completion Rate | 94.2% (100% with Pattern B Gate) | 81.5% | 58.4% |
| Custom Question Table Rendering | Native CommonMark Markdown | Fixed PDF Tabs (Truncates long answers) | Manual copy-paste into Word |
| Monthly Cost at 800 Bookings | Flat developer plan ($0 envelope tax) | $2,000 – $3,840 / mo | ~26 hours of admin labor / mo |
7. Edge Cases: Multi-Attendee Briefings, Reschedules & Pre-Call Reminders
When running this integration in production across high-stakes advisory or clinical calendars, keep these three operational refinements in mind:
- Multi-Attendee Bookings (
payload.attendeesArray): When a prospect invites two additional colleagues to a Cal.com M&A briefing,payload.attendeescontains multiple objects. For corporate MNDAs, binding the primary corporate officer covers the organization; for individual facility liability waivers or podcast guest releases, iterate overpayload.attendeesand dispatch an individual Signbee waiver to each participant's email address. - Idempotent Reschedule Handling (
BOOKING_RESCHEDULED): When an attendee moves their call from Tuesday to Thursday, Cal.com includespayload.rescheduleUidreferencing the original booking. Check your database or Signbee document status (GET https://signb.ee/api/v1/documents/{id}) first—if the Mutual NDA was already signed under the original booking UID, carry the verifiedsha256_hashforward to the new slot instead of asking the client to sign twice. - Automated 60-Minute Pre-Call Check: If you use Pattern A (non-blocking dispatch), run a lightweight scheduled check 60 minutes prior to
startTime. If the associated Signbee document status is stillpending, send the attendee an SMS or WhatsApp nudge containing their directhttps://signb.ee/sign/[token]URL so they can sign on their phone in 10 seconds before joining the video room.
Frequently Asked Questions: Cal.com Webhooks & Signbee E-Signatures
How do I automatically send an NDA or waiver when someone books a meeting on Cal.com?
In your Cal.com dashboard (or via the Cal.com Platform v2 API), configure a webhook subscriber listening for the BOOKING_CREATED trigger event. When an attendee schedules a session, Cal.com posts the booking JSON payload—including attendee name, email, startTime, uid, and custom booking responses—to your Next.js endpoint. After verifying the X-Cal-Signature-256 HMAC header, your server interpolates the meeting details into a CommonMark markdown template and calls POST https://signb.ee/api/v1/send. Signbee immediately emails the attendee a signing ceremony link and returns a document_id in under 250 milliseconds.
Can I hold or gate a Cal.com meeting confirmation until the attendee signs the NDA on Signbee?
Yes. Enable Cal.com's “Requires Confirmation” (Opt-In Booking) setting on your Event Type. When a prospect selects a slot, Cal.com fires the BOOKING_REQUESTED webhook rather than confirming the calendar invite and video conference link immediately. Your webhook handler dispatches the Mutual NDA or intake waiver via Signbee and stores the Cal.com bookingUid. The moment the attendee signs the document, Signbee fires the document.signed webhook to your server, which then calls POST https://api.cal.com/v2/bookings/{bookingUid}/confirm to release the calendar invitation and video room URL.
How do I verify the X-Cal-Signature-256 header in Next.js App Router?
When you set a Webhook Secret in Cal.com, every outbound webhook request includes an X-Cal-Signature-256 HTTP header containing the hex-encoded HMAC-SHA256 digest of the raw request body. In your Next.js route handler, read the raw body string via await req.text(), compute crypto.createHmac('sha256', process.env.CALCOM_WEBHOOK_SECRET).update(rawBody).digest('hex'), and compare the digests using crypto.timingSafeEqual to prevent timing side-channel attacks before dispatching any contract via Signbee.
What happens if a Cal.com booking is rescheduled or canceled after the NDA was sent?
For a Mutual Non-Disclosure Agreement (NDA), the confidentiality term typically spans 2 to 5 years from the Effective Date regardless of whether the specific discovery call is rescheduled, so you do not need to re-send the NDA on BOOKING_RESCHEDULED if the original document_id is already signed. However, for date-specific clinical consent forms, studio rental waivers, or field liability releases, listening to BOOKING_CANCELLED or BOOKING_RESCHEDULED allows your backend to mark the prior booking UID as superseded and issue an updated waiver tied to the new session timestamp.
Can I map custom Cal.com booking questions directly into the Signbee contract text?
Yes. Cal.com delivers all custom booking form answers inside payload.responses (for example, payload.responses.company_legal_name, payload.responses.jurisdiction, or payload.responses.date_of_birth). Because Signbee compiles standard CommonMark Markdown directly into paginated A4 PDFs, you can dynamically inject any custom intake question, medical history table, or corporate entity identifier straight into the contract clauses without maintaining fixed-coordinate PDF form fields.
Why use Signbee with Cal.com instead of legacy e-signature tools like DocuSign or HelloSign?
Cal.com is chosen by developer-first organizations, venture funds, M&A advisories, and modern telehealth platforms for its open-source extensibility and clean API design. Legacy e-signature vendors charge $2.00 to $4.80 per envelope—meaning a high-volume clinic or advisory firm pays a steep financial penalty every time a lead books a slot and later no-shows. Signbee offers flat, predictable developer pricing without per-envelope taxes, zero SDK bloat, and instant SHA-256 cryptographic certificates.
Automate Your Cal.com Pre-Meeting NDAs & Waivers Today
Wire your Cal.com webhooks to Signbee's REST API in under 10 minutes and guarantee every attendee arrives with a cryptographically signed agreement.
Related resources
Guide
How to Send a Document for Signature
Guide
How to Automate Document Signing
Use Case
Freelancer Contracts
Use Case
SaaS Terms of Service
Blog
State of AI Agent Contract Signing (October 2026): MCP, OpenAPI & Speed Benchmark
Blog
Automotive Dealership & Fleet E-Signature API: Test-Drive & Lease Waivers (2026)