Quickstart
Next.js
Add booking to a Next.js App Router project using Server Actions and the Seshn SDK.
Prerequisites
- Node.js 18+
- A Seshn account with an API key (sign up)
- A Next.js 14+ project with App Router
1. Install the SDK
terminal
1npm install @seshn/sdk2. Add your API key
Store the key in an environment variable. Never expose it to the browser.
.env.local
1SESHN_API_KEY=sk_test_...3. Create a Seshn client
Initialize the client once and reuse it across server code.
lib/seshn.ts
1import { Seshn } from '@seshn/sdk';23export const seshn = new Seshn(process.env.SESHN_API_KEY!, {4 baseUrl: 'https://api.seshn.net',5});4. Create Server Actions
Server Actions run on the server and can be called directly from React components. These three actions cover the core booking flow: check availability, create a booking, and confirm it.
app/actions.ts
1'use server';23import { seshn } from '@/lib/seshn';45export async function getAvailability(serviceId: string, from: string, to: string) {6 const result = await seshn.availability.query({ serviceId, from, to });7 return result.data;8}910export async function createBooking(slotId: string, contactId: string, seats: number) {11 const { booking } = await seshn.bookings.create({12 slotId,13 contactId,14 seats,15 hold: true, // hold the slot while the user confirms16 });17 return booking;18}1920export async function confirmBooking(bookingId: string) {21 const { booking } = await seshn.bookings.confirm(bookingId);22 return booking;23}5. Build a booking component
This client component calls the Server Actions you defined above. It fetches slots, lets the user pick one, and confirms the booking.
app/book/page.tsx
1'use client';23import { useState, useEffect } from 'react';4import { getAvailability, createBooking, confirmBooking } from '../actions';56export default function BookingPage() {7 const [slots, setSlots] = useState<any[]>([]);8 const [booking, setBooking] = useState<any>(null);9 const [confirmed, setConfirmed] = useState(false);1011 useEffect(() => {12 getAvailability('svc_yoga_class', '2026-03-20', '2026-03-27')13 .then(setSlots);14 }, []);1516 async function handleBook(slotId: string) {17 const b = await createBooking(slotId, 'ct_jane_doe', 1);18 setBooking(b);19 }2021 async function handleConfirm() {22 if (!booking) return;23 await confirmBooking(booking.id);24 setConfirmed(true);25 }2627 if (confirmed) {28 return <p>Booking {booking.id} confirmed.</p>;29 }3031 if (booking) {32 return (33 <div>34 <p>Booking {booking.id} is held. Confirm?</p>35 <button onClick={handleConfirm}>Confirm</button>36 </div>37 );38 }3940 return (41 <div>42 <h1>Available Slots</h1>43 {slots.map((slot) => (44 <div key={slot.id}>45 <span>{slot.startTime} - {slot.endTime}</span>46 <button onClick={() => handleBook(slot.id)}>Book</button>47 </div>48 ))}49 </div>50 );51}6. Alternative: API Route
If you prefer Route Handlers over Server Actions, expose the same logic as an API endpoint.
app/api/book/route.ts
1import { NextRequest, NextResponse } from 'next/server';2import { seshn } from '@/lib/seshn';34export async function POST(req: NextRequest) {5 const { slotId, contactId, seats } = await req.json();67 // Create the booking8 const { booking } = await seshn.bookings.create({9 slotId,10 contactId,11 seats,12 });1314 // Confirm immediately (or let the client confirm later)15 const { booking: confirmed } = await seshn.bookings.confirm(booking.id);1617 return NextResponse.json(confirmed);18}What's next
- API Reference — Explore all endpoints interactively
- Webhooks — React to booking events in real time
- Payments — Charge for bookings with Stripe
- Entitlements — Credit packs and memberships