Quickstart
Express
Build a booking API with Express and the Seshn SDK, including webhook signature verification.
Prerequisites
- Node.js 18+
- A Seshn account with an API key (sign up)
1. Set up the project
terminal
1mkdir seshn-express && cd seshn-express2npm init -y3npm install @seshn/sdk express4npm install -D typescript @types/express tsx2. Initialize the Seshn client
src/seshn.ts
1import { Seshn } from '@seshn/sdk';23export const seshn = new Seshn(process.env.SESHN_API_KEY!, {4 baseUrl: 'https://api.seshn.net',5});3. Create the server
Three endpoints cover the core flow: check availability, create and confirm a booking, and receive webhook events.
src/index.ts
1import express from 'express';2import crypto from 'crypto';3import { seshn } from './seshn';45const app = express();67// Parse JSON for all routes except webhooks (need raw body there)8app.use((req, res, next) => {9 if (req.path === '/webhooks') {10 express.raw({ type: 'application/json' })(req, res, next);11 } else {12 express.json()(req, res, next);13 }14});1516// ─── GET /availability ──────────────────────────────────────17app.get('/availability', async (req, res) => {18 const { serviceId, from, to } = req.query as Record<string, string>;1920 const result = await seshn.availability.query({21 serviceId,22 from,23 to,24 });2526 res.json(result.data);27});2829// ─── POST /book ─────────────────────────────────────────────30app.post('/book', async (req, res) => {31 const { slotId, contactId, seats } = req.body;3233 // Create the booking34 const { booking } = await seshn.bookings.create({35 slotId,36 contactId,37 seats,38 });3940 // Confirm immediately41 const { booking: confirmed } = await seshn.bookings.confirm(booking.id);4243 res.json(confirmed);44});4546// ─── POST /webhooks ─────────────────────────────────────────47app.post('/webhooks', (req, res) => {48 const signature = req.headers['x-webhook-signature'] as string;49 const event = req.headers['x-webhook-event'] as string;50 const payload = (req.body as Buffer).toString('utf-8');5152 // Verify HMAC signature53 if (!verifySignature(payload, signature, process.env.SESHN_WEBHOOK_SECRET!)) {54 res.status(401).json({ error: 'Invalid signature' });55 return;56 }5758 const data = JSON.parse(payload);59 console.log(`Received ${event}:`, data);6061 // Handle different event types62 switch (event) {63 case 'booking.confirmed':64 // Send confirmation email, sync calendar, etc.65 break;66 case 'booking.cancelled':67 // Process refund, notify staff, etc.68 break;69 case 'payment.succeeded':70 // Update your records71 break;72 }7374 res.json({ received: true });75});7677// ─── Signature verification ─────────────────────────────────78function verifySignature(payload: string, header: string, secret: string): boolean {79 const expected = `sha256=${crypto80 .createHmac('sha256', secret)81 .update(payload)82 .digest('hex')}`;8384 return crypto.timingSafeEqual(85 Buffer.from(header),86 Buffer.from(expected),87 );88}8990app.listen(3001, () => {91 console.log('Server running on http://localhost:3001');92});4. Run it
terminal
1SESHN_API_KEY=sk_test_... npx tsx src/index.ts5. Test the endpoints
terminal
1# Check availability2curl "http://localhost:3001/availability?serviceId=svc_yoga_class&from=2026-03-20&to=2026-03-27"34# Create a booking5curl -X POST http://localhost:3001/book \6 -H "Content-Type: application/json" \7 -d '{"slotId": "slot_...", "contactId": "ct_jane_doe", "seats": 1}'Webhook setup
Register your webhook endpoint in the dashboard or via the API. The signing secret is returned once at creation time -- store it securely.
register-webhook.ts
1const webhook = await seshn.webhooks.create({2 url: 'https://your-domain.com/webhooks',3 events: ['booking.confirmed', 'booking.cancelled', 'payment.succeeded'],4});56// Save webhook.secret -- it won't be shown again7console.log('Webhook secret:', webhook.secret);What's next
- API Reference — Explore all endpoints interactively
- Webhooks — Event types, retries, and delivery logs
- Bookings — Holds, cancellations, and rescheduling
- Payments — Charge for bookings with Stripe