# daybag.io > Bookings for outdoor outfitters: classes (sessions with seats), appointments (slots from weekly hours) and rentals (inventory over periods). Everything is available over REST and MCP. ## Auth Send `Authorization: Bearer daybag_live_…` with every request. Create keys in Dashboard → Developers. Errors are JSON: `{ "error": { "code": "sold_out", "message": "…" } }`. ## Endpoints - REST: https://daybag.io/api/v1 - OpenAPI: https://daybag.io/api/v1/openapi.json - MCP (streamable HTTP): https://daybag.io/api/mcp - Docs: https://daybag.io/docs - Each outfitter: https://daybag.io/book/ to book, https://daybag.io/book//llms.txt for its offerings in plain text ## Connect an agent - Claude Code: `claude mcp add --transport http daybag https://daybag.io/api/mcp --header "Authorization: Bearer daybag_live_…"` - Cursor and other MCP clients (mcp.json): ```json { "mcpServers": { "daybag": { "type": "http", "url": "https://daybag.io/api/mcp", "headers": { "Authorization": "Bearer daybag_live_…" } } } } ``` - claude.ai and ChatGPT connect once OAuth sign-in lands; until then use an API key as above. ## Typical flow 1. offerings_list: pick an offering 2. availability_get: slots with remaining capacity (from/to are local dates in the org time zone) 3. bookings_create: session_id for classes, starts_at for appointments and rentals 4. events_list: poll with after= to follow every change ## Events and webhooks Every change writes an event: - booking.held: A seat is held while the guest pays; it expires at expires_at - booking.confirmed: A booking is confirmed, from any surface and any path - booking.cancelled: A booking is cancelled - session.created: A class session is scheduled - session.cancelled: A class session is cancelled, with its bookings - offering.created: An offering is added - offering.updated: An offering changes or is archived - offering.deleted: An offering that was never booked is deleted - offering.hours_updated: Weekly hours are replaced - customer.updated: A customer is added or edited - customer.deleted: A customer's personal data is erased on request - org.updated: The org's name, time zone or currency changes A paid booking is held first (booking.held) and confirmed when the payment lands; a free one confirms at once. Every event carries a source: dashboard, api, mcp, widget or stripe. Poll: GET https://daybag.io/api/v1/events?after= (events_list) returns { data, next_after }; pass next_after back to keep following. Webhooks: webhooks_create { url, events } POSTs each event as JSON { id, type, created_at, data } to your HTTPS URL, signed with the secret it returns once: Daybag-Signature: t=,v1=.")> Verify a delivery: 1. Keep the raw request body; verify before you parse it. 2. Split the header at the commas: t is a unix time, v1 the signature. 3. HMAC-SHA256 the string "." with your webhook secret, hex encoded, and compare it to v1 in constant time. 4. Reject a t more than five minutes away, so a captured request can't be replayed. ## Pricing - Free: $0, no card. Hosted booking page, widget, dashboard, API, MCP, webhooks and confirmation emails, with a soft cap of 25 bookings a month that never blocks a guest. - Pro: $39 a month flat. Payment at booking into the outfitter's own Stripe account, and no cap. - No guest fees and no per-booking cut. API and MCP on every plan. ## Operations (tool: METHOD path — summary) ### offerings - offerings_list: GET /offerings — List offerings (classes, appointments and rentals), including archived ones - offerings_create: POST /offerings — Create an offering. Only kind and name are required; everything else has defaults per kind. Appointments and rentals open daily 9:00–17:00 (org time) until you set hours; classes need sessions. - offerings_get: GET /offerings/{id} — Get one offering - offerings_update: PATCH /offerings/{id} — Update an offering. Set active: false to archive it. - offerings_delete: DELETE /offerings/{id} — Delete an offering that has never been booked (otherwise archive it) - offerings_get_hours: GET /offerings/{id}/hours — Weekly opening hours of an appointment or rental, in the org's local time - offerings_set_hours: PUT /offerings/{id}/hours — Replace weekly opening hours, e.g. [{ weekday: 6, start_time: '08:00', end_time: '16:00' }] ### availability - availability_get: GET /offerings/{id}/availability — Bookable slots with remaining capacity between two local dates (default: the next 14 days) ### sessions - sessions_list: GET /sessions — List class sessions with the number of seats booked - sessions_create: POST /sessions — Schedule a class session; repeat_weeks repeats it weekly at the same local time - sessions_cancel: POST /sessions/{id}/cancel — Cancel a class session and every booking in it ### bookings - bookings_list: GET /bookings — List bookings filtered by time range, status, offering, customer or session (order=desc for newest first) - bookings_get: GET /bookings/{id} — Get one booking with its offering and customer - bookings_create: POST /bookings — Book a slot from availability.get (classes need session_id; appointments and rentals need starts_at). Pass hold_minutes to hold it instead, and idempotency_key so retries never book twice. - bookings_cancel: POST /bookings/{id}/cancel — Cancel a booking or a hold and free its capacity (safe to repeat) - bookings_confirm: POST /bookings/{id}/confirm — Confirm a held booking (safe to repeat). A hold past its expires_at confirms only if its place is still free. ### customers - customers_list: GET /customers — List customers, newest first; q searches name, email and phone - customers_get: GET /customers/{id} — Get a customer with their bookings - customers_upsert: POST /customers — Create a customer, or update the given fields when the email already exists - customers_update: PATCH /customers/{id} — Update a customer's name, phone, notes or metadata - customers_delete: DELETE /customers/{id} — Erase a customer's personal data (name, email, phone, notes) on request; their bookings stay, anonymized ### org - org_get: GET /org — Your organization: name, slug (booking page /book/{slug}), time zone and currency - org_update: PATCH /org — Rename the organization or change its time zone (IANA, e.g. America/Denver) or currency - org_export: GET /org/export — Export all your data as JSON: org, offerings, hours, sessions, customers, bookings, webhooks and the last 1000 events ### events - events_list: GET /events — Everything that happened, oldest first. Poll with after= to follow along. ### webhooks - webhooks_list: GET /webhooks — List webhook endpoints and their last delivery status - webhooks_create: POST /webhooks — Send events to an HTTPS URL, signed with HMAC-SHA256. Returns the signing secret once. - webhooks_delete: DELETE /webhooks/{id} — Stop sending events to a webhook endpoint ### billing - billing_get: GET /billing — Your plan (free or pro) and this month's confirmed bookings against the free plan's soft cap of 25