Calendly is the standard for online appointment scheduling. But its true power emerges with automation: automatically add leads to your CRM, generate Zoom links, customize reminders, track no-shows. In this guide, we show you how to turn Calendly into an automation hub. If you are new to these platforms, start with our Zapier vs. Make.com vs. n8n comparison or our n8n beginner's guide.

Why Automate Calendly?

Typical Manual Tasks:

TaskManual EffortAutomated
Enter lead in CRM5 min/appointmentAutomatic
Create Zoom link2 min/appointmentAutomatic
Send preparation email5 min/appointmentTemplate
Follow up on no-shows10 min/caseAutomatic
Create meeting notes3 min/appointmentAutomatic

With 50 appointments/month: 20+ hours saved

Setting Up Calendly Webhooks

Step 1: Create Webhook URL

In n8n:

  1. New Workflow → Webhook Node
  2. HTTP Method: POST
  3. Path: calendly
  4. Copy URL: https://n8n.your-domain.com/webhook/calendly

In Make.com:

  1. New Scenario → Custom Webhook
  2. Copy URL

Step 2: Register with Calendly

  1. Calendly → Integrations → Webhooks
  2. Click "Add Webhook"
  3. Enter URL
  4. Select events:
    • invitee.created (appointment booked)
    • invitee.canceled (appointment canceled)
    • invitee.no_show (no-show marked)

Webhook Payload Example

{
  "event": "invitee.created",
  "payload": {
    "event_type": {
      "name": "30 Minute Consultation",
      "duration": 30
    },
    "event": {
      "uuid": "abc123",
      "start_time": "2024-01-20T10:00:00Z",
      "end_time": "2024-01-20T10:30:00Z",
      "location": {
        "type": "zoom",
        "join_url": "https://zoom.us/j/123456"
      }
    },
    "invitee": {
      "name": "John Smith",
      "email": "john@example.com",
      "questions_and_answers": [
        {
          "question": "Your company?",
          "answer": "Acme Inc."
        },
        {
          "question": "What is this about?",
          "answer": "Process automation"
        }
      ]
    }
  }
}

Workflow 1: Lead to CRM

The Workflow

Calendly (Appointment booked)
        ↓
    Search for contact in HubSpot
        ↓
    Exists? → Update
    New? → Create
        ↓
    Create deal
        ↓
    Create task: "Prepare for meeting"

n8n Implementation

Node 1: Receive webhook

Node 2: Search HubSpot Contact

// Node: HTTP Request - HubSpot Search
{
  "method": "POST",
  "url": "https://api.hubapi.com/crm/v3/objects/contacts/search",
  "headers": {
    "Authorization": "Bearer {{ $env.HUBSPOT_TOKEN }}"
  },
  "body": {
    "filterGroups": [{
      "filters": [{
        "propertyName": "email",
        "operator": "EQ",
        "value": "{{ $json.payload.invitee.email }}"
      }]
    }]
  }
}

Node 3: Create/Update Contact

// Node: IF - Contact exists?
const contacts = $json.results;

if (contacts.length > 0) {
  // Update existing contact
  return { action: 'update', contactId: contacts[0].id };
} else {
  // Create new contact
  return { action: 'create' };
}

Node 4: Create Deal

// Node: HubSpot - Create Deal
{
  "properties": {
    "dealname": "Consultation: {{ $('Webhook').item.json.payload.invitee.name }}",
    "pipeline": "default",
    "dealstage": "appointmentscheduled",
    "amount": "0",
    "closedate": "{{ $('Webhook').item.json.payload.event.start_time }}"
  }
}

Workflow 2: Personalized Preparation

The Workflow

Calendly (Appointment booked)
        ↓
    Research (LinkedIn, Website)
        ↓
    Create meeting brief
        ↓
    Create Notion page
        ↓
    Reminder 1h before appointment

LinkedIn Research

// Node: HTTP Request - LinkedIn (via Proxycurl)
{
  "method": "GET",
  "url": "https://nubela.co/proxycurl/api/v2/linkedin",
  "qs": {
    "url": "https://linkedin.com/in/{{ $json.linkedinProfile }}"
  },
  "headers": {
    "Authorization": "Bearer {{ $env.PROXYCURL_KEY }}"
  }
}

Meeting Brief in Notion

// Node: Notion - Create Page
{
  "parent": { "database_id": "{{ $env.NOTION_MEETINGS_DB }}" },
  "properties": {
    "Name": {
      "title": [{ "text": { "content": "Meeting: {{ $json.invitee.name }}" } }]
    },
    "Date": {
      "date": { "start": "{{ $json.event.start_time }}" }
    },
    "Company": {
      "rich_text": [{ "text": { "content": "{{ $json.company }}" } }]
    }
  },
  "children": [
    {
      "object": "block",
      "type": "heading_2",
      "heading_2": {
        "rich_text": [{ "text": { "content": "Preparation" } }]
      }
    },
    {
      "object": "block",
      "type": "bulleted_list_item",
      "bulleted_list_item": {
        "rich_text": [{ "text": { "content": "Topic: {{ $json.topic }}" } }]
      }
    }
  ]
}

Workflow 3: No-Show Follow-up

The Workflow

Calendly (No-show marked)
        ↓
    Send apology email
        ↓
    Offer new booking link
        ↓
    CRM: Update status
        ↓
    After 3 days: Follow-up

Implementation

