Quickstart
Python / FastAPI
Integrate Seshn into a FastAPI application using httpx for direct REST calls.
Prerequisites
- Python 3.9+
- A Seshn account with an API key (sign up)
1. Set up the project
terminal
1mkdir seshn-fastapi && cd seshn-fastapi2python -m venv .venv && source .venv/bin/activate3pip install fastapi uvicorn httpx2. Create a Seshn HTTP client
There is no Python SDK yet, so use httpx to call the REST API directly. This thin wrapper handles authentication and error checking.
seshn_client.py
1import os2import httpx34BASE_URL = "https://api.seshn.net"5API_KEY = os.environ["SESHN_API_KEY"]67client = httpx.AsyncClient(8 base_url=BASE_URL,9 headers={10 "Authorization": f"Bearer {API_KEY}",11 "Content-Type": "application/json",12 },13)141516async def get_availability(service_id: str, from_date: str, to_date: str) -> list[dict]:17 """Query available slots for a service within a date range."""18 resp = await client.get(19 "/v1/availability",20 params={"serviceId": service_id, "from": from_date, "to": to_date},21 )22 resp.raise_for_status()23 return resp.json()["data"]242526async def create_booking(slot_id: str, contact_id: str, seats: int = 1) -> dict:27 """Create a new booking for a slot."""28 resp = await client.post(29 "/v1/bookings",30 json={"slotId": slot_id, "contactId": contact_id, "seats": seats},31 )32 resp.raise_for_status()33 return resp.json()["booking"]343536async def confirm_booking(booking_id: str) -> dict:37 """Confirm a pending or held booking."""38 resp = await client.post(f"/v1/bookings/{booking_id}/confirm", json={})39 resp.raise_for_status()40 return resp.json()["booking"]3. Build the FastAPI app
Three endpoints: check availability, book a slot, and receive webhooks.
main.py
1import hashlib2import hmac3import os45from fastapi import FastAPI, Request, HTTPException6from pydantic import BaseModel78from seshn_client import get_availability, create_booking, confirm_booking910app = FastAPI()1112WEBHOOK_SECRET = os.environ.get("SESHN_WEBHOOK_SECRET", "")131415# ── Schemas ──────────────────────────────────────────────────1617class BookRequest(BaseModel):18 slot_id: str19 contact_id: str20 seats: int = 1212223# ── GET /availability ────────────────────────────────────────2425@app.get("/availability")26async def availability(service_id: str, from_date: str, to_date: str):27 slots = await get_availability(service_id, from_date, to_date)28 return {"slots": slots, "count": len(slots)}293031# ── POST /book ───────────────────────────────────────────────3233@app.post("/book")34async def book(body: BookRequest):35 booking = await create_booking(body.slot_id, body.contact_id, body.seats)36 confirmed = await confirm_booking(booking["id"])37 return confirmed383940# ── POST /webhooks ───────────────────────────────────────────4142@app.post("/webhooks")43async def webhooks(request: Request):44 signature = request.headers.get("x-webhook-signature", "")45 event = request.headers.get("x-webhook-event", "")46 payload = await request.body()4748 if not verify_signature(payload, signature, WEBHOOK_SECRET):49 raise HTTPException(status_code=401, detail="Invalid signature")5051 data = await request.json()5253 match event:54 case "booking.confirmed":55 # Send confirmation email, sync calendar, etc.56 pass57 case "booking.cancelled":58 # Process refund, notify staff, etc.59 pass60 case "payment.succeeded":61 # Update your records62 pass6364 return {"received": True}656667# ── Signature verification ───────────────────────────────────6869def verify_signature(payload: bytes, header: str, secret: str) -> bool:70 """Verify the HMAC-SHA256 signature from Seshn webhooks."""71 expected = "sha256=" + hmac.new(72 secret.encode(),73 payload,74 hashlib.sha256,75 ).hexdigest()7677 return hmac.compare_digest(header, expected)4. Run it
terminal
1SESHN_API_KEY=sk_test_... uvicorn main:app --reload --port 30015. Test the endpoints
terminal
1# Check availability2curl "http://localhost:3001/availability?service_id=svc_yoga_class&from_date=2026-03-20&to_date=2026-03-27"34# Create a booking5curl -X POST http://localhost:3001/book \6 -H "Content-Type: application/json" \7 -d '{"slot_id": "slot_...", "contact_id": "ct_jane_doe", "seats": 1}'Adding type safety
For stronger type guarantees, define Pydantic models that match the Seshn API responses. You can generate these from the OpenAPI spec using tools like datamodel-code-generator.
terminal
1pip install datamodel-code-generator2datamodel-codegen --url https://api.seshn.net/openapi.json --output models.pyWhat's next
- API Reference — Explore all endpoints interactively
- Webhooks — Event types, retries, and delivery logs
- Availability — Slot generation and capacity
- Bookings — Holds, cancellations, and rescheduling