Guide

How to Send Appointment Reminder Notifications

Reduce no-shows by up to 50% with automated appointment reminders via WhatsApp, SMS, and Email. Set it up once and let it run on autopilot.

The Cost of No-Shows

Missed appointments cost service businesses billions of dollars every year. Whether you run a medical practice, a salon, a consulting firm, or a tutoring service, no-shows mean lost revenue and wasted time. The Healthcare Finance Management Association estimates that the average no-show rate across industries is 20-30%. A simple reminder sent 24 hours before the appointment can reduce that rate by 30-50%.

The most effective reminder systems use multiple channels. An email sent the day before serves as a detailed reminder with appointment information and a calendar link. A WhatsApp or SMS message sent one hour before serves as a final nudge. With One-Ping, you can automate this entire flow and reach your clients on the channels they actually check.

What you will build: An automated reminder system that sends a detailed email 24 hours before each appointment and a short WhatsApp or SMS reminder 1 hour before. Includes integration with Google Calendar, Calendly, and custom booking systems.

Step-by-Step Setup

Plan Your Reminder Schedule

Before building anything, decide when to send reminders and what each one should contain. The industry standard is a 24-hour reminder with full appointment details (date, time, location, preparation instructions) and a 1-hour reminder that is short and action-oriented ("Your appointment is in 1 hour at 123 Main St"). Some businesses also send a 1-week reminder for appointments booked far in advance. Start with the 24-hour and 1-hour pattern and add more intervals later based on your no-show data.

Choose Your Reminder Channels

Different channels serve different purposes in a reminder system. Email is best for the 24-hour reminder because it can include rich details, calendar attachments, and links to reschedule. WhatsApp is ideal for the 1-hour reminder because it has a 98% open rate and most people read WhatsApp messages within 3 minutes. SMS is the universal fallback since it works on every phone, even without internet. Use multi-channel delivery for the most effective reach.

Connect Your Calendar or Booking System

Your reminder system needs to know about upcoming appointments. If you use Google Calendar, you can query the Google Calendar API for events in the next 24 hours. If you use Calendly, set up a webhook that fires when a new booking is created. If you have a custom booking system, query your database for appointments with scheduled times approaching. The code examples below cover all three approaches.

Build the Reminder Logic

The reminder logic runs on a schedule (cron job or n8n scheduled trigger) and checks for appointments that need reminders. For each appointment, it calculates how much time is left and sends the appropriate reminder via One-Ping. The script should track which reminders have been sent to avoid duplicates. A simple approach is to store a "reminder_sent" flag for each appointment in your database.

Handle Confirmations and Cancellations

Make your reminders actionable by including links to confirm or cancel the appointment. For email, include confirmation and cancellation buttons that link to your booking system. For WhatsApp, you can use interactive message templates with reply buttons. Track confirmations in your system and send a follow-up if someone cancels so you can fill the slot.

Code Examples

Node.js: Cron-Based Reminder Script

const cron = require('node-cron');

// Check for appointments every 15 minutes
cron.schedule('*/15 * * * *', async () => {
  const now = new Date();
  const in24h = new Date(now.getTime() + 24 * 60 * 60 * 1000);
  const in1h = new Date(now.getTime() + 60 * 60 * 1000);

  // Get appointments needing 24h reminder
  const upcoming24h = await db.query(`
    SELECT * FROM appointments
    WHERE start_time BETWEEN $1 AND $2
    AND reminder_24h_sent = false
  `, [in24h, new Date(in24h.getTime() + 15 * 60 * 1000)]);

  for (const apt of upcoming24h.rows) {
    // Send detailed email reminder
    await fetch('https://api.one-ping.com/send', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.ONEPING_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        message: `Reminder: You have an appointment tomorrow at ${apt.start_time}`,
        channels: ['email'],
        metadata: {
          email: {
            to: apt.client_email,
            subject: `Appointment Reminder - ${apt.service_name}`,
            html: `<h2>Appointment Reminder</h2>
                   <p><strong>Service:</strong> ${apt.service_name}</p>
                   <p><strong>Date:</strong> ${apt.start_time}</p>
                   <p><strong>Location:</strong> ${apt.location}</p>
                   <p><a href="${apt.confirm_url}">Confirm</a> |
                      <a href="${apt.cancel_url}">Cancel</a></p>`
          }
        }
      })
    });

    await db.query('UPDATE appointments SET reminder_24h_sent = true WHERE id = $1', [apt.id]);
  }

  // Get appointments needing 1h reminder
  const upcoming1h = await db.query(`
    SELECT * FROM appointments
    WHERE start_time BETWEEN $1 AND $2
    AND reminder_1h_sent = false
  `, [in1h, new Date(in1h.getTime() + 15 * 60 * 1000)]);

  for (const apt of upcoming1h.rows) {
    // Send short WhatsApp/SMS reminder
    await fetch('https://api.one-ping.com/send', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.ONEPING_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        message: `Reminder: Your ${apt.service_name} appointment is in 1 hour at ${apt.location}.`,
        channels: ['whatsapp', 'sms'],
        recipient: apt.client_phone
      })
    });

    await db.query('UPDATE appointments SET reminder_1h_sent = true WHERE id = $1', [apt.id]);
  }
});