// Node: Send Email
{
  "to": "{{ $json.payload.invitee.email }}",
  "subject": "We missed you - reschedule?",
  "body": `
    Hi {{ $json.payload.invitee.name }},

    Unfortunately we couldn't meet today.
    No problem - you can book a new appointment here:

    {{ $env.CALENDLY_LINK }}

    Looking forward to our conversation!

    Best regards
  `
}

Workflow 4: Zoom Integration

Automatically Create Zoom Meeting

Calendly (Appointment booked)
        ↓
    Zoom: Create meeting
        ↓
    Calendly: Update event
        ↓
    Confirmation email with link

Zoom API

// Node: HTTP Request - Zoom Create Meeting
{
  "method": "POST",
  "url": "https://api.zoom.us/v2/users/me/meetings",
  "headers": {
    "Authorization": "Bearer {{ $json.zoomToken }}"
  },
  "body": {
    "topic": "Consultation: {{ $json.invitee.name }}",
    "type": 2,
    "start_time": "{{ $json.event.start_time }}",
    "duration": {{ $json.event_type.duration }},
    "settings": {
      "join_before_host": true,
      "waiting_room": false
    }
  }
}

Workflow 5: SMS Reminder

The Workflow

Schedule (hourly)
        ↓
    Calendly: Appointments in next 2h
        ↓
    For each appointment:
      Send SMS reminder (Twilio)

Implementation

// Node: Twilio - Send SMS
{
  "to": "{{ $json.invitee.phone }}",
  "body": "Reminder: Your appointment with {{ $env.COMPANY_NAME }} starts in 1 hour. Zoom link: {{ $json.event.location.join_url }}"
}

Make.com: Calendly Modules

Native Modules

ModuleFunction
Watch EventsTrigger on new appointments
List EventsRetrieve appointments
Get EventRetrieve single appointment
Cancel EventCancel appointment

Example Scenario

Calendly (Watch Events)
        ↓
    Router:
    ├─ Event Created → CRM + Notion
    ├─ Event Canceled → CRM Update
    └─ No Show → Follow-up Email

Advanced Integrations

Calendly + Stripe (Paid Appointments)

Appointment booked
        ↓
    Stripe: Create payment link
        ↓
    Email: Payment request
        ↓
    [Payment successful]
        ↓
    Unlock Zoom link

Calendly + Google Calendar (Sync)

Calendly appointment
        ↓
    Google Calendar: Create event
        ↓
    Add details:
    - Attendee info
    - Preparation checklist
    - Zoom link

Calendly + Slack (Team Info)

New appointment
        ↓
    Slack #sales:
    "New appointment:
     John Smith - Acme Inc.
     Jan 20, 10:00 AM
     Topic: Automation"

Custom Booking Pages

Dynamic Event Types

// Event type based on lead score
const leadScore = await getLeadScore(email);

let eventType;
if (leadScore > 80) {
  eventType = 'enterprise-demo-60min';
} else if (leadScore > 50) {
  eventType = 'standard-demo-30min';
} else {
  eventType = 'discovery-call-15min';
}

const bookingUrl = `https://calendly.com/your-team/${eventType}?email=${email}`;

Pre-filled Booking Links

// Personalized link
const params = new URLSearchParams({
  name: lead.name,
  email: lead.email,
  a1: lead.company,  // Answer to question 1
  a2: lead.topic     // Answer to question 2
});

const bookingUrl = `https://calendly.com/team/meeting?${params}`;

Reporting & Analytics

Meeting Statistics

// Weekly report
const stats = {
  scheduled: await countEvents('created', 'week'),
  completed: await countEvents('completed', 'week'),
  cancelled: await countEvents('canceled', 'week'),
  noShow: await countEvents('no_show', 'week'),
  conversionRate: (completed / scheduled * 100).toFixed(1)
};

await sendSlackMessage('#sales', `
Weekly Booking Report:
- Scheduled: ${stats.scheduled}
- Completed: ${stats.completed}
- Cancelled: ${stats.cancelled}
- No-shows: ${stats.noShow}
- Conversion: ${stats.conversionRate}%
`);

Best Practices

1. Use Questions

Add required questions:

  • Company
  • Role
  • Topic/Goal
  • Phone number (for SMS reminders)

2. Routing Rules

// Route appointment to the right team member
const topic = $json.questions_and_answers.find(q => q.question.includes('Topic'))?.answer;

let assignee;
if (topic.includes('technical')) {
  assignee = 'tech-sales@company.com';
} else if (topic.includes('enterprise')) {
  assignee = 'enterprise@company.com';
} else {
  assignee = 'sales@company.com';
}

3. Reminder Timing

TimingChannelContent
24h beforeEmailAgenda + Preparation
1h beforeSMSQuick reminder + Link
10 min beforeEmail"Meeting starts soon"

Costs

ComponentCost
Calendly Pro$12/month
n8n CloudFrom $20/month
Make.comFrom $9/month
Twilio SMS~$0.05/SMS

Conclusion

Calendly automation turns a scheduling tool into a complete sales workflow:

  • Capture leads automatically
  • Prepare meetings professionally
  • Track no-shows
  • Keep the team informed

Next Steps

  1. Set up webhook at Calendly
  2. Build CRM integration
  3. Create reminder flow
  4. Add no-show flow

We support you with Calendly automation - from setup to productive use. For more ideas on automating your sales pipeline, see our article on HubSpot automation workflows. Contact us to get started.