← Integrations
SMS
Seshn + Twilio
Send SMS confirmations, appointment reminders, and waitlist alerts using Twilio and Seshn webhooks.
Install
1npm install twilioWebhook events
SMS works best for time-sensitive, short-form notifications:
booking.createdConfirm the booking via textbooking.cancelledNotify of cancellationbooking.hold_expiredAlert that their hold timed outwaitlist.promotedThey got a spot — act fastWebhook handler
A Next.js API route that receives Seshn webhooks and sends SMS via Twilio.
app/api/webhooks/seshn/route.ts
1import twilio from 'twilio';2import { createHmac } from 'crypto';34const client = twilio(5 process.env.TWILIO_ACCOUNT_SID,6 process.env.TWILIO_AUTH_TOKEN7);8const FROM_NUMBER = process.env.TWILIO_PHONE_NUMBER!;9const WEBHOOK_SECRET = process.env.SESHN_WEBHOOK_SECRET!;1011export async function POST(req: Request) {12 const body = await req.text();13 const signature = req.headers.get('x-webhook-signature');1415 const expected = 'sha256=' +16 createHmac('sha256', WEBHOOK_SECRET).update(body).digest('hex');1718 if (signature !== expected) {19 return new Response('Invalid signature', { status: 401 });20 }2122 const event = req.headers.get('x-webhook-event');23 const payload = JSON.parse(body);2425 // Only send SMS if the contact has a phone number26 if (!payload.contact?.phone) {27 return new Response('No phone number', { status: 200 });28 }2930 let message: string | null = null;3132 switch (event) {33 case 'booking.created':34 const date = new Date(payload.slot.startTime);35 message = `Booking confirmed: ${payload.service.name} on ${date.toLocaleDateString()} at ${date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}. ${payload.seats} seat(s).`;36 break;3738 case 'booking.cancelled':39 message = `Your booking for ${payload.service.name} has been cancelled.`;40 break;4142 case 'booking.hold_expired':43 message = `Your held spot for ${payload.service.name} has expired. Book again at ${payload.bookingUrl ?? 'our website'}.`;44 break;4546 case 'waitlist.promoted':47 message = `A spot opened up! You've been booked for ${payload.service.name}.`;48 break;49 }5051 if (message) {52 await client.messages.create({53 body: message,54 from: FROM_NUMBER,55 to: payload.contact.phone,56 });57 }5859 return new Response('OK', { status: 200 });60}Register the webhook
terminal
1curl -X POST https://api.seshn.net/v1/webhooks \2 -H "Authorization: Bearer sk_live_..." \3 -H "Content-Type: application/json" \4 -d '{5 "url": "https://yourdomain.com/api/webhooks/seshn",6 "events": [7 "booking.created",8 "booking.cancelled",9 "booking.hold_expired",10 "waitlist.promoted"11 ]12 }'Next steps
- Use Twilio Messaging Services for number pooling and compliance at scale.
- Add WhatsApp via Twilio for international customers by changing the
fromto awhatsapp:prefix. - Rate-limit SMS sends to avoid surprising customers with duplicate texts on retries.