console.log('Appointment reminder service running...');

n8n Workflow for Appointment Reminders

For a no-code approach, build an n8n workflow that handles the entire reminder flow visually. The workflow structure is:

  1. Schedule Trigger -- runs every 15 minutes to check for upcoming appointments.
  2. Google Calendar node (or database query) -- fetches appointments within the reminder window.
  3. IF node -- checks if the appointment is 24 hours away or 1 hour away.
  4. HTTP Request node -- calls One-Ping API with the appropriate channel (email for 24h, WhatsApp/SMS for 1h).
  5. Update node -- marks the reminder as sent in your database or calendar.

This workflow can be imported from our n8n template library and customized with your specific calendar and message content.

Calendly Integration

If you use Calendly for booking, you can set up a webhook that fires when a new appointment is scheduled, and immediately schedule the reminders.

# Python: Calendly webhook - schedule reminders when booking is created
from flask import Flask, request
import requests, os
from datetime import datetime, timedelta
from apscheduler.schedulers.background import BackgroundScheduler

app = Flask(__name__)
scheduler = BackgroundScheduler()
scheduler.start()

def send_reminder(message, channels, recipient, metadata=None):
    payload = {
        'message': message,
        'channels': channels,
        'recipient': recipient
    }
    if metadata:
        payload['metadata'] = metadata

    requests.post(
        'https://api.one-ping.com/send',
        headers={'Authorization': f'Bearer {os.environ["ONEPING_API_KEY"]}'},
        json=payload
    )

@app.route('/webhooks/calendly', methods=['POST'])
def calendly_webhook():
    data = request.get_json()
    event = data['payload']
    start = datetime.fromisoformat(event['scheduled_event']['start_time'])
    name = event['name']
    email = event['email']

    # Schedule 24h reminder
    scheduler.add_job(
        send_reminder,
        'date',
        run_date=start - timedelta(hours=24),
        args=[
            f'Reminder: Your appointment is tomorrow at {start.strftime("%I:%M %p")}.',
            ['email'],
            email,
            {'email': {'subject': 'Appointment Reminder - Tomorrow', 'to': email}}
        ]
    )

    # Schedule 1h reminder
    scheduler.add_job(
        send_reminder,
        'date',
        run_date=start - timedelta(hours=1),
        args=[
            f'Reminder: Your appointment starts in 1 hour!',
            ['whatsapp', 'sms'],
            email
        ]
    )

    return '', 200

Choosing the Right Channel for Each Reminder

Timing Best Channels Why
1 week before Email Gives time to reschedule. Include full details and calendar link.
24 hours before Email + WhatsApp Detailed email for reference, WhatsApp for visibility and confirmation.
1 hour before WhatsApp or SMS Short, urgent nudge. High open rate ensures they see it in time.
15 minutes before SMS Last resort for critical appointments. Keep the message very short.

Pro tip: Track your confirmation and no-show rates by channel to find the optimal reminder timing and channel for your specific audience. Healthcare practices often see the best results with a 24-hour email plus a 2-hour SMS reminder.

Best Practices

Ready to reduce no-shows?

Start free with 100 messages/month. No credit card required.

Get started free