API reference
The REST API lives at https://daybooked.io/api/v1: send Authorization: Bearer daybooked_live_… and JSON. Lists come back as { data } and errors as { "error": { "code", "message" } } with an HTTP status. Every operation is also an MCP tool of the same name, and this page is generated from the schemas behind the OpenAPI document.
Offerings
GET/offeringsofferings_list
List offerings (classes, appointments and rentals), paused ones included
Request1
- kindquery
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
Response 20037
- datarequired
- object[]
- data[].idrequired
- string
- data[].org_idrequired
- string
- data[].kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- data[].namerequired
- string
- data[].descriptionrequired
- string
- data[].locationrequired
- string · Where it meets, as guests read it: an address, a place or GPS coordinates. Or an https meeting link for an offering online, which guests join
- data[].duration_minutesrequired
- integer · Length of a class session or appointment, or of one rental period (1440 = a day)
- data[].capacityrequired
- integer · class: seats per session · appointment: parallel bookings per slot · rental: items in stock
- data[].max_per_bookingrequired
- integer · Most seats, people or items in one booking. An appointment is one-on-one at 1 (its default); more lets a guest book for a party
- data[].price_centsrequired
- integer · class: per seat · appointment: per appointment, for its first person (see guest_price_cents) · rental: per item per period
- data[].guest_price_cents
- integer | null · appointment: what each additional guest in a party adds; null (the default) charges each the full price, 0 makes them free
- data[].deposit_cents
- integer | null · A deposit guests pay at booking where they pay online, in the currency's minor units (at most the total); the rest is due at the start. Null: the whole total
- data[].deposit_percent
- integer | null · A deposit as a percent of the total, 1 to 99, paid at booking where guests pay online; null: the whole total
- data[].slot_interval_minutesrequired
- integer | null · Minutes between start times; null means back to back
- data[].buffer_minutesrequired
- integer
- data[].min_notice_minutesrequired
- integer
- data[].max_advance_daysrequired
- integer
- data[].max_periodsrequired
- integer · Rentals: the most periods one booking can span
- data[].activerequired
- boolean · false pauses booking: guests and agents can't book it, and it stays in your dashboard
- data[].metadatarequired
- any · Free-form JSON object for your own integrations
- data[].lat
- number | null · The meeting point's latitude, for its map link and the weather call
- data[].lon
- number | null
- data[].place_id
- string | null · Google Maps' place ID for the location, which the guest's map link opens
- data[].gauge_site
- string | null · A USGS river gauge's site number
- data[].schedule
- hours | calendar | null · An appointment's: weekly hours or calendar entries; null for other kinds
- data[].waiver_required
- boolean · Each person booked signs your waiver (waiver.get) on their phone before they come
- data[].waitlist_enabled
- boolean · A full time keeps a waitlist that guests join, emailed when a place opens (waitlist_list). Switched off, everyone waiting comes off and is emailed
- data[].course
- boolean · A class sold as a course: availability.get lists each calendar entry that ends as one slot, and bookings.create takes its series_id to book every time of it
- data[].questions
- object[] · What guests answer as they book, in this order: ask the guest, then pass the answers to bookings.create as answers, keyed by each question's id
- data[].questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- data[].questions[].labelrequired
- string · The question as guests read it
- data[].questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- data[].questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- data[].questions[].requiredrequired
- boolean · Guests must answer it to book online
- data[].photo_url
- string | null · Its photo, at the top of its card on the booking page: a JPEG's absolute URL, or null without one. Read-only: photos are uploaded in the dashboard (the offering's Photo)
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
POST/offeringsofferings_create
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.
Request32
- namerequired
- string · ≤ 120 chars
- description
- string · ≤ 2000 chars
- location
- string · ≤ 500 chars · Where it meets, as guests read it, with a Google Maps link: an address, a place with its town, or GPS coordinates ("45.6770, -111.0429"). Or an https meeting link (Zoom, Meet, Teams) for an offering online: guests get Join instead of a map, and its times on their own clock
- duration_minutes
- integer · 5–43200 · Length of a class session or appointment, or of one rental period (1440 = a day)
- capacity
- integer · 1–10000 · class: seats per session · appointment: parallel bookings per slot · rental: items in stock
- max_per_booking
- integer · 1–10000 · Most seats, people or items in one booking. An appointment is one-on-one at 1 (its default); more lets a guest book for a party
- price_cents
- integer · ≥ 0 · class: per seat · appointment: per appointment, for its first person (see guest_price_cents) · rental: per item per period
- guest_price_cents
- integer | null · appointment: what each additional guest in a party adds; null (the default) charges each the full price, 0 makes them free
- deposit_cents
- integer | null · A deposit to hold a place, in the currency's minor units: where guests pay online at booking, they pay this much (at most the total) and the rest at the start. Null (the default) takes the whole total. One or the other with deposit_percent: setting one clears the other, both at once is 400 deposit_conflict
- deposit_percent
- integer | null · A deposit as a percent of the total, 1 to 99, rounded half up to a whole minor unit (after any promo code). Null (the default) takes the whole total
- slot_interval_minutes
- integer | null · Minutes between start times; null means back to back
- buffer_minutes
- integer · 0–1440 · Gap between bookings: minutes kept free before and after each one, for rentals and appointments on weekly hours (a calendar's times keep none)
- min_notice_minutes
- integer · 0–43200 · When booking closes: how many minutes before a time starts (0: open until it starts)
- max_advance_days
- integer · 1–730
- max_periods
- integer · 1–60 · Rentals: the most periods one booking can span
- active
- boolean · false pauses booking: guests and agents can't book it, and it stays in your dashboard
- metadata
- object · Free-form JSON for your own integrations
- lat
- number | null · The meeting point's latitude, for its map link and the weather call. A new location without lat and lon sets them from coordinates typed in it, or clears them
- lon
- number | null · The meeting point's longitude
- place_id
- string | null · Google Maps' place ID for the location, which the guest's map link opens; the dashboard's Location search sets it, and a new location without it clears it
- gauge_site
- string | null · A USGS river gauge's site number (e.g. 13022500), for the river's flow
- schedule
- hours | calendar · Appointments only: open on weekly hours (offerings.set_hours) or on calendar entries (series.create), one or the other; new ones use the calendar, and it moves to hours only once its calendar has no times to come
- waiver_required
- boolean · Each person booked signs your waiver on their phone before they come: one per seat or guest, one per rental booking. Needs your waiver's text first (waiver.update; 409 waiver_missing)
- waitlist_enabled
- boolean · A full time keeps a waitlist: guests whose party doesn't fit join it from the booking page, and when a place opens everyone whose party fits is emailed at once (waitlist_list). Times on a calendar only: a class's, or an appointment's on its calendar (400 waitlist_not_supported)
- questions
- object[] · ≤ 6 items · What guests answer as they book, up to 6, in this order; the whole list replaces the last. bookings.create takes their answers keyed by each question's id
- questions[].id
- string · Keep a question's id to keep the answers given to it; a new question gets one
- questions[].labelrequired
- string · ≤ 80 chars · The question as guests read it, e.g. Shoe size
- questions[].typerequired
- text | yes_no | choice · text: a line in their words · yes_no: yes or no · choice: one of its options
- questions[].options
- string[] · ≤ 8 items · A choice's options, 2 to 8, each once; the other types take none
- questions[].required
- boolean · Guests must answer it to book (false by default)
- course
- boolean · Classes only (409 not_a_class): sell it as a course. One booking (bookings.create's series_id) takes a seat in every time of a calendar entry from its first to come, at price_cents per seat for the whole course; a repeating entry needs ends_on. No waitlist (409 waitlist_conflict)
- kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
Response 20136
- idrequired
- string
- org_idrequired
- string
- kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- namerequired
- string
- descriptionrequired
- string
- locationrequired
- string · Where it meets, as guests read it: an address, a place or GPS coordinates. Or an https meeting link for an offering online, which guests join
- duration_minutesrequired
- integer · Length of a class session or appointment, or of one rental period (1440 = a day)
- capacityrequired
- integer · class: seats per session · appointment: parallel bookings per slot · rental: items in stock
- max_per_bookingrequired
- integer · Most seats, people or items in one booking. An appointment is one-on-one at 1 (its default); more lets a guest book for a party
- price_centsrequired
- integer · class: per seat · appointment: per appointment, for its first person (see guest_price_cents) · rental: per item per period
- guest_price_cents
- integer | null · appointment: what each additional guest in a party adds; null (the default) charges each the full price, 0 makes them free
- deposit_cents
- integer | null · A deposit guests pay at booking where they pay online, in the currency's minor units (at most the total); the rest is due at the start. Null: the whole total
- deposit_percent
- integer | null · A deposit as a percent of the total, 1 to 99, paid at booking where guests pay online; null: the whole total
- slot_interval_minutesrequired
- integer | null · Minutes between start times; null means back to back
- buffer_minutesrequired
- integer
- min_notice_minutesrequired
- integer
- max_advance_daysrequired
- integer
- max_periodsrequired
- integer · Rentals: the most periods one booking can span
- activerequired
- boolean · false pauses booking: guests and agents can't book it, and it stays in your dashboard
- metadatarequired
- any · Free-form JSON object for your own integrations
- lat
- number | null · The meeting point's latitude, for its map link and the weather call
- lon
- number | null
- place_id
- string | null · Google Maps' place ID for the location, which the guest's map link opens
- gauge_site
- string | null · A USGS river gauge's site number
- schedule
- hours | calendar | null · An appointment's: weekly hours or calendar entries; null for other kinds
- waiver_required
- boolean · Each person booked signs your waiver (waiver.get) on their phone before they come
- waitlist_enabled
- boolean · A full time keeps a waitlist that guests join, emailed when a place opens (waitlist_list). Switched off, everyone waiting comes off and is emailed
- course
- boolean · A class sold as a course: availability.get lists each calendar entry that ends as one slot, and bookings.create takes its series_id to book every time of it
- questions
- object[] · What guests answer as they book, in this order: ask the guest, then pass the answers to bookings.create as answers, keyed by each question's id
- questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- questions[].labelrequired
- string · The question as guests read it
- questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- questions[].requiredrequired
- boolean · Guests must answer it to book online
- photo_url
- string | null · Its photo, at the top of its card on the booking page: a JPEG's absolute URL, or null without one. Read-only: photos are uploaded in the dashboard (the offering's Photo)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
GET/offerings/{id}offerings_get
Get one offering, with the questions guests answer as they book: bookings.create takes their answers, keyed by question id
Request1
- idpathrequired
- string · uuid
Response 20036
- idrequired
- string
- org_idrequired
- string
- kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- namerequired
- string
- descriptionrequired
- string
- locationrequired
- string · Where it meets, as guests read it: an address, a place or GPS coordinates. Or an https meeting link for an offering online, which guests join
- duration_minutesrequired
- integer · Length of a class session or appointment, or of one rental period (1440 = a day)
- capacityrequired
- integer · class: seats per session · appointment: parallel bookings per slot · rental: items in stock
- max_per_bookingrequired
- integer · Most seats, people or items in one booking. An appointment is one-on-one at 1 (its default); more lets a guest book for a party
- price_centsrequired
- integer · class: per seat · appointment: per appointment, for its first person (see guest_price_cents) · rental: per item per period
- guest_price_cents
- integer | null · appointment: what each additional guest in a party adds; null (the default) charges each the full price, 0 makes them free
- deposit_cents
- integer | null · A deposit guests pay at booking where they pay online, in the currency's minor units (at most the total); the rest is due at the start. Null: the whole total
- deposit_percent
- integer | null · A deposit as a percent of the total, 1 to 99, paid at booking where guests pay online; null: the whole total
- slot_interval_minutesrequired
- integer | null · Minutes between start times; null means back to back
- buffer_minutesrequired
- integer
- min_notice_minutesrequired
- integer
- max_advance_daysrequired
- integer
- max_periodsrequired
- integer · Rentals: the most periods one booking can span
- activerequired
- boolean · false pauses booking: guests and agents can't book it, and it stays in your dashboard
- metadatarequired
- any · Free-form JSON object for your own integrations
- lat
- number | null · The meeting point's latitude, for its map link and the weather call
- lon
- number | null
- place_id
- string | null · Google Maps' place ID for the location, which the guest's map link opens
- gauge_site
- string | null · A USGS river gauge's site number
- schedule
- hours | calendar | null · An appointment's: weekly hours or calendar entries; null for other kinds
- waiver_required
- boolean · Each person booked signs your waiver (waiver.get) on their phone before they come
- waitlist_enabled
- boolean · A full time keeps a waitlist that guests join, emailed when a place opens (waitlist_list). Switched off, everyone waiting comes off and is emailed
- course
- boolean · A class sold as a course: availability.get lists each calendar entry that ends as one slot, and bookings.create takes its series_id to book every time of it
- questions
- object[] · What guests answer as they book, in this order: ask the guest, then pass the answers to bookings.create as answers, keyed by each question's id
- questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- questions[].labelrequired
- string · The question as guests read it
- questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- questions[].requiredrequired
- boolean · Guests must answer it to book online
- photo_url
- string | null · Its photo, at the top of its card on the booking page: a JPEG's absolute URL, or null without one. Read-only: photos are uploaded in the dashboard (the offering's Photo)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
PATCH/offerings/{id}offerings_update
Update an offering. Set active: false to pause booking; it stays in your dashboard. Setting waitlist_enabled false takes everyone waiting for its times off the waitlist and emails each of them that it closed.
Request32
- idpathrequired
- string · uuid
- name
- string · ≤ 120 chars
- description
- string · ≤ 2000 chars
- location
- string · ≤ 500 chars · Where it meets, as guests read it, with a Google Maps link: an address, a place with its town, or GPS coordinates ("45.6770, -111.0429"). Or an https meeting link (Zoom, Meet, Teams) for an offering online: guests get Join instead of a map, and its times on their own clock
- duration_minutes
- integer · 5–43200 · Length of a class session or appointment, or of one rental period (1440 = a day)
- capacity
- integer · 1–10000 · class: seats per session · appointment: parallel bookings per slot · rental: items in stock
- max_per_booking
- integer · 1–10000 · Most seats, people or items in one booking. An appointment is one-on-one at 1 (its default); more lets a guest book for a party
- price_cents
- integer · ≥ 0 · class: per seat · appointment: per appointment, for its first person (see guest_price_cents) · rental: per item per period
- guest_price_cents
- integer | null · appointment: what each additional guest in a party adds; null (the default) charges each the full price, 0 makes them free
- deposit_cents
- integer | null · A deposit to hold a place, in the currency's minor units: where guests pay online at booking, they pay this much (at most the total) and the rest at the start. Null (the default) takes the whole total. One or the other with deposit_percent: setting one clears the other, both at once is 400 deposit_conflict
- deposit_percent
- integer | null · A deposit as a percent of the total, 1 to 99, rounded half up to a whole minor unit (after any promo code). Null (the default) takes the whole total
- slot_interval_minutes
- integer | null · Minutes between start times; null means back to back
- buffer_minutes
- integer · 0–1440 · Gap between bookings: minutes kept free before and after each one, for rentals and appointments on weekly hours (a calendar's times keep none)
- min_notice_minutes
- integer · 0–43200 · When booking closes: how many minutes before a time starts (0: open until it starts)
- max_advance_days
- integer · 1–730
- max_periods
- integer · 1–60 · Rentals: the most periods one booking can span
- active
- boolean · false pauses booking: guests and agents can't book it, and it stays in your dashboard
- metadata
- object · Free-form JSON for your own integrations
- lat
- number | null · The meeting point's latitude, for its map link and the weather call. A new location without lat and lon sets them from coordinates typed in it, or clears them
- lon
- number | null · The meeting point's longitude
- place_id
- string | null · Google Maps' place ID for the location, which the guest's map link opens; the dashboard's Location search sets it, and a new location without it clears it
- gauge_site
- string | null · A USGS river gauge's site number (e.g. 13022500), for the river's flow
- schedule
- hours | calendar · Appointments only: open on weekly hours (offerings.set_hours) or on calendar entries (series.create), one or the other; new ones use the calendar, and it moves to hours only once its calendar has no times to come
- waiver_required
- boolean · Each person booked signs your waiver on their phone before they come: one per seat or guest, one per rental booking. Needs your waiver's text first (waiver.update; 409 waiver_missing)
- waitlist_enabled
- boolean · A full time keeps a waitlist: guests whose party doesn't fit join it from the booking page, and when a place opens everyone whose party fits is emailed at once (waitlist_list). Times on a calendar only: a class's, or an appointment's on its calendar (400 waitlist_not_supported)
- questions
- object[] · ≤ 6 items · What guests answer as they book, up to 6, in this order; the whole list replaces the last. bookings.create takes their answers keyed by each question's id
- questions[].id
- string · Keep a question's id to keep the answers given to it; a new question gets one
- questions[].labelrequired
- string · ≤ 80 chars · The question as guests read it, e.g. Shoe size
- questions[].typerequired
- text | yes_no | choice · text: a line in their words · yes_no: yes or no · choice: one of its options
- questions[].options
- string[] · ≤ 8 items · A choice's options, 2 to 8, each once; the other types take none
- questions[].required
- boolean · Guests must answer it to book (false by default)
- course
- boolean · Classes only (409 not_a_class): sell it as a course. One booking (bookings.create's series_id) takes a seat in every time of a calendar entry from its first to come, at price_cents per seat for the whole course; a repeating entry needs ends_on. No waitlist (409 waitlist_conflict)
Response 20036
- idrequired
- string
- org_idrequired
- string
- kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- namerequired
- string
- descriptionrequired
- string
- locationrequired
- string · Where it meets, as guests read it: an address, a place or GPS coordinates. Or an https meeting link for an offering online, which guests join
- duration_minutesrequired
- integer · Length of a class session or appointment, or of one rental period (1440 = a day)
- capacityrequired
- integer · class: seats per session · appointment: parallel bookings per slot · rental: items in stock
- max_per_bookingrequired
- integer · Most seats, people or items in one booking. An appointment is one-on-one at 1 (its default); more lets a guest book for a party
- price_centsrequired
- integer · class: per seat · appointment: per appointment, for its first person (see guest_price_cents) · rental: per item per period
- guest_price_cents
- integer | null · appointment: what each additional guest in a party adds; null (the default) charges each the full price, 0 makes them free
- deposit_cents
- integer | null · A deposit guests pay at booking where they pay online, in the currency's minor units (at most the total); the rest is due at the start. Null: the whole total
- deposit_percent
- integer | null · A deposit as a percent of the total, 1 to 99, paid at booking where guests pay online; null: the whole total
- slot_interval_minutesrequired
- integer | null · Minutes between start times; null means back to back
- buffer_minutesrequired
- integer
- min_notice_minutesrequired
- integer
- max_advance_daysrequired
- integer
- max_periodsrequired
- integer · Rentals: the most periods one booking can span
- activerequired
- boolean · false pauses booking: guests and agents can't book it, and it stays in your dashboard
- metadatarequired
- any · Free-form JSON object for your own integrations
- lat
- number | null · The meeting point's latitude, for its map link and the weather call
- lon
- number | null
- place_id
- string | null · Google Maps' place ID for the location, which the guest's map link opens
- gauge_site
- string | null · A USGS river gauge's site number
- schedule
- hours | calendar | null · An appointment's: weekly hours or calendar entries; null for other kinds
- waiver_required
- boolean · Each person booked signs your waiver (waiver.get) on their phone before they come
- waitlist_enabled
- boolean · A full time keeps a waitlist that guests join, emailed when a place opens (waitlist_list). Switched off, everyone waiting comes off and is emailed
- course
- boolean · A class sold as a course: availability.get lists each calendar entry that ends as one slot, and bookings.create takes its series_id to book every time of it
- questions
- object[] · What guests answer as they book, in this order: ask the guest, then pass the answers to bookings.create as answers, keyed by each question's id
- questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- questions[].labelrequired
- string · The question as guests read it
- questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- questions[].requiredrequired
- boolean · Guests must answer it to book online
- photo_url
- string | null · Its photo, at the top of its card on the booking page: a JPEG's absolute URL, or null without one. Read-only: photos are uploaded in the dashboard (the offering's Photo)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
DELETE/offerings/{id}offerings_delete
Delete an offering. With upcoming bookings, pass cancel_bookings: true: they're cancelled (guests emailed, online payments refunded in full) and past bookings stay on record. Returns { cancelled, refunded, refunding, refund_failed }.
Request2
- idpathrequired
- string · uuid
- cancel_bookingsquery
- boolean · Required when the offering has upcoming bookings or live holds; otherwise the delete answers 409 with what it would cancel
Response 2004
- cancelledrequired
- integer · Upcoming bookings and holds cancelled
- refundedrequired
- integer · Online payments Stripe confirmed refunded in full
- refundingrequired
- integer · Refunds still on their way: Stripe hasn't confirmed them yet
- refund_failedrequired
- integer · Refunds that failed: each booking says why in refund_error
GET/offerings/{id}/hoursofferings_get_hours
Weekly opening hours of an appointment or rental, in the org's local time
Request1
- idpathrequired
- string · uuid
Response 2004
- datarequired
- object[]
- data[].weekdayrequired
- integer · 0 = Sunday … 6 = Saturday
- data[].start_timerequired
- string · Local wall-clock time, HH:MM:SS
- data[].end_timerequired
- string · Local wall-clock time, HH:MM:SS
PUT/offerings/{id}/hoursofferings_set_hours
Replace weekly opening hours of a rental or an appointment on weekly hours, e.g. [{ weekday: 6, start_time: '08:00', end_time: '16:00' }]
Request5
- idpathrequired
- string · uuid
- hoursrequired
- object[] · ≤ 50 items
- hours[].weekdayrequired
- integer · 0–6 · 0 = Sunday … 6 = Saturday
- hours[].start_timerequired
- string
- hours[].end_timerequired
- string
Response 2004
- datarequired
- object[]
- data[].weekdayrequired
- integer · 0 = Sunday … 6 = Saturday
- data[].start_timerequired
- string · Local wall-clock time, HH:MM:SS
- data[].end_timerequired
- string · Local wall-clock time, HH:MM:SS
Availability
GET/offerings/{id}/availabilityavailability_get
Bookable slots with remaining capacity between two local dates (default: the next 14 days)
Request3
- idpathrequired
- string · uuid
- fromquery
- string · date · Local calendar date (YYYY-MM-DD) in the org's time zone
- toquery
- string · date · Local calendar date (YYYY-MM-DD) in the org's time zone
Response 20010
- timezonerequired
- string · The org's time zone; from and to are local dates in it
- datarequired
- object[]
- data[].starts_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].ends_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].capacityrequired
- integer
- data[].remainingrequired
- integer · What's left to book: seats, parallel slots or items; a course's, the seats left in its fullest time
- data[].session_id
- string · Classes only: pass it to bookings_create
- data[].series_id
- string · A course only: the entry it books whole; pass it to bookings_create as series_id
- data[].sessions
- integer · A course only: how many times it has to come, from starts_at to the last's end (ends_at)
- data[].repeat
- string · A course only: how its times repeat, as its entry's repeat
Series
GET/seriesseries_list
List an offering's calendar entries; each makes the sessions (times) it repeats as, listed by sessions.list
Request1
- offering_idqueryrequired
- string · uuid
Response 20014
- datarequired
- object[]
- data[].idrequired
- string
- data[].org_idrequired
- string
- data[].offering_idrequired
- string
- data[].starts_onrequired
- string · The first time's local date
- data[].start_timerequired
- string | null · Local HH:MM:SS; null with end_time null is all day
- data[].end_timerequired
- string | null
- data[].span_daysrequired
- integer · Days from a time's date to the date it ends
- data[].repeatrequired
- none | daily | weekly | monthly | yearly | weekdays · none · daily · weekly (its first date's weekday) · monthly (that weekday of the month, e.g. the last Tuesday) · yearly · weekdays (Monday to Friday)
- data[].capacityrequired
- integer | null · A class's seats for these times; null uses the class's
- data[].ends_on
- string | null · A repeat's last local date, that day included; null repeats on
- data[].made_untilrequired
- string · Its sessions exist through this local date; repeats are kept about a year ahead
- data[].teacher
- object | null · Who teaches it; null for nobody
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
POST/seriesseries_create
Add times to a class's calendar, or a calendar appointment's: a date, a start and end (or all day, or overnight), how it repeats and who teaches. Its sessions are made about a year ahead.
Request9
- starts_onrequired
- string · date · The first time's local date (YYYY-MM-DD) in the org's time zone
- start_time
- string | null · Local start, HH:MM. Leave start_time and end_time out for all day
- end_time
- string | null · Local end, HH:MM; before the start with span_days 1 runs overnight
- span_days
- integer · 0–30 · Days from a time's date to the date it ends (default 0): 1 runs overnight; all day, the extra whole days
- repeat
- none | daily | weekly | monthly | yearly | weekdays · How it repeats (default none)
- capacity
- integer | null · Classes only: seats for these times; null uses the class's
- teacher
- string | null · Who teaches it: a member's user id (Settings → Team); null for nobody. Anyone not on your team answers 400 not_a_member. Copied to each of its times; a change reaches every time to come
- ends_on
- string | null · A repeat's last local date, that day included; null (the default) repeats on. A course's repeating entry needs one (409 invalid_entry)
- offering_idrequired
- string · uuid
Response 20113
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- starts_onrequired
- string · The first time's local date
- start_timerequired
- string | null · Local HH:MM:SS; null with end_time null is all day
- end_timerequired
- string | null
- span_daysrequired
- integer · Days from a time's date to the date it ends
- repeatrequired
- none | daily | weekly | monthly | yearly | weekdays · none · daily · weekly (its first date's weekday) · monthly (that weekday of the month, e.g. the last Tuesday) · yearly · weekdays (Monday to Friday)
- capacityrequired
- integer | null · A class's seats for these times; null uses the class's
- ends_on
- string | null · A repeat's last local date, that day included; null repeats on
- made_untilrequired
- string · Its sessions exist through this local date; repeats are kept about a year ahead
- teacher
- object | null · Who teaches it; null for nobody
- created_atrequired
- string · ISO 8601 timestamp (UTC)
PATCH/series/{id}series_update
Change all of an entry's times: future ones nobody booked are remade from it, booked ones keep their time. A new teacher teaches every time to come
Request9
- idpathrequired
- string · uuid
- starts_on
- string · date · The first time's local date (YYYY-MM-DD) in the org's time zone
- start_time
- string | null · Local start, HH:MM. Leave start_time and end_time out for all day
- end_time
- string | null · Local end, HH:MM; before the start with span_days 1 runs overnight
- span_days
- integer · 0–30 · Days from a time's date to the date it ends (default 0): 1 runs overnight; all day, the extra whole days
- repeat
- none | daily | weekly | monthly | yearly | weekdays · How it repeats (default none)
- capacity
- integer | null · Classes only: seats for these times; null uses the class's
- teacher
- string | null · Who teaches it: a member's user id (Settings → Team); null for nobody. Anyone not on your team answers 400 not_a_member. Copied to each of its times; a change reaches every time to come
- ends_on
- string | null · A repeat's last local date, that day included; null (the default) repeats on. A course's repeating entry needs one (409 invalid_entry)
Response 20013
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- starts_onrequired
- string · The first time's local date
- start_timerequired
- string | null · Local HH:MM:SS; null with end_time null is all day
- end_timerequired
- string | null
- span_daysrequired
- integer · Days from a time's date to the date it ends
- repeatrequired
- none | daily | weekly | monthly | yearly | weekdays · none · daily · weekly (its first date's weekday) · monthly (that weekday of the month, e.g. the last Tuesday) · yearly · weekdays (Monday to Friday)
- capacityrequired
- integer | null · A class's seats for these times; null uses the class's
- ends_on
- string | null · A repeat's last local date, that day included; null repeats on
- made_untilrequired
- string · Its sessions exist through this local date; repeats are kept about a year ahead
- teacher
- object | null · Who teaches it; null for nobody
- created_atrequired
- string · ISO 8601 timestamp (UTC)
DELETE/series/{id}series_delete
Remove an entry and its future times; past ones stay on record. If any is booked, pass cancel_bookings: true: they're cancelled and their guests emailed. Returns { cancelled }.
Request2
- idpathrequired
- string · uuid
- cancel_bookingsquery
- boolean · Required when any of its future times is booked; otherwise the delete answers 409
Response 2001
- cancelledrequired
- integer · Booked times cancelled
Sessions
GET/sessionssessions_list
List sessions, the times on a class's calendar (or a calendar appointment's), with what's booked in each and who teaches it
Request4
- offering_idquery
- string · uuid
- fromquery
- string · ISO 8601 instant, e.g. 2026-10-03T15:00:00Z
- toquery
- string · ISO 8601 instant, e.g. 2026-10-03T15:00:00Z
- statusquery
- scheduled | cancelled
Response 20013
- datarequired
- object[]
- data[].idrequired
- string
- data[].org_idrequired
- string
- data[].offering_idrequired
- string
- data[].starts_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].ends_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].capacityrequired
- integer | null · Seats for this session; null means the class's capacity
- data[].statusrequired
- scheduled | cancelled
- data[].series_id
- string | null · The calendar entry it's a time of; null when scheduled on its own
- data[].occurs_on
- string | null · Its entry's local date for it
- data[].teacher
- object | null · Who teaches it; null for nobody
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].bookedrequired
- integer · Seats booked in a class; bookings at the time in an appointment
POST/sessionssessions_create
Schedule a class session; repeat_weeks repeats it weekly at the same local time
Request6
- offering_idrequired
- string · uuid
- starts_atrequired
- string · ISO 8601 instant, e.g. 2026-10-03T15:00:00Z
- ends_at
- string · When it ends, each weekly repeat as long; without it, the class's length after starts_at
- repeat_weeks
- integer · 1–52
- capacity
- integer | null · Override the class's seats
- teacher
- string | null · Who teaches it: a member's user id (Settings → Team); null for nobody. Anyone not on your team answers 400 not_a_member
Response 20112
- datarequired
- object[]
- data[].idrequired
- string
- data[].org_idrequired
- string
- data[].offering_idrequired
- string
- data[].starts_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].ends_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].capacityrequired
- integer | null · Seats for this session; null means the class's capacity
- data[].statusrequired
- scheduled | cancelled
- data[].series_id
- string | null · The calendar entry it's a time of; null when scheduled on its own
- data[].occurs_on
- string | null · Its entry's local date for it
- data[].teacher
- object | null · Who teaches it; null for nobody
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
PATCH/sessions/{id}sessions_update
Move one time nobody has booked (starts_at and ends_at together), or change who teaches it (teacher); its calendar entry's other times stay. A booked one can't move, only be cancelled, but its teacher can change.
Request4
- idpathrequired
- string · uuid
- starts_at
- string · ISO 8601 instant, e.g. 2026-10-03T15:00:00Z
- ends_at
- string · ISO 8601 instant, e.g. 2026-10-03T15:00:00Z
- teacher
- string | null · Who teaches it: a member's user id (Settings → Team); null for nobody. Anyone not on your team answers 400 not_a_member
Response 20011
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- capacityrequired
- integer | null · Seats for this session; null means the class's capacity
- statusrequired
- scheduled | cancelled
- series_id
- string | null · The calendar entry it's a time of; null when scheduled on its own
- occurs_on
- string | null · Its entry's local date for it
- teacher
- object | null · Who teaches it; null for nobody
- created_atrequired
- string · ISO 8601 timestamp (UTC)
POST/sessions/{id}/cancelsessions_cancel
Cancel one time and every booking in it; its guests are emailed. With guests: choose, each guest picks another time of the offering (or a refund) on their booking page within 7 days instead. On a time already called off, guests: refund cancels and refunds whoever is still picking; again, it changes nothing
Request3
- idpathrequired
- string · uuid
- guests
- refund | choose · refund (default): cancel every booking, refunding what was paid online. choose: holds and a reseller's bookings are cancelled; each other booking stays confirmed with choose_by, the end of the 7th day in the org's time zone, while its guest picks another time of the offering (booking.moved) or cancels. Whoever hasn't picked by then is cancelled, refunding what they paid online
- note
- string · ≤ 200 chars · A line in your words for the guests' email, such as why the time can't run
Response 20011
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- capacityrequired
- integer | null · Seats for this session; null means the class's capacity
- statusrequired
- scheduled | cancelled
- series_id
- string | null · The calendar entry it's a time of; null when scheduled on its own
- occurs_on
- string | null · Its entry's local date for it
- teacher
- object | null · Who teaches it; null for nobody
- created_atrequired
- string · ISO 8601 timestamp (UTC)
Bookings
GET/bookingsbookings_list
List bookings filtered by time range, status, offering, customer, session or reference, soonest first (order=desc for newest first); q searches a guest's name or email, or a reference. Page with after=<next_after>.
Request11
- fromquery
- string · ISO 8601 instant, e.g. 2026-10-03T15:00:00Z
- toquery
- string · ISO 8601 instant, e.g. 2026-10-03T15:00:00Z
- statusquery
- held | confirmed | cancelled
- offering_idquery
- string · uuid
- customer_idquery
- string · uuid
- session_idquery
- string · uuid
- referencequery
- string · ≤ 40 chars · The booking's reference as the guest reads it, e.g. 0GWYRZ2V (any case)
- qquery
- string · ≤ 80 chars · Any part of a guest's name or email, in any case, or a booking's reference
- orderquery
- asc | desc
- limitquery
- integer · 1–500
- afterquery
- string · uuid · A booking's id: the page continues with those after it, in the same order (pass next_after)
Response 20067
- datarequired
- object[]
- data[].idrequired
- string
- data[].org_idrequired
- string
- data[].offering_idrequired
- string
- data[].session_idrequired
- string | null · Classes only; a course's, the first time it was booked from
- data[].series_id
- string | null · A course's booking: the calendar entry it holds a seat in every time of, from session_id's on. Null for a booking of one time
- data[].customer_idrequired
- string
- data[].starts_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].ends_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].quantityrequired
- integer · class: seats · appointment: people, 1 for one-on-one · rental: items
- data[].total_centsrequired
- integer · In the org's currency, in the currency's minor units (cents; whole yen for zero-decimal currencies): what's left to pay after a promo code
- data[].promo_code
- string | null · The promo code it was booked with, as stored; kept after the code is deleted. Null without one
- data[].discount_cents
- integer · What the promo code took off, in the currency's minor units (cents; whole yen for zero-decimal currencies); 0 without one
- data[].gift_card_id
- string | null · The gift card that paid part of it (gift_cards_get); null without one
- data[].gift_cents
- integer · What the gift card paid, in the currency's minor units (cents; whole yen for zero-decimal currencies), counted as paid: taken off the card once the booking is confirmed, back on it if it's cancelled; 0 without one
- data[].referencerequired
- string · Short code the guest sees, e.g. 0GWYRZ2V
- data[].statusrequired
- held | confirmed | cancelled · held, confirmed or cancelled; a hold keeps its place until expires_at
- data[].sourcerequired
- string · Where it was made: dashboard, api, mcp, widget, octo (a reseller, over /api/octo), or assistant (held for a guest over /api/mcp/book/{slug}, who confirms it)
- data[].notesrequired
- string
- data[].answers
- object · The guest's answers to its offering's questions, keyed by question id: text (a choice's option, as listed), or true or false for a yes or no
- data[].metadatarequired
- any · Free-form JSON object for your own integrations
- data[].cancelled_atrequired
- string | null · ISO 8601 timestamp (UTC)
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].expires_atrequired
- string | null · Held bookings: when the hold stops keeping its place
- data[].handlerequired
- string · Opens the guest's own page, /b/{handle}: their messages, bookings and cancel. daybooked sends it only to the guest's email; never give it to whoever is booking, who may have typed someone else's email. bookings.resend emails it to the guest again
- data[].checkout_urlrequired
- string | null · Stripe Checkout for a hold being paid online
- data[].paid_atrequired
- string | null · When it was paid: online, or marked paid by hand (then payment_intent_id is null)
- data[].paid_cents
- integer | null · What's been paid so far, online and by hand, in the currency's minor units (cents; whole yen for zero-decimal currencies): less than total_cents after a deposit, the rest due at the start. Null on bookings from before deposits: the whole total once paid_at is set
- data[].payment_intent_idrequired
- string | null · The Stripe payment, when paid online
- data[].charged_cents
- integer | null · What its Stripe Checkout charged, a deposit or the whole total, in the currency's minor units (cents; whole yen for zero-decimal currencies): all that cancelling can refund. Null when not paid online, and on bookings from before deposits (the whole total)
- data[].refund_idrequired
- string | null · The Stripe refund of a payment made online, once Stripe took it (cancelling refunds in full, unless refund_cents says otherwise)
- data[].refund_cents
- integer | null · What cancelling refunds of a payment made online, as bookings.cancel's refund chose, in the currency's minor units (cents; whole yen for zero-decimal currencies): null the whole payment, 0 none (the business kept it), otherwise that part
- data[].refunded_atrequired
- string | null · When Stripe confirmed the refund; until then it's on its way
- data[].refund_failed_atrequired
- string | null · When the last try at the refund failed
- data[].refund_errorrequired
- string | null · Why the refund failed, as Stripe said
- data[].refund_next_atrequired
- string | null · When daybooked next looks at the refund (a pending one, or another try); null once refunded or failed for good
- data[].guest_cancel_hours
- integer | null · The window promised when it was booked: the guest may cancel on their page, or change its time, until this many hours before the start (or by the org's rule now, if kinder)
- data[].nudged_at
- string | null · When the guest of this lapsed, unpaid hold was emailed a link to finish booking (bookings_nudge), which goes once
- data[].choose_by
- string | null · Its time was called off with sessions_cancel and guests: "choose": it stays confirmed, holding no place, while its guest picks another time (bookings move it) or takes the refund, until the end of this day in the org's time zone. Past it, it is cancelled, refunding what was paid online. Null otherwise, and once it is cancelled
- data[].waiver_token
- string | null · When its offering asks guests to sign your waiver: the signing link for everyone on the booking, /w/{waiver_token}. It only lets someone sign
- data[].waiver
- object | null · bookings.get and bookings.list: how many signatures of your waiver it needs and has; null when its offering doesn't ask, or it's cancelled or a lapsed hold
- data[].confirmed_at
- string | null · When it was confirmed; null while held, and on bookings older than this field
- data[].updated_at
- string | null · When it last changed; null on bookings older than this field
- data[].reseller_reference
- string | null · A reseller's own reference for a booking it made over OCTO
- data[].cancel_reason
- string | null · Why a reseller cancelled it, in its words
- data[].checked_in_at
- string | null · When the guest was checked in at the door (a rental's guest: picked up), by hand on the roster or with bookings_set_attendance; null otherwise
- data[].no_show_at
- string | null · When it was marked a no-show, once its time had started; never set together with checked_in_at
- data[].previous
- object · bookings.move: where the booking was
- data[].previous.starts_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].previous.ends_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].previous.session_idrequired
- string | null
- data[].offeringrequired
- object
- data[].offering.idrequired
- string
- data[].offering.namerequired
- string
- data[].offering.kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- data[].offering.questions
- object[] · bookings.get and bookings.list: its questions, which answers answers by id
- data[].offering.questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- data[].offering.questions[].labelrequired
- string · The question as guests read it
- data[].offering.questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- data[].offering.questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- data[].offering.questions[].requiredrequired
- boolean · Guests must answer it to book online
- data[].customerrequired
- object
- data[].customer.idrequired
- string
- data[].customer.namerequired
- string
- data[].customer.emailrequired
- string
- data[].customer.phonerequired
- string
- next_afterrequired
- string | null · Pass as after= for the next page; null after the last
GET/bookings/{id}bookings_get
Get one booking with its offering and customer, and how its waiver stands
Request1
- idpathrequired
- string · uuid
Response 20065
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- session_idrequired
- string | null · Classes only; a course's, the first time it was booked from
- series_id
- string | null · A course's booking: the calendar entry it holds a seat in every time of, from session_id's on. Null for a booking of one time
- customer_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- quantityrequired
- integer · class: seats · appointment: people, 1 for one-on-one · rental: items
- total_centsrequired
- integer · In the org's currency, in the currency's minor units (cents; whole yen for zero-decimal currencies): what's left to pay after a promo code
- promo_code
- string | null · The promo code it was booked with, as stored; kept after the code is deleted. Null without one
- discount_cents
- integer · What the promo code took off, in the currency's minor units (cents; whole yen for zero-decimal currencies); 0 without one
- gift_card_id
- string | null · The gift card that paid part of it (gift_cards_get); null without one
- gift_cents
- integer · What the gift card paid, in the currency's minor units (cents; whole yen for zero-decimal currencies), counted as paid: taken off the card once the booking is confirmed, back on it if it's cancelled; 0 without one
- referencerequired
- string · Short code the guest sees, e.g. 0GWYRZ2V
- statusrequired
- held | confirmed | cancelled · held, confirmed or cancelled; a hold keeps its place until expires_at
- sourcerequired
- string · Where it was made: dashboard, api, mcp, widget, octo (a reseller, over /api/octo), or assistant (held for a guest over /api/mcp/book/{slug}, who confirms it)
- notesrequired
- string
- answers
- object · The guest's answers to its offering's questions, keyed by question id: text (a choice's option, as listed), or true or false for a yes or no
- metadatarequired
- any · Free-form JSON object for your own integrations
- cancelled_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- expires_atrequired
- string | null · Held bookings: when the hold stops keeping its place
- handlerequired
- string · Opens the guest's own page, /b/{handle}: their messages, bookings and cancel. daybooked sends it only to the guest's email; never give it to whoever is booking, who may have typed someone else's email. bookings.resend emails it to the guest again
- checkout_urlrequired
- string | null · Stripe Checkout for a hold being paid online
- paid_atrequired
- string | null · When it was paid: online, or marked paid by hand (then payment_intent_id is null)
- paid_cents
- integer | null · What's been paid so far, online and by hand, in the currency's minor units (cents; whole yen for zero-decimal currencies): less than total_cents after a deposit, the rest due at the start. Null on bookings from before deposits: the whole total once paid_at is set
- payment_intent_idrequired
- string | null · The Stripe payment, when paid online
- charged_cents
- integer | null · What its Stripe Checkout charged, a deposit or the whole total, in the currency's minor units (cents; whole yen for zero-decimal currencies): all that cancelling can refund. Null when not paid online, and on bookings from before deposits (the whole total)
- refund_idrequired
- string | null · The Stripe refund of a payment made online, once Stripe took it (cancelling refunds in full, unless refund_cents says otherwise)
- refund_cents
- integer | null · What cancelling refunds of a payment made online, as bookings.cancel's refund chose, in the currency's minor units (cents; whole yen for zero-decimal currencies): null the whole payment, 0 none (the business kept it), otherwise that part
- refunded_atrequired
- string | null · When Stripe confirmed the refund; until then it's on its way
- refund_failed_atrequired
- string | null · When the last try at the refund failed
- refund_errorrequired
- string | null · Why the refund failed, as Stripe said
- refund_next_atrequired
- string | null · When daybooked next looks at the refund (a pending one, or another try); null once refunded or failed for good
- guest_cancel_hours
- integer | null · The window promised when it was booked: the guest may cancel on their page, or change its time, until this many hours before the start (or by the org's rule now, if kinder)
- nudged_at
- string | null · When the guest of this lapsed, unpaid hold was emailed a link to finish booking (bookings_nudge), which goes once
- choose_by
- string | null · Its time was called off with sessions_cancel and guests: "choose": it stays confirmed, holding no place, while its guest picks another time (bookings move it) or takes the refund, until the end of this day in the org's time zone. Past it, it is cancelled, refunding what was paid online. Null otherwise, and once it is cancelled
- waiver_token
- string | null · When its offering asks guests to sign your waiver: the signing link for everyone on the booking, /w/{waiver_token}. It only lets someone sign
- waiver
- object | null · bookings.get and bookings.list: how many signatures of your waiver it needs and has; null when its offering doesn't ask, or it's cancelled or a lapsed hold
- confirmed_at
- string | null · When it was confirmed; null while held, and on bookings older than this field
- updated_at
- string | null · When it last changed; null on bookings older than this field
- reseller_reference
- string | null · A reseller's own reference for a booking it made over OCTO
- cancel_reason
- string | null · Why a reseller cancelled it, in its words
- checked_in_at
- string | null · When the guest was checked in at the door (a rental's guest: picked up), by hand on the roster or with bookings_set_attendance; null otherwise
- no_show_at
- string | null · When it was marked a no-show, once its time had started; never set together with checked_in_at
- previous
- object · bookings.move: where the booking was
- previous.starts_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.ends_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.session_idrequired
- string | null
- offeringrequired
- object
- offering.idrequired
- string
- offering.namerequired
- string
- offering.kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- offering.questions
- object[] · bookings.get and bookings.list: its questions, which answers answers by id
- offering.questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- offering.questions[].labelrequired
- string · The question as guests read it
- offering.questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- offering.questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- offering.questions[].requiredrequired
- boolean · Guests must answer it to book online
- customerrequired
- object
- customer.idrequired
- string
- customer.namerequired
- string
- customer.emailrequired
- string
- customer.phonerequired
- string
POST/bookingsbookings_create
Book a slot from availability.get (classes need session_id, a course its series_id; appointments and rentals need starts_at). Pass hold_minutes to hold it instead, and idempotency_key so retries never book twice.
Request17
- offering_idrequired
- string · uuid
- session_id
- string · uuid
- series_id
- string · uuid · A course (offering course: true): the entry availability.get gives, booked whole from its first time to come
- starts_at
- string · ISO 8601 instant, e.g. 2026-10-03T15:00:00Z
- quantity
- integer · 1–10000 · class: seats · appointment: people, 1 for one-on-one · rental: items
- periods
- integer · 1–60 · Rentals: how many periods (e.g. days)
- customer_id
- string · uuid
- customer
- object · Matched by email; created if new
- customer.emailrequired
- string · email
- customer.name
- string · ≤ 120 chars
- customer.phone
- string · ≤ 40 chars
- notes
- string · ≤ 2000 chars
- answers
- object · Answers to the offering's questions (offerings.get), keyed by each question's id: text, a choice's option exactly as listed, or true/false for yes_no. A required one left out answers 400 answers_required with its question_id
- promo_code
- string · ≤ 20 chars · A promo code the guest gave, in any case: taken off total_cents, or refused with 400 code_invalid, code_expired or code_used_up
- gift_card_code
- string · ≤ 40 chars · A gift card's code the guest gave, in any case, spaced or not: it pays what's due at booking (after promo_code, and the offering's deposit where it asks one), all it has at most, and the booking keeps gift_card_id and gift_cents. Refused with 400 gift_card_invalid or gift_card_empty, or 409 gift_card_short when its balance moved
- hold_minutes
- integer · 5–1440 · Hold the place this many minutes (status held) instead of confirming; then call bookings.confirm
- idempotency_key
- string · uuid · A UUID you generate per booking: retrying with it returns the same booking instead of booking twice
Response 20165
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- session_idrequired
- string | null · Classes only; a course's, the first time it was booked from
- series_id
- string | null · A course's booking: the calendar entry it holds a seat in every time of, from session_id's on. Null for a booking of one time
- customer_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- quantityrequired
- integer · class: seats · appointment: people, 1 for one-on-one · rental: items
- total_centsrequired
- integer · In the org's currency, in the currency's minor units (cents; whole yen for zero-decimal currencies): what's left to pay after a promo code
- promo_code
- string | null · The promo code it was booked with, as stored; kept after the code is deleted. Null without one
- discount_cents
- integer · What the promo code took off, in the currency's minor units (cents; whole yen for zero-decimal currencies); 0 without one
- gift_card_id
- string | null · The gift card that paid part of it (gift_cards_get); null without one
- gift_cents
- integer · What the gift card paid, in the currency's minor units (cents; whole yen for zero-decimal currencies), counted as paid: taken off the card once the booking is confirmed, back on it if it's cancelled; 0 without one
- referencerequired
- string · Short code the guest sees, e.g. 0GWYRZ2V
- statusrequired
- held | confirmed | cancelled · held, confirmed or cancelled; a hold keeps its place until expires_at
- sourcerequired
- string · Where it was made: dashboard, api, mcp, widget, octo (a reseller, over /api/octo), or assistant (held for a guest over /api/mcp/book/{slug}, who confirms it)
- notesrequired
- string
- answers
- object · The guest's answers to its offering's questions, keyed by question id: text (a choice's option, as listed), or true or false for a yes or no
- metadatarequired
- any · Free-form JSON object for your own integrations
- cancelled_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- expires_atrequired
- string | null · Held bookings: when the hold stops keeping its place
- handlerequired
- string · Opens the guest's own page, /b/{handle}: their messages, bookings and cancel. daybooked sends it only to the guest's email; never give it to whoever is booking, who may have typed someone else's email. bookings.resend emails it to the guest again
- checkout_urlrequired
- string | null · Stripe Checkout for a hold being paid online
- paid_atrequired
- string | null · When it was paid: online, or marked paid by hand (then payment_intent_id is null)
- paid_cents
- integer | null · What's been paid so far, online and by hand, in the currency's minor units (cents; whole yen for zero-decimal currencies): less than total_cents after a deposit, the rest due at the start. Null on bookings from before deposits: the whole total once paid_at is set
- payment_intent_idrequired
- string | null · The Stripe payment, when paid online
- charged_cents
- integer | null · What its Stripe Checkout charged, a deposit or the whole total, in the currency's minor units (cents; whole yen for zero-decimal currencies): all that cancelling can refund. Null when not paid online, and on bookings from before deposits (the whole total)
- refund_idrequired
- string | null · The Stripe refund of a payment made online, once Stripe took it (cancelling refunds in full, unless refund_cents says otherwise)
- refund_cents
- integer | null · What cancelling refunds of a payment made online, as bookings.cancel's refund chose, in the currency's minor units (cents; whole yen for zero-decimal currencies): null the whole payment, 0 none (the business kept it), otherwise that part
- refunded_atrequired
- string | null · When Stripe confirmed the refund; until then it's on its way
- refund_failed_atrequired
- string | null · When the last try at the refund failed
- refund_errorrequired
- string | null · Why the refund failed, as Stripe said
- refund_next_atrequired
- string | null · When daybooked next looks at the refund (a pending one, or another try); null once refunded or failed for good
- guest_cancel_hours
- integer | null · The window promised when it was booked: the guest may cancel on their page, or change its time, until this many hours before the start (or by the org's rule now, if kinder)
- nudged_at
- string | null · When the guest of this lapsed, unpaid hold was emailed a link to finish booking (bookings_nudge), which goes once
- choose_by
- string | null · Its time was called off with sessions_cancel and guests: "choose": it stays confirmed, holding no place, while its guest picks another time (bookings move it) or takes the refund, until the end of this day in the org's time zone. Past it, it is cancelled, refunding what was paid online. Null otherwise, and once it is cancelled
- waiver_token
- string | null · When its offering asks guests to sign your waiver: the signing link for everyone on the booking, /w/{waiver_token}. It only lets someone sign
- waiver
- object | null · bookings.get and bookings.list: how many signatures of your waiver it needs and has; null when its offering doesn't ask, or it's cancelled or a lapsed hold
- confirmed_at
- string | null · When it was confirmed; null while held, and on bookings older than this field
- updated_at
- string | null · When it last changed; null on bookings older than this field
- reseller_reference
- string | null · A reseller's own reference for a booking it made over OCTO
- cancel_reason
- string | null · Why a reseller cancelled it, in its words
- checked_in_at
- string | null · When the guest was checked in at the door (a rental's guest: picked up), by hand on the roster or with bookings_set_attendance; null otherwise
- no_show_at
- string | null · When it was marked a no-show, once its time had started; never set together with checked_in_at
- previous
- object · bookings.move: where the booking was
- previous.starts_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.ends_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.session_idrequired
- string | null
- offeringrequired
- object
- offering.idrequired
- string
- offering.namerequired
- string
- offering.kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- offering.questions
- object[] · bookings.get and bookings.list: its questions, which answers answers by id
- offering.questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- offering.questions[].labelrequired
- string · The question as guests read it
- offering.questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- offering.questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- offering.questions[].requiredrequired
- boolean · Guests must answer it to book online
- customerrequired
- object
- customer.idrequired
- string
- customer.namerequired
- string
- customer.emailrequired
- string
- customer.phonerequired
- string
POST/bookings/{id}/cancelbookings_cancel
Cancel a booking or a hold and free its capacity; the guest is emailed. A payment made online (a deposit, or the whole total: charged_cents) is refunded in full, or as refund says: none, or a part (more than was paid online: 400 refund_too_large). Safe to repeat: a booking already cancelled keeps its first choice
Request2
- idpathrequired
- string · uuid
- refund
- full | none | object · For a booking paid online: "full" (the default) refunds the whole payment, "none" keeps it, { amount_cents } refunds that part. Recorded as refund_cents. A booking not paid online ignores it
Response 20065
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- session_idrequired
- string | null · Classes only; a course's, the first time it was booked from
- series_id
- string | null · A course's booking: the calendar entry it holds a seat in every time of, from session_id's on. Null for a booking of one time
- customer_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- quantityrequired
- integer · class: seats · appointment: people, 1 for one-on-one · rental: items
- total_centsrequired
- integer · In the org's currency, in the currency's minor units (cents; whole yen for zero-decimal currencies): what's left to pay after a promo code
- promo_code
- string | null · The promo code it was booked with, as stored; kept after the code is deleted. Null without one
- discount_cents
- integer · What the promo code took off, in the currency's minor units (cents; whole yen for zero-decimal currencies); 0 without one
- gift_card_id
- string | null · The gift card that paid part of it (gift_cards_get); null without one
- gift_cents
- integer · What the gift card paid, in the currency's minor units (cents; whole yen for zero-decimal currencies), counted as paid: taken off the card once the booking is confirmed, back on it if it's cancelled; 0 without one
- referencerequired
- string · Short code the guest sees, e.g. 0GWYRZ2V
- statusrequired
- held | confirmed | cancelled · held, confirmed or cancelled; a hold keeps its place until expires_at
- sourcerequired
- string · Where it was made: dashboard, api, mcp, widget, octo (a reseller, over /api/octo), or assistant (held for a guest over /api/mcp/book/{slug}, who confirms it)
- notesrequired
- string
- answers
- object · The guest's answers to its offering's questions, keyed by question id: text (a choice's option, as listed), or true or false for a yes or no
- metadatarequired
- any · Free-form JSON object for your own integrations
- cancelled_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- expires_atrequired
- string | null · Held bookings: when the hold stops keeping its place
- handlerequired
- string · Opens the guest's own page, /b/{handle}: their messages, bookings and cancel. daybooked sends it only to the guest's email; never give it to whoever is booking, who may have typed someone else's email. bookings.resend emails it to the guest again
- checkout_urlrequired
- string | null · Stripe Checkout for a hold being paid online
- paid_atrequired
- string | null · When it was paid: online, or marked paid by hand (then payment_intent_id is null)
- paid_cents
- integer | null · What's been paid so far, online and by hand, in the currency's minor units (cents; whole yen for zero-decimal currencies): less than total_cents after a deposit, the rest due at the start. Null on bookings from before deposits: the whole total once paid_at is set
- payment_intent_idrequired
- string | null · The Stripe payment, when paid online
- charged_cents
- integer | null · What its Stripe Checkout charged, a deposit or the whole total, in the currency's minor units (cents; whole yen for zero-decimal currencies): all that cancelling can refund. Null when not paid online, and on bookings from before deposits (the whole total)
- refund_idrequired
- string | null · The Stripe refund of a payment made online, once Stripe took it (cancelling refunds in full, unless refund_cents says otherwise)
- refund_cents
- integer | null · What cancelling refunds of a payment made online, as bookings.cancel's refund chose, in the currency's minor units (cents; whole yen for zero-decimal currencies): null the whole payment, 0 none (the business kept it), otherwise that part
- refunded_atrequired
- string | null · When Stripe confirmed the refund; until then it's on its way
- refund_failed_atrequired
- string | null · When the last try at the refund failed
- refund_errorrequired
- string | null · Why the refund failed, as Stripe said
- refund_next_atrequired
- string | null · When daybooked next looks at the refund (a pending one, or another try); null once refunded or failed for good
- guest_cancel_hours
- integer | null · The window promised when it was booked: the guest may cancel on their page, or change its time, until this many hours before the start (or by the org's rule now, if kinder)
- nudged_at
- string | null · When the guest of this lapsed, unpaid hold was emailed a link to finish booking (bookings_nudge), which goes once
- choose_by
- string | null · Its time was called off with sessions_cancel and guests: "choose": it stays confirmed, holding no place, while its guest picks another time (bookings move it) or takes the refund, until the end of this day in the org's time zone. Past it, it is cancelled, refunding what was paid online. Null otherwise, and once it is cancelled
- waiver_token
- string | null · When its offering asks guests to sign your waiver: the signing link for everyone on the booking, /w/{waiver_token}. It only lets someone sign
- waiver
- object | null · bookings.get and bookings.list: how many signatures of your waiver it needs and has; null when its offering doesn't ask, or it's cancelled or a lapsed hold
- confirmed_at
- string | null · When it was confirmed; null while held, and on bookings older than this field
- updated_at
- string | null · When it last changed; null on bookings older than this field
- reseller_reference
- string | null · A reseller's own reference for a booking it made over OCTO
- cancel_reason
- string | null · Why a reseller cancelled it, in its words
- checked_in_at
- string | null · When the guest was checked in at the door (a rental's guest: picked up), by hand on the roster or with bookings_set_attendance; null otherwise
- no_show_at
- string | null · When it was marked a no-show, once its time had started; never set together with checked_in_at
- previous
- object · bookings.move: where the booking was
- previous.starts_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.ends_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.session_idrequired
- string | null
- offeringrequired
- object
- offering.idrequired
- string
- offering.namerequired
- string
- offering.kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- offering.questions
- object[] · bookings.get and bookings.list: its questions, which answers answers by id
- offering.questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- offering.questions[].labelrequired
- string · The question as guests read it
- offering.questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- offering.questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- offering.questions[].requiredrequired
- boolean · Guests must answer it to book online
- customerrequired
- object
- customer.idrequired
- string
- customer.namerequired
- string
- customer.emailrequired
- string
- customer.phonerequired
- string
POST/bookings/{id}/confirmbookings_confirm
Confirm a held booking (safe to repeat). A hold past its expires_at confirms only if its place is still free.
Request1
- idpathrequired
- string · uuid
Response 20065
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- session_idrequired
- string | null · Classes only; a course's, the first time it was booked from
- series_id
- string | null · A course's booking: the calendar entry it holds a seat in every time of, from session_id's on. Null for a booking of one time
- customer_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- quantityrequired
- integer · class: seats · appointment: people, 1 for one-on-one · rental: items
- total_centsrequired
- integer · In the org's currency, in the currency's minor units (cents; whole yen for zero-decimal currencies): what's left to pay after a promo code
- promo_code
- string | null · The promo code it was booked with, as stored; kept after the code is deleted. Null without one
- discount_cents
- integer · What the promo code took off, in the currency's minor units (cents; whole yen for zero-decimal currencies); 0 without one
- gift_card_id
- string | null · The gift card that paid part of it (gift_cards_get); null without one
- gift_cents
- integer · What the gift card paid, in the currency's minor units (cents; whole yen for zero-decimal currencies), counted as paid: taken off the card once the booking is confirmed, back on it if it's cancelled; 0 without one
- referencerequired
- string · Short code the guest sees, e.g. 0GWYRZ2V
- statusrequired
- held | confirmed | cancelled · held, confirmed or cancelled; a hold keeps its place until expires_at
- sourcerequired
- string · Where it was made: dashboard, api, mcp, widget, octo (a reseller, over /api/octo), or assistant (held for a guest over /api/mcp/book/{slug}, who confirms it)
- notesrequired
- string
- answers
- object · The guest's answers to its offering's questions, keyed by question id: text (a choice's option, as listed), or true or false for a yes or no
- metadatarequired
- any · Free-form JSON object for your own integrations
- cancelled_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- expires_atrequired
- string | null · Held bookings: when the hold stops keeping its place
- handlerequired
- string · Opens the guest's own page, /b/{handle}: their messages, bookings and cancel. daybooked sends it only to the guest's email; never give it to whoever is booking, who may have typed someone else's email. bookings.resend emails it to the guest again
- checkout_urlrequired
- string | null · Stripe Checkout for a hold being paid online
- paid_atrequired
- string | null · When it was paid: online, or marked paid by hand (then payment_intent_id is null)
- paid_cents
- integer | null · What's been paid so far, online and by hand, in the currency's minor units (cents; whole yen for zero-decimal currencies): less than total_cents after a deposit, the rest due at the start. Null on bookings from before deposits: the whole total once paid_at is set
- payment_intent_idrequired
- string | null · The Stripe payment, when paid online
- charged_cents
- integer | null · What its Stripe Checkout charged, a deposit or the whole total, in the currency's minor units (cents; whole yen for zero-decimal currencies): all that cancelling can refund. Null when not paid online, and on bookings from before deposits (the whole total)
- refund_idrequired
- string | null · The Stripe refund of a payment made online, once Stripe took it (cancelling refunds in full, unless refund_cents says otherwise)
- refund_cents
- integer | null · What cancelling refunds of a payment made online, as bookings.cancel's refund chose, in the currency's minor units (cents; whole yen for zero-decimal currencies): null the whole payment, 0 none (the business kept it), otherwise that part
- refunded_atrequired
- string | null · When Stripe confirmed the refund; until then it's on its way
- refund_failed_atrequired
- string | null · When the last try at the refund failed
- refund_errorrequired
- string | null · Why the refund failed, as Stripe said
- refund_next_atrequired
- string | null · When daybooked next looks at the refund (a pending one, or another try); null once refunded or failed for good
- guest_cancel_hours
- integer | null · The window promised when it was booked: the guest may cancel on their page, or change its time, until this many hours before the start (or by the org's rule now, if kinder)
- nudged_at
- string | null · When the guest of this lapsed, unpaid hold was emailed a link to finish booking (bookings_nudge), which goes once
- choose_by
- string | null · Its time was called off with sessions_cancel and guests: "choose": it stays confirmed, holding no place, while its guest picks another time (bookings move it) or takes the refund, until the end of this day in the org's time zone. Past it, it is cancelled, refunding what was paid online. Null otherwise, and once it is cancelled
- waiver_token
- string | null · When its offering asks guests to sign your waiver: the signing link for everyone on the booking, /w/{waiver_token}. It only lets someone sign
- waiver
- object | null · bookings.get and bookings.list: how many signatures of your waiver it needs and has; null when its offering doesn't ask, or it's cancelled or a lapsed hold
- confirmed_at
- string | null · When it was confirmed; null while held, and on bookings older than this field
- updated_at
- string | null · When it last changed; null on bookings older than this field
- reseller_reference
- string | null · A reseller's own reference for a booking it made over OCTO
- cancel_reason
- string | null · Why a reseller cancelled it, in its words
- checked_in_at
- string | null · When the guest was checked in at the door (a rental's guest: picked up), by hand on the roster or with bookings_set_attendance; null otherwise
- no_show_at
- string | null · When it was marked a no-show, once its time had started; never set together with checked_in_at
- previous
- object · bookings.move: where the booking was
- previous.starts_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.ends_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.session_idrequired
- string | null
- offeringrequired
- object
- offering.idrequired
- string
- offering.namerequired
- string
- offering.kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- offering.questions
- object[] · bookings.get and bookings.list: its questions, which answers answers by id
- offering.questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- offering.questions[].labelrequired
- string · The question as guests read it
- offering.questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- offering.questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- offering.questions[].requiredrequired
- boolean · Guests must answer it to book online
- customerrequired
- object
- customer.idrequired
- string
- customer.namerequired
- string
- customer.emailrequired
- string
- customer.phonerequired
- string
POST/bookings/{id}/movebookings_move
Move a booking or a hold to another time of the same offering (classes: session_id; appointments and rentals: starts_at from availability.get). It keeps its reference, price and payment, the guest gets one email, and moving it to its current time changes nothing.
Request3
- idpathrequired
- string · uuid
- session_id
- string · uuid · Classes: the session to move to
- starts_at
- string · Appointments and rentals: the new start; the booking keeps its length
Response 20065
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- session_idrequired
- string | null · Classes only; a course's, the first time it was booked from
- series_id
- string | null · A course's booking: the calendar entry it holds a seat in every time of, from session_id's on. Null for a booking of one time
- customer_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- quantityrequired
- integer · class: seats · appointment: people, 1 for one-on-one · rental: items
- total_centsrequired
- integer · In the org's currency, in the currency's minor units (cents; whole yen for zero-decimal currencies): what's left to pay after a promo code
- promo_code
- string | null · The promo code it was booked with, as stored; kept after the code is deleted. Null without one
- discount_cents
- integer · What the promo code took off, in the currency's minor units (cents; whole yen for zero-decimal currencies); 0 without one
- gift_card_id
- string | null · The gift card that paid part of it (gift_cards_get); null without one
- gift_cents
- integer · What the gift card paid, in the currency's minor units (cents; whole yen for zero-decimal currencies), counted as paid: taken off the card once the booking is confirmed, back on it if it's cancelled; 0 without one
- referencerequired
- string · Short code the guest sees, e.g. 0GWYRZ2V
- statusrequired
- held | confirmed | cancelled · held, confirmed or cancelled; a hold keeps its place until expires_at
- sourcerequired
- string · Where it was made: dashboard, api, mcp, widget, octo (a reseller, over /api/octo), or assistant (held for a guest over /api/mcp/book/{slug}, who confirms it)
- notesrequired
- string
- answers
- object · The guest's answers to its offering's questions, keyed by question id: text (a choice's option, as listed), or true or false for a yes or no
- metadatarequired
- any · Free-form JSON object for your own integrations
- cancelled_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- expires_atrequired
- string | null · Held bookings: when the hold stops keeping its place
- handlerequired
- string · Opens the guest's own page, /b/{handle}: their messages, bookings and cancel. daybooked sends it only to the guest's email; never give it to whoever is booking, who may have typed someone else's email. bookings.resend emails it to the guest again
- checkout_urlrequired
- string | null · Stripe Checkout for a hold being paid online
- paid_atrequired
- string | null · When it was paid: online, or marked paid by hand (then payment_intent_id is null)
- paid_cents
- integer | null · What's been paid so far, online and by hand, in the currency's minor units (cents; whole yen for zero-decimal currencies): less than total_cents after a deposit, the rest due at the start. Null on bookings from before deposits: the whole total once paid_at is set
- payment_intent_idrequired
- string | null · The Stripe payment, when paid online
- charged_cents
- integer | null · What its Stripe Checkout charged, a deposit or the whole total, in the currency's minor units (cents; whole yen for zero-decimal currencies): all that cancelling can refund. Null when not paid online, and on bookings from before deposits (the whole total)
- refund_idrequired
- string | null · The Stripe refund of a payment made online, once Stripe took it (cancelling refunds in full, unless refund_cents says otherwise)
- refund_cents
- integer | null · What cancelling refunds of a payment made online, as bookings.cancel's refund chose, in the currency's minor units (cents; whole yen for zero-decimal currencies): null the whole payment, 0 none (the business kept it), otherwise that part
- refunded_atrequired
- string | null · When Stripe confirmed the refund; until then it's on its way
- refund_failed_atrequired
- string | null · When the last try at the refund failed
- refund_errorrequired
- string | null · Why the refund failed, as Stripe said
- refund_next_atrequired
- string | null · When daybooked next looks at the refund (a pending one, or another try); null once refunded or failed for good
- guest_cancel_hours
- integer | null · The window promised when it was booked: the guest may cancel on their page, or change its time, until this many hours before the start (or by the org's rule now, if kinder)
- nudged_at
- string | null · When the guest of this lapsed, unpaid hold was emailed a link to finish booking (bookings_nudge), which goes once
- choose_by
- string | null · Its time was called off with sessions_cancel and guests: "choose": it stays confirmed, holding no place, while its guest picks another time (bookings move it) or takes the refund, until the end of this day in the org's time zone. Past it, it is cancelled, refunding what was paid online. Null otherwise, and once it is cancelled
- waiver_token
- string | null · When its offering asks guests to sign your waiver: the signing link for everyone on the booking, /w/{waiver_token}. It only lets someone sign
- waiver
- object | null · bookings.get and bookings.list: how many signatures of your waiver it needs and has; null when its offering doesn't ask, or it's cancelled or a lapsed hold
- confirmed_at
- string | null · When it was confirmed; null while held, and on bookings older than this field
- updated_at
- string | null · When it last changed; null on bookings older than this field
- reseller_reference
- string | null · A reseller's own reference for a booking it made over OCTO
- cancel_reason
- string | null · Why a reseller cancelled it, in its words
- checked_in_at
- string | null · When the guest was checked in at the door (a rental's guest: picked up), by hand on the roster or with bookings_set_attendance; null otherwise
- no_show_at
- string | null · When it was marked a no-show, once its time had started; never set together with checked_in_at
- previous
- object · bookings.move: where the booking was
- previous.starts_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.ends_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.session_idrequired
- string | null
- offeringrequired
- object
- offering.idrequired
- string
- offering.namerequired
- string
- offering.kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- offering.questions
- object[] · bookings.get and bookings.list: its questions, which answers answers by id
- offering.questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- offering.questions[].labelrequired
- string · The question as guests read it
- offering.questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- offering.questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- offering.questions[].requiredrequired
- boolean · Guests must answer it to book online
- customerrequired
- object
- customer.idrequired
- string
- customer.namerequired
- string
- customer.emailrequired
- string
- customer.phonerequired
- string
POST/bookings/{id}/resendbookings_resend
Email the guest their booking confirmation again, at most once a day (while its time is called off and its guest is picking another, the email asking them to pick); not for held or cancelled bookings
Request1
- idpathrequired
- string · uuid
Response 2001
- okrequired
- true
PUT/bookings/{id}/paidbookings_set_paid
Mark a confirmed booking paid when the money was taken by hand (cash, a card reader), or pass paid false to take that back. It sets paid_at and paid_cents and logs booking.paid or booking.unpaid. After a deposit paid online, it records the rest paid, and paid false takes back only that rest; a payment made online stays as it is. Safe to repeat.
Request2
- idpathrequired
- string · uuid
- paidrequired
- boolean · true: the guest paid the business directly · false: undo that
Response 20065
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- session_idrequired
- string | null · Classes only; a course's, the first time it was booked from
- series_id
- string | null · A course's booking: the calendar entry it holds a seat in every time of, from session_id's on. Null for a booking of one time
- customer_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- quantityrequired
- integer · class: seats · appointment: people, 1 for one-on-one · rental: items
- total_centsrequired
- integer · In the org's currency, in the currency's minor units (cents; whole yen for zero-decimal currencies): what's left to pay after a promo code
- promo_code
- string | null · The promo code it was booked with, as stored; kept after the code is deleted. Null without one
- discount_cents
- integer · What the promo code took off, in the currency's minor units (cents; whole yen for zero-decimal currencies); 0 without one
- gift_card_id
- string | null · The gift card that paid part of it (gift_cards_get); null without one
- gift_cents
- integer · What the gift card paid, in the currency's minor units (cents; whole yen for zero-decimal currencies), counted as paid: taken off the card once the booking is confirmed, back on it if it's cancelled; 0 without one
- referencerequired
- string · Short code the guest sees, e.g. 0GWYRZ2V
- statusrequired
- held | confirmed | cancelled · held, confirmed or cancelled; a hold keeps its place until expires_at
- sourcerequired
- string · Where it was made: dashboard, api, mcp, widget, octo (a reseller, over /api/octo), or assistant (held for a guest over /api/mcp/book/{slug}, who confirms it)
- notesrequired
- string
- answers
- object · The guest's answers to its offering's questions, keyed by question id: text (a choice's option, as listed), or true or false for a yes or no
- metadatarequired
- any · Free-form JSON object for your own integrations
- cancelled_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- expires_atrequired
- string | null · Held bookings: when the hold stops keeping its place
- handlerequired
- string · Opens the guest's own page, /b/{handle}: their messages, bookings and cancel. daybooked sends it only to the guest's email; never give it to whoever is booking, who may have typed someone else's email. bookings.resend emails it to the guest again
- checkout_urlrequired
- string | null · Stripe Checkout for a hold being paid online
- paid_atrequired
- string | null · When it was paid: online, or marked paid by hand (then payment_intent_id is null)
- paid_cents
- integer | null · What's been paid so far, online and by hand, in the currency's minor units (cents; whole yen for zero-decimal currencies): less than total_cents after a deposit, the rest due at the start. Null on bookings from before deposits: the whole total once paid_at is set
- payment_intent_idrequired
- string | null · The Stripe payment, when paid online
- charged_cents
- integer | null · What its Stripe Checkout charged, a deposit or the whole total, in the currency's minor units (cents; whole yen for zero-decimal currencies): all that cancelling can refund. Null when not paid online, and on bookings from before deposits (the whole total)
- refund_idrequired
- string | null · The Stripe refund of a payment made online, once Stripe took it (cancelling refunds in full, unless refund_cents says otherwise)
- refund_cents
- integer | null · What cancelling refunds of a payment made online, as bookings.cancel's refund chose, in the currency's minor units (cents; whole yen for zero-decimal currencies): null the whole payment, 0 none (the business kept it), otherwise that part
- refunded_atrequired
- string | null · When Stripe confirmed the refund; until then it's on its way
- refund_failed_atrequired
- string | null · When the last try at the refund failed
- refund_errorrequired
- string | null · Why the refund failed, as Stripe said
- refund_next_atrequired
- string | null · When daybooked next looks at the refund (a pending one, or another try); null once refunded or failed for good
- guest_cancel_hours
- integer | null · The window promised when it was booked: the guest may cancel on their page, or change its time, until this many hours before the start (or by the org's rule now, if kinder)
- nudged_at
- string | null · When the guest of this lapsed, unpaid hold was emailed a link to finish booking (bookings_nudge), which goes once
- choose_by
- string | null · Its time was called off with sessions_cancel and guests: "choose": it stays confirmed, holding no place, while its guest picks another time (bookings move it) or takes the refund, until the end of this day in the org's time zone. Past it, it is cancelled, refunding what was paid online. Null otherwise, and once it is cancelled
- waiver_token
- string | null · When its offering asks guests to sign your waiver: the signing link for everyone on the booking, /w/{waiver_token}. It only lets someone sign
- waiver
- object | null · bookings.get and bookings.list: how many signatures of your waiver it needs and has; null when its offering doesn't ask, or it's cancelled or a lapsed hold
- confirmed_at
- string | null · When it was confirmed; null while held, and on bookings older than this field
- updated_at
- string | null · When it last changed; null on bookings older than this field
- reseller_reference
- string | null · A reseller's own reference for a booking it made over OCTO
- cancel_reason
- string | null · Why a reseller cancelled it, in its words
- checked_in_at
- string | null · When the guest was checked in at the door (a rental's guest: picked up), by hand on the roster or with bookings_set_attendance; null otherwise
- no_show_at
- string | null · When it was marked a no-show, once its time had started; never set together with checked_in_at
- previous
- object · bookings.move: where the booking was
- previous.starts_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.ends_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.session_idrequired
- string | null
- offeringrequired
- object
- offering.idrequired
- string
- offering.namerequired
- string
- offering.kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- offering.questions
- object[] · bookings.get and bookings.list: its questions, which answers answers by id
- offering.questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- offering.questions[].labelrequired
- string · The question as guests read it
- offering.questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- offering.questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- offering.questions[].requiredrequired
- boolean · Guests must answer it to book online
- customerrequired
- object
- customer.idrequired
- string
- customer.namerequired
- string
- customer.emailrequired
- string
- customer.phonerequired
- string
POST/bookings/{id}/nudgebookings_nudge
Email the guest of a lapsed, unpaid hold a link to finish booking. Once per booking: for a hold made on the booking page whose Stripe Checkout expired unpaid 10 minutes to a day ago, for a time still free, to a guest who hasn't booked since; anything else is refused with 409 not_nudgeable (already_nudged once sent), and 503 unavailable while Stripe can't be asked. It sets nudged_at and logs booking.nudged.
Request1
- idpathrequired
- string · uuid
Response 20065
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- session_idrequired
- string | null · Classes only; a course's, the first time it was booked from
- series_id
- string | null · A course's booking: the calendar entry it holds a seat in every time of, from session_id's on. Null for a booking of one time
- customer_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- quantityrequired
- integer · class: seats · appointment: people, 1 for one-on-one · rental: items
- total_centsrequired
- integer · In the org's currency, in the currency's minor units (cents; whole yen for zero-decimal currencies): what's left to pay after a promo code
- promo_code
- string | null · The promo code it was booked with, as stored; kept after the code is deleted. Null without one
- discount_cents
- integer · What the promo code took off, in the currency's minor units (cents; whole yen for zero-decimal currencies); 0 without one
- gift_card_id
- string | null · The gift card that paid part of it (gift_cards_get); null without one
- gift_cents
- integer · What the gift card paid, in the currency's minor units (cents; whole yen for zero-decimal currencies), counted as paid: taken off the card once the booking is confirmed, back on it if it's cancelled; 0 without one
- referencerequired
- string · Short code the guest sees, e.g. 0GWYRZ2V
- statusrequired
- held | confirmed | cancelled · held, confirmed or cancelled; a hold keeps its place until expires_at
- sourcerequired
- string · Where it was made: dashboard, api, mcp, widget, octo (a reseller, over /api/octo), or assistant (held for a guest over /api/mcp/book/{slug}, who confirms it)
- notesrequired
- string
- answers
- object · The guest's answers to its offering's questions, keyed by question id: text (a choice's option, as listed), or true or false for a yes or no
- metadatarequired
- any · Free-form JSON object for your own integrations
- cancelled_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- expires_atrequired
- string | null · Held bookings: when the hold stops keeping its place
- handlerequired
- string · Opens the guest's own page, /b/{handle}: their messages, bookings and cancel. daybooked sends it only to the guest's email; never give it to whoever is booking, who may have typed someone else's email. bookings.resend emails it to the guest again
- checkout_urlrequired
- string | null · Stripe Checkout for a hold being paid online
- paid_atrequired
- string | null · When it was paid: online, or marked paid by hand (then payment_intent_id is null)
- paid_cents
- integer | null · What's been paid so far, online and by hand, in the currency's minor units (cents; whole yen for zero-decimal currencies): less than total_cents after a deposit, the rest due at the start. Null on bookings from before deposits: the whole total once paid_at is set
- payment_intent_idrequired
- string | null · The Stripe payment, when paid online
- charged_cents
- integer | null · What its Stripe Checkout charged, a deposit or the whole total, in the currency's minor units (cents; whole yen for zero-decimal currencies): all that cancelling can refund. Null when not paid online, and on bookings from before deposits (the whole total)
- refund_idrequired
- string | null · The Stripe refund of a payment made online, once Stripe took it (cancelling refunds in full, unless refund_cents says otherwise)
- refund_cents
- integer | null · What cancelling refunds of a payment made online, as bookings.cancel's refund chose, in the currency's minor units (cents; whole yen for zero-decimal currencies): null the whole payment, 0 none (the business kept it), otherwise that part
- refunded_atrequired
- string | null · When Stripe confirmed the refund; until then it's on its way
- refund_failed_atrequired
- string | null · When the last try at the refund failed
- refund_errorrequired
- string | null · Why the refund failed, as Stripe said
- refund_next_atrequired
- string | null · When daybooked next looks at the refund (a pending one, or another try); null once refunded or failed for good
- guest_cancel_hours
- integer | null · The window promised when it was booked: the guest may cancel on their page, or change its time, until this many hours before the start (or by the org's rule now, if kinder)
- nudged_at
- string | null · When the guest of this lapsed, unpaid hold was emailed a link to finish booking (bookings_nudge), which goes once
- choose_by
- string | null · Its time was called off with sessions_cancel and guests: "choose": it stays confirmed, holding no place, while its guest picks another time (bookings move it) or takes the refund, until the end of this day in the org's time zone. Past it, it is cancelled, refunding what was paid online. Null otherwise, and once it is cancelled
- waiver_token
- string | null · When its offering asks guests to sign your waiver: the signing link for everyone on the booking, /w/{waiver_token}. It only lets someone sign
- waiver
- object | null · bookings.get and bookings.list: how many signatures of your waiver it needs and has; null when its offering doesn't ask, or it's cancelled or a lapsed hold
- confirmed_at
- string | null · When it was confirmed; null while held, and on bookings older than this field
- updated_at
- string | null · When it last changed; null on bookings older than this field
- reseller_reference
- string | null · A reseller's own reference for a booking it made over OCTO
- cancel_reason
- string | null · Why a reseller cancelled it, in its words
- checked_in_at
- string | null · When the guest was checked in at the door (a rental's guest: picked up), by hand on the roster or with bookings_set_attendance; null otherwise
- no_show_at
- string | null · When it was marked a no-show, once its time had started; never set together with checked_in_at
- previous
- object · bookings.move: where the booking was
- previous.starts_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.ends_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.session_idrequired
- string | null
- offeringrequired
- object
- offering.idrequired
- string
- offering.namerequired
- string
- offering.kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- offering.questions
- object[] · bookings.get and bookings.list: its questions, which answers answers by id
- offering.questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- offering.questions[].labelrequired
- string · The question as guests read it
- offering.questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- offering.questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- offering.questions[].requiredrequired
- boolean · Guests must answer it to book online
- customerrequired
- object
- customer.idrequired
- string
- customer.namerequired
- string
- customer.emailrequired
- string
- customer.phonerequired
- string
POST/bookings/{id}/attendancebookings_set_attendance
Record who showed up: state checked_in when the guest arrives (a rental's guest: picks up), no_show once the booking's time has started and they haven't come, or none to clear either. It sets checked_in_at or no_show_at, never both, and logs booking.checked_in, booking.no_show or booking.attendance_cleared; setting what it already is changes nothing. Only a confirmed booking: a hold or a cancelled booking answers 409 not_confirmed, and a no-show before the start 409 not_started.
Request2
- idpathrequired
- string · uuid
- staterequired
- checked_in | no_show | none · checked_in: they're here · no_show: they didn't come, once the time has started · none: clear either
Response 20065
- idrequired
- string
- org_idrequired
- string
- offering_idrequired
- string
- session_idrequired
- string | null · Classes only; a course's, the first time it was booked from
- series_id
- string | null · A course's booking: the calendar entry it holds a seat in every time of, from session_id's on. Null for a booking of one time
- customer_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- quantityrequired
- integer · class: seats · appointment: people, 1 for one-on-one · rental: items
- total_centsrequired
- integer · In the org's currency, in the currency's minor units (cents; whole yen for zero-decimal currencies): what's left to pay after a promo code
- promo_code
- string | null · The promo code it was booked with, as stored; kept after the code is deleted. Null without one
- discount_cents
- integer · What the promo code took off, in the currency's minor units (cents; whole yen for zero-decimal currencies); 0 without one
- gift_card_id
- string | null · The gift card that paid part of it (gift_cards_get); null without one
- gift_cents
- integer · What the gift card paid, in the currency's minor units (cents; whole yen for zero-decimal currencies), counted as paid: taken off the card once the booking is confirmed, back on it if it's cancelled; 0 without one
- referencerequired
- string · Short code the guest sees, e.g. 0GWYRZ2V
- statusrequired
- held | confirmed | cancelled · held, confirmed or cancelled; a hold keeps its place until expires_at
- sourcerequired
- string · Where it was made: dashboard, api, mcp, widget, octo (a reseller, over /api/octo), or assistant (held for a guest over /api/mcp/book/{slug}, who confirms it)
- notesrequired
- string
- answers
- object · The guest's answers to its offering's questions, keyed by question id: text (a choice's option, as listed), or true or false for a yes or no
- metadatarequired
- any · Free-form JSON object for your own integrations
- cancelled_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- expires_atrequired
- string | null · Held bookings: when the hold stops keeping its place
- handlerequired
- string · Opens the guest's own page, /b/{handle}: their messages, bookings and cancel. daybooked sends it only to the guest's email; never give it to whoever is booking, who may have typed someone else's email. bookings.resend emails it to the guest again
- checkout_urlrequired
- string | null · Stripe Checkout for a hold being paid online
- paid_atrequired
- string | null · When it was paid: online, or marked paid by hand (then payment_intent_id is null)
- paid_cents
- integer | null · What's been paid so far, online and by hand, in the currency's minor units (cents; whole yen for zero-decimal currencies): less than total_cents after a deposit, the rest due at the start. Null on bookings from before deposits: the whole total once paid_at is set
- payment_intent_idrequired
- string | null · The Stripe payment, when paid online
- charged_cents
- integer | null · What its Stripe Checkout charged, a deposit or the whole total, in the currency's minor units (cents; whole yen for zero-decimal currencies): all that cancelling can refund. Null when not paid online, and on bookings from before deposits (the whole total)
- refund_idrequired
- string | null · The Stripe refund of a payment made online, once Stripe took it (cancelling refunds in full, unless refund_cents says otherwise)
- refund_cents
- integer | null · What cancelling refunds of a payment made online, as bookings.cancel's refund chose, in the currency's minor units (cents; whole yen for zero-decimal currencies): null the whole payment, 0 none (the business kept it), otherwise that part
- refunded_atrequired
- string | null · When Stripe confirmed the refund; until then it's on its way
- refund_failed_atrequired
- string | null · When the last try at the refund failed
- refund_errorrequired
- string | null · Why the refund failed, as Stripe said
- refund_next_atrequired
- string | null · When daybooked next looks at the refund (a pending one, or another try); null once refunded or failed for good
- guest_cancel_hours
- integer | null · The window promised when it was booked: the guest may cancel on their page, or change its time, until this many hours before the start (or by the org's rule now, if kinder)
- nudged_at
- string | null · When the guest of this lapsed, unpaid hold was emailed a link to finish booking (bookings_nudge), which goes once
- choose_by
- string | null · Its time was called off with sessions_cancel and guests: "choose": it stays confirmed, holding no place, while its guest picks another time (bookings move it) or takes the refund, until the end of this day in the org's time zone. Past it, it is cancelled, refunding what was paid online. Null otherwise, and once it is cancelled
- waiver_token
- string | null · When its offering asks guests to sign your waiver: the signing link for everyone on the booking, /w/{waiver_token}. It only lets someone sign
- waiver
- object | null · bookings.get and bookings.list: how many signatures of your waiver it needs and has; null when its offering doesn't ask, or it's cancelled or a lapsed hold
- confirmed_at
- string | null · When it was confirmed; null while held, and on bookings older than this field
- updated_at
- string | null · When it last changed; null on bookings older than this field
- reseller_reference
- string | null · A reseller's own reference for a booking it made over OCTO
- cancel_reason
- string | null · Why a reseller cancelled it, in its words
- checked_in_at
- string | null · When the guest was checked in at the door (a rental's guest: picked up), by hand on the roster or with bookings_set_attendance; null otherwise
- no_show_at
- string | null · When it was marked a no-show, once its time had started; never set together with checked_in_at
- previous
- object · bookings.move: where the booking was
- previous.starts_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.ends_atrequired
- string · ISO 8601 timestamp (UTC)
- previous.session_idrequired
- string | null
- offeringrequired
- object
- offering.idrequired
- string
- offering.namerequired
- string
- offering.kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- offering.questions
- object[] · bookings.get and bookings.list: its questions, which answers answers by id
- offering.questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- offering.questions[].labelrequired
- string · The question as guests read it
- offering.questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- offering.questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- offering.questions[].requiredrequired
- boolean · Guests must answer it to book online
- customerrequired
- object
- customer.idrequired
- string
- customer.namerequired
- string
- customer.emailrequired
- string
- customer.phonerequired
- string
Promo codes
GET/promo_codespromo_codes_list
List the business's promo codes, newest first, each with how many bookings have used it
Response 20013
- datarequired
- object[]
- data[].idrequired
- string
- data[].org_idrequired
- string
- data[].coderequired
- string · As guests give it, upper-cased: 3 to 20 letters, digits and dashes
- data[].percent_offrequired
- integer | null · Percent off a booking's total, 1 to 100; null when it takes an amount off
- data[].amount_offrequired
- integer | null · Off a booking's total, in the currency's minor units (cents; whole yen for zero-decimal currencies), never below zero; null when it takes a percent off
- data[].offering_idrequired
- string | null · The one offering it's for; null for any offering
- data[].max_usesrequired
- integer | null · How many bookings may use it; null for no limit
- data[].usesrequired
- integer · Bookings made with it
- data[].starts_atrequired
- string | null · It works from then; null for at once
- data[].ends_atrequired
- string | null · It works until then; null for no end
- data[].activerequired
- boolean · false: switched off, it can't be used
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
POST/promo_codespromo_codes_create
Add a promo code guests can give as they book (bookings.create's promo_code): percent_off or amount_off a booking's total, for any offering or one, with an optional limit on uses and dates. Up to 100 per org; a code the org has already is refused with 409 code_taken
Request8
- coderequired
- string · ≤ 20 chars · 3 to 20 letters, digits and dashes, such as SPRING20; stored upper-cased, and guests may type it in any case
- percent_off
- integer · 1–100 · Percent off the total, 1 to 100 (100 makes the booking free); or amount_off
- amount_off
- integer · ≥ 1 · Off the total, in the currency's minor units (cents; whole yen for zero-decimal currencies), never below zero; or percent_off
- offering_id
- string | null · Only this offering's bookings; null (or left out) for any offering
- max_uses
- integer | null · How many bookings may use it; null (or left out) for no limit
- starts_at
- string | null · It works from then; null (or left out) for at once
- ends_at
- string | null · It stops working then; null (or left out) for no end
- active
- boolean · false adds it switched off (default true)
Response 20112
- idrequired
- string
- org_idrequired
- string
- coderequired
- string · As guests give it, upper-cased: 3 to 20 letters, digits and dashes
- percent_offrequired
- integer | null · Percent off a booking's total, 1 to 100; null when it takes an amount off
- amount_offrequired
- integer | null · Off a booking's total, in the currency's minor units (cents; whole yen for zero-decimal currencies), never below zero; null when it takes a percent off
- offering_idrequired
- string | null · The one offering it's for; null for any offering
- max_usesrequired
- integer | null · How many bookings may use it; null for no limit
- usesrequired
- integer · Bookings made with it
- starts_atrequired
- string | null · It works from then; null for at once
- ends_atrequired
- string | null · It works until then; null for no end
- activerequired
- boolean · false: switched off, it can't be used
- created_atrequired
- string · ISO 8601 timestamp (UTC)
PATCH/promo_codes/{id}promo_codes_update
Switch a promo code on or off, or change its limit, end or offering; null opens each again. Bookings made with it keep what it took off
Request5
- idpathrequired
- string · uuid
- active
- boolean · false switches it off: guests can't use it
- max_uses
- integer | null · How many bookings may use it; null (or left out) for no limit
- ends_at
- string | null · It stops working then; null (or left out) for no end
- offering_id
- string | null · Only this offering's bookings; null (or left out) for any offering
Response 20012
- idrequired
- string
- org_idrequired
- string
- coderequired
- string · As guests give it, upper-cased: 3 to 20 letters, digits and dashes
- percent_offrequired
- integer | null · Percent off a booking's total, 1 to 100; null when it takes an amount off
- amount_offrequired
- integer | null · Off a booking's total, in the currency's minor units (cents; whole yen for zero-decimal currencies), never below zero; null when it takes a percent off
- offering_idrequired
- string | null · The one offering it's for; null for any offering
- max_usesrequired
- integer | null · How many bookings may use it; null for no limit
- usesrequired
- integer · Bookings made with it
- starts_atrequired
- string | null · It works from then; null for at once
- ends_atrequired
- string | null · It works until then; null for no end
- activerequired
- boolean · false: switched off, it can't be used
- created_atrequired
- string · ISO 8601 timestamp (UTC)
DELETE/promo_codes/{id}promo_codes_delete
Delete a promo code: it can't be used again, and bookings made with it keep its words (promo_code) and what it took off
Request1
- idpathrequired
- string · uuid
Response 2001
- okrequired
- true
Gift cards
GET/gift_cardsgift_cards_list
List the business's gift cards, newest first, each with its code, who it's for and from, and what's left on it (balance). Page with before=<next_before>.
Request2
- limitquery
- integer · 1–500
- beforequery
- string · uuid · A card's id: the page continues with those made before it (pass next_before)
Response 20018
- datarequired
- object[]
- data[].idrequired
- string
- data[].org_idrequired
- string
- data[].coderequired
- string · 12 characters of Crockford base32, as made: guests give it as they book (bookings.create's gift_card_code), in any case, spaced or not
- data[].amount_centsrequired
- integer · What it was worth when made, in the currency's minor units (cents; whole yen for zero-decimal currencies)
- data[].currencyrequired
- string · ISO 4217, lowercase: the org's when it was made
- data[].for_namerequired
- string · Who it's for, as given; may be empty
- data[].for_emailrequired
- string · Who it's for: emailed the code when it was made
- data[].from_namerequired
- string · Who it's from: the buyer, or your business for one you issued
- data[].from_emailrequired
- string
- data[].messagerequired
- string · The buyer's message to who it's for, up to 300 characters; may be empty
- data[].issued_byrequired
- purchase | business | null · purchase: bought on your booking page; business: issued by you (gift_cards_issue)
- data[].checkout_session_idrequired
- string | null · A bought card's Stripe Checkout, on your account
- data[].payment_intent_idrequired
- string | null · A bought card's Stripe payment, on your account
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].balancerequired
- integer · What's on it: the sum of its entries, in the currency's minor units (cents; whole yen for zero-decimal currencies). Gift cards never expire
- data[].availablerequired
- integer · What it can spend now: the balance less the parts of live holds that take it once they're confirmed, in the currency's minor units (cents; whole yen for zero-decimal currencies)
- next_beforerequired
- string | null · Pass as before= for the next page; null after the last
GET/gift_cards/{id}gift_cards_get
Get one gift card by its id or its code (in any case, spaced or not), with every change to what's on it: purchase or issue, redeems, refunds and adjusts
Request1
- idpathrequired
- string · ≤ 40 chars · The card's id, or its code
Response 20023
- idrequired
- string
- org_idrequired
- string
- coderequired
- string · 12 characters of Crockford base32, as made: guests give it as they book (bookings.create's gift_card_code), in any case, spaced or not
- amount_centsrequired
- integer · What it was worth when made, in the currency's minor units (cents; whole yen for zero-decimal currencies)
- currencyrequired
- string · ISO 4217, lowercase: the org's when it was made
- for_namerequired
- string · Who it's for, as given; may be empty
- for_emailrequired
- string · Who it's for: emailed the code when it was made
- from_namerequired
- string · Who it's from: the buyer, or your business for one you issued
- from_emailrequired
- string
- messagerequired
- string · The buyer's message to who it's for, up to 300 characters; may be empty
- issued_byrequired
- purchase | business | null · purchase: bought on your booking page; business: issued by you (gift_cards_issue)
- checkout_session_idrequired
- string | null · A bought card's Stripe Checkout, on your account
- payment_intent_idrequired
- string | null · A bought card's Stripe payment, on your account
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- balancerequired
- integer · What's on it: the sum of its entries, in the currency's minor units (cents; whole yen for zero-decimal currencies). Gift cards never expire
- availablerequired
- integer · What it can spend now: the balance less the parts of live holds that take it once they're confirmed, in the currency's minor units (cents; whole yen for zero-decimal currencies)
- entriesrequired
- object[] · Every change to what's on it, oldest first
- entries[].idrequired
- string
- entries[].booking_idrequired
- string | null · The booking a redeem or a refund was for
- entries[].centsrequired
- integer · Signed, in the currency's minor units (cents; whole yen for zero-decimal currencies): a purchase, an issue and a refund add, a redeem takes off, an adjust either
- entries[].kindrequired
- purchase | issue | redeem | refund | adjust · redeem: a booking was confirmed with it; refund: that booking was cancelled; adjust: you fixed the balance
- entries[].noterequired
- string · An adjust's reason
- entries[].created_atrequired
- string · ISO 8601 timestamp (UTC)
POST/gift_cardsgift_cards_issue
Issue a gift card by hand, for goodwill or a refund as credit, on any plan: it's from your business, and who it's for is emailed the code. Logs gift_card.issued
Request4
- amount_centsrequired
- integer · 1–10000000 · What it's worth, in the currency's minor units (cents; whole yen for zero-decimal currencies), in your currency
- for_name
- string · ≤ 120 chars · Who it's for, as the email greets them
- for_emailrequired
- string · email · Who it's for: emailed the code
- message
- string · ≤ 300 chars · A line for them in the email
Response 20116
- idrequired
- string
- org_idrequired
- string
- coderequired
- string · 12 characters of Crockford base32, as made: guests give it as they book (bookings.create's gift_card_code), in any case, spaced or not
- amount_centsrequired
- integer · What it was worth when made, in the currency's minor units (cents; whole yen for zero-decimal currencies)
- currencyrequired
- string · ISO 4217, lowercase: the org's when it was made
- for_namerequired
- string · Who it's for, as given; may be empty
- for_emailrequired
- string · Who it's for: emailed the code when it was made
- from_namerequired
- string · Who it's from: the buyer, or your business for one you issued
- from_emailrequired
- string
- messagerequired
- string · The buyer's message to who it's for, up to 300 characters; may be empty
- issued_byrequired
- purchase | business | null · purchase: bought on your booking page; business: issued by you (gift_cards_issue)
- checkout_session_idrequired
- string | null · A bought card's Stripe Checkout, on your account
- payment_intent_idrequired
- string | null · A bought card's Stripe payment, on your account
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- balancerequired
- integer · What's on it: the sum of its entries, in the currency's minor units (cents; whole yen for zero-decimal currencies). Gift cards never expire
- availablerequired
- integer · What it can spend now: the balance less the parts of live holds that take it once they're confirmed, in the currency's minor units (cents; whole yen for zero-decimal currencies)
POST/gift_cards/{id}/adjustgift_cards_adjust
Fix a gift card's balance by a signed amount, in the currency's minor units (cents; whole yen for zero-decimal currencies), with your reason: an entry of kind adjust, and gift_card.adjusted. It can't go below zero (409 gift_card_short)
Request3
- idpathrequired
- string · uuid
- amount_centsrequired
- integer · -10000000–10000000 · More than zero adds to the balance, less takes off it
- reasonrequired
- string · ≤ 200 chars · Why, kept on the entry
Response 20016
- idrequired
- string
- org_idrequired
- string
- coderequired
- string · 12 characters of Crockford base32, as made: guests give it as they book (bookings.create's gift_card_code), in any case, spaced or not
- amount_centsrequired
- integer · What it was worth when made, in the currency's minor units (cents; whole yen for zero-decimal currencies)
- currencyrequired
- string · ISO 4217, lowercase: the org's when it was made
- for_namerequired
- string · Who it's for, as given; may be empty
- for_emailrequired
- string · Who it's for: emailed the code when it was made
- from_namerequired
- string · Who it's from: the buyer, or your business for one you issued
- from_emailrequired
- string
- messagerequired
- string · The buyer's message to who it's for, up to 300 characters; may be empty
- issued_byrequired
- purchase | business | null · purchase: bought on your booking page; business: issued by you (gift_cards_issue)
- checkout_session_idrequired
- string | null · A bought card's Stripe Checkout, on your account
- payment_intent_idrequired
- string | null · A bought card's Stripe payment, on your account
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- balancerequired
- integer · What's on it: the sum of its entries, in the currency's minor units (cents; whole yen for zero-decimal currencies). Gift cards never expire
- availablerequired
- integer · What it can spend now: the balance less the parts of live holds that take it once they're confirmed, in the currency's minor units (cents; whole yen for zero-decimal currencies)
Waiver
GET/waiverwaiver_get
Your waiver: the title and text each person on a booking signs before they come (the booker as they book online, the rest from the booking's signing link), and its version. body null: you have none, and nobody is asked to sign
Response 2005
- idrequired
- string | null · This version's id; null before the first save
- titlerequired
- string | null · e.g. Release of liability; null when you have no waiver
- bodyrequired
- string | null · The text each person signs: plain text, a blank line between paragraphs. null: you have no waiver and nobody is asked to sign
- versionrequired
- integer · Goes up by one with each save; a signature keeps the version it signed. 0 before the first
- created_atrequired
- string | null · When this version was saved
PUT/waiverwaiver_update
Save your waiver's title and text as a new version (each signature keeps the version it signed), or pass body null to remove it, which stops every offering asking for it. Switch it on per offering with offerings.update waiver_required. daybooked stores the text and the signatures; it doesn't write or review your waiver
Request2
- title
- string · ≤ 120 chars · Required with a body, e.g. Release of liability
- bodyrequired
- string | null · Plain text, a blank line between paragraphs; null removes the waiver
Response 2005
- idrequired
- string | null · This version's id; null before the first save
- titlerequired
- string | null · e.g. Release of liability; null when you have no waiver
- bodyrequired
- string | null · The text each person signs: plain text, a blank line between paragraphs. null: you have no waiver and nobody is asked to sign
- versionrequired
- integer · Goes up by one with each save; a signature keeps the version it signed. 0 before the first
- created_atrequired
- string | null · When this version was saved
Waiver signatures
GET/waiver_signatureswaiver_signatures_list
Who signed your waiver for a booking (booking_id), or for everyone in a class session (session_id), oldest first, each with the version signed. A booking's waiver { needed, signed } counts them
Request2
- booking_idquery
- string · uuid
- session_idquery
- string · uuid
Response 2009
- datarequired
- object[]
- data[].idrequired
- string
- data[].booking_idrequired
- string
- data[].waiver_idrequired
- string · The waiver version signed
- data[].versionrequired
- integer · The version signed
- data[].namerequired
- string · The signer's full name
- data[].for_minorrequired
- string | null · The child's full name, when a parent or guardian signed for them
- data[].signed_atrequired
- string · When it was signed, by daybooked's clock
- data[].with_bookingrequired
- boolean · true: the booker signed it as they booked, on your booking page or widget; false: someone signed from the booking's signing link
Waitlist
GET/waitlistwaitlist_list
Who is waiting for a full time, soonest time first, then in the order they joined: for one time (session_id), an offering's times to come (offering_id), or every time to come. Each entry has the guest, their places and when they were last told a place opened
Request2
- session_idquery
- string · uuid
- offering_idquery
- string · uuid
Response 20014
- datarequired
- object[]
- data[].idrequired
- string
- data[].session_idrequired
- string · The time they're waiting for
- data[].offering_idrequired
- string
- data[].starts_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].ends_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].placesrequired
- integer · Their party: seats, guests or items
- data[].joined_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].told_atrequired
- string | null · When they were last told a place opened; null until they are. A guest is told at most once every 6 hours, 3 times in all
- data[].customerrequired
- object
- data[].customer.idrequired
- string
- data[].customer.namerequired
- string
- data[].customer.emailrequired
- string
- data[].customer.phonerequired
- string
POST/waitlistwaitlist_add
Put a guest on a full time's waitlist by hand, such as a caller: by session_id, or offering_id with starts_at. Its offering's waitlist must be on (offerings.update waitlist_enabled; 409 waitlist_off). Nothing is held or charged. The guest is emailed that they're on it, with a link to leave; when a place opens, everyone waiting whose party fits is emailed at once and the first to book gets it. A party that fits now is refused with 409 has_room (book it instead), and one the time could never take with 400 too_many_places. The same guest again changes their places. The answer says what changed and whether they were emailed
Request8
- session_id
- string · uuid · The time: a class's session_id from availability_get, or any time's from sessions_list
- offering_id
- string · uuid
- starts_at
- string · With offering_id, the time's start: how an appointment's calendar time is named
- placesrequired
- integer · 1–10000 · Their party: seats, guests or items
- customerrequired
- object
- customer.emailrequired
- string · email
- customer.name
- string · ≤ 120 chars
- customer.phone
- string · ≤ 40 chars
Response 20115
- idrequired
- string
- session_idrequired
- string · The time they're waiting for
- offering_idrequired
- string
- starts_atrequired
- string · ISO 8601 timestamp (UTC)
- ends_atrequired
- string · ISO 8601 timestamp (UTC)
- placesrequired
- integer · Their party: seats, guests or items
- joined_atrequired
- string · ISO 8601 timestamp (UTC)
- told_atrequired
- string | null · When they were last told a place opened; null until they are. A guest is told at most once every 6 hours, 3 times in all
- customerrequired
- object
- customer.idrequired
- string
- customer.namerequired
- string
- customer.emailrequired
- string
- customer.phonerequired
- string
- changerequired
- joined | rejoined | updated | same · joined: put on; rejoined: put back after leaving; updated: their places changed; same: already waiting as asked
- emailedrequired
- boolean · Whether they were emailed that they're on it: false when nothing new was joined, or when their inbox's daily cap for waitlist mail held it back
POST/waitlist/offerwaitlist_offer
Tell everyone waiting for a full time (session_id) about another time of the same offering (starts_at), as Fill the day does when it opens the next day's: each guest whose party fits it now is emailed once, with a link that books it for their party. They stay on the waitlist they joined. 404 not_found when the offering has no time starting then. Answers how many were emailed; offering the same time again emails nobody new
Request2
- session_idrequired
- string · uuid · The full time they're waiting for
- starts_atrequired
- string · The other time's start, a time of the same offering
Response 2001
- toldrequired
- integer · Guests emailed about it now
DELETE/waitlist/{id}waitlist_remove
Take a guest off a waitlist; they aren't emailed. Logs waitlist.left with reason removed. Removing twice changes nothing
Request1
- idpathrequired
- string · uuid
Response 2001
- okrequired
- true
Conversations
GET/conversationsconversations_list
List conversations with guests, the ones waiting on a reply first, each with its guest, last message and booking chip (filter by status, unread, a search q, or customer_id for one guest's)
Request5
- statusquery
- open | done
- unreadquery
- boolean
- qquery
- string · ≤ 200 chars · Matches the guest's name or email, or words in the messages
- customer_idquery
- string · uuid
- limitquery
- integer · 1–500
Response 20013
- datarequired
- object[]
- data[].idrequired
- string
- data[].statusrequired
- open | done
- data[].last_message_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].outfitter_read_atrequired
- string | null · ISO 8601 timestamp (UTC)
- data[].guest_read_atrequired
- string | null · ISO 8601 timestamp (UTC)
- data[].snoozed_untilrequired
- string | null · ISO 8601 timestamp (UTC)
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].unreadrequired
- boolean · A guest message is newer than outfitter_read_at
- data[].needs_replyrequired
- boolean · The guest wrote last
- data[].customerrequired
- object | null · Null on a pre-sale question
- data[].last_messagerequired
- object | null
- data[].bookingrequired
- object | null · The guest's next upcoming booking, else their latest
GET/conversations/{id}conversations_get
Get a conversation with its thread oldest first: messages, notes, and the guest's booking events as system rows
Request1
- idpathrequired
- string · uuid
Response 20013
- idrequired
- string
- statusrequired
- open | done
- last_message_atrequired
- string · ISO 8601 timestamp (UTC)
- outfitter_read_atrequired
- string | null · ISO 8601 timestamp (UTC)
- guest_read_atrequired
- string | null · ISO 8601 timestamp (UTC)
- snoozed_untilrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- unreadrequired
- boolean · A guest message is newer than outfitter_read_at
- needs_replyrequired
- boolean · The guest wrote last
- customerrequired
- object | null · Null on a pre-sale question
- last_messagerequired
- object | null
- bookingrequired
- object | null · The guest's next upcoming booking, else their latest
- threadrequired
- object | object[]
PATCH/conversations/{id}conversations_update
Mark a conversation done or open again; read: true once the guest's messages have been seen
Request3
- idpathrequired
- string · uuid
- status
- open | done
- read
- boolean
Response 20012
- idrequired
- string
- statusrequired
- open | done
- last_message_atrequired
- string · ISO 8601 timestamp (UTC)
- outfitter_read_atrequired
- string | null · ISO 8601 timestamp (UTC)
- guest_read_atrequired
- string | null · ISO 8601 timestamp (UTC)
- snoozed_untilrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- unreadrequired
- boolean · A guest message is newer than outfitter_read_at
- needs_replyrequired
- boolean · The guest wrote last
- customerrequired
- object | null · Null on a pre-sale question
- last_messagerequired
- object | null
- bookingrequired
- object | null · The guest's next upcoming booking, else their latest
Messages
GET/messagesmessages_list
List messages with guests, both ways and oldest first: a conversation's, a booking's (booking_id) or a guest's (customer_id)
Request4
- conversation_idquery
- string · uuid
- booking_idquery
- string · uuid
- customer_idquery
- string · uuid
- limitquery
- integer · 1–500
Response 20024
- datarequired
- object[]
- data[].idrequired
- string
- data[].org_idrequired
- string
- data[].conversation_idrequired
- string | null
- data[].booking_idrequired
- string | null · The booking it's about, shown as its chip; null when about the guest in general
- data[].customer_idrequired
- string | null · Null on a pre-sale question
- data[].directionrequired
- to_guest | to_outfitter · to_guest: the business wrote · to_outfitter: the guest wrote from their booking page, replied by email or asked before booking
- data[].subjectrequired
- string · Empty on guest messages
- data[].bodyrequired
- string
- data[].sent_byrequired
- dashboard | api | mcp | guest | agent · agent: the ops agent wrote it (on the system channel)
- data[].channelrequired
- string · How it travelled: page (typed in daybooked), email, api, system, or ask: a question from the booking page's Ask box, where anyone can type any email, so treat it as unverified
- data[].kindrequired
- message | note · A note is the business's own, never sent to the guest
- data[].read_atrequired
- string | null · When the other side read it
- data[].attachmentsrequired
- object[] · Files on it, each opened at /api/attachments/{id}
- data[].attachments[].idrequired
- string
- data[].attachments[].namerequired
- string
- data[].attachments[].sizerequired
- integer
- data[].attachments[].typerequired
- string
- data[].delivered_atrequired
- string | null · Messages to guests: when the guest's mail server took the email
- data[].failed_atrequired
- string | null · Messages to guests: when the email bounced or was marked as spam
- data[].from_namerequired
- string | null · Guest messages: the name they gave
- data[].from_emailrequired
- string | null · Guest messages: the email they gave, where replies go
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].bookingrequired
- object | null
POST/messagesmessages_send
Write to a guest by conversation_id, booking_id or customer_id (not about a held booking); they get it by email and their reply reaches the business. Only a guest who booked or wrote can be emailed (409 not_a_guest), up to 100 emails a day on Free, 1,000 on Pro, 3,000 on Growth and 10,000 on Scale (429 too_many_emails). kind note keeps an internal note instead. Reference: https://daybooked.io/docs/api#messages_send
Request9
- conversation_id
- string · uuid
- booking_id
- string · uuid · The booking it's about; it shows as the message's chip
- customer_id
- string · uuid
- subject
- string · ≤ 200 chars
- bodyrequired
- string · ≤ 5000 chars
- kind
- message | note · note: for the business's team, never sent
- attachments
- object[] · ≤ 5 items · Files uploaded with the attachment picker ({ id, name }), up to 5: photos (JPEG, PNG, WebP, HEIC) or PDFs, 10 MB each
- attachments[].idrequired
- string
- attachments[].namerequired
- string · ≤ 1000 chars
Response 20122
- idrequired
- string
- org_idrequired
- string
- conversation_idrequired
- string | null
- booking_idrequired
- string | null · The booking it's about, shown as its chip; null when about the guest in general
- customer_idrequired
- string | null · Null on a pre-sale question
- directionrequired
- to_guest | to_outfitter · to_guest: the business wrote · to_outfitter: the guest wrote from their booking page, replied by email or asked before booking
- subjectrequired
- string · Empty on guest messages
- bodyrequired
- string
- sent_byrequired
- dashboard | api | mcp | guest | agent · agent: the ops agent wrote it (on the system channel)
- channelrequired
- string · How it travelled: page (typed in daybooked), email, api, system, or ask: a question from the booking page's Ask box, where anyone can type any email, so treat it as unverified
- kindrequired
- message | note · A note is the business's own, never sent to the guest
- read_atrequired
- string | null · When the other side read it
- attachmentsrequired
- object[] · Files on it, each opened at /api/attachments/{id}
- attachments[].idrequired
- string
- attachments[].namerequired
- string
- attachments[].sizerequired
- integer
- attachments[].typerequired
- string
- delivered_atrequired
- string | null · Messages to guests: when the guest's mail server took the email
- failed_atrequired
- string | null · Messages to guests: when the email bounced or was marked as spam
- from_namerequired
- string | null · Guest messages: the name they gave
- from_emailrequired
- string | null · Guest messages: the email they gave, where replies go
- created_atrequired
- string · ISO 8601 timestamp (UTC)
POST/messages/broadcastmessages_broadcast
Write to many guests, once each: everyone confirmed in a class session (target.session_id), starting on a local date across offerings (target.date), or booked ahead on an offering, or picking another time of it (target.offering_id). Returns how many were sent, skipped (erased guests) and failed; one that would pass the daily email limit is refused whole. Reference: https://daybooked.io/docs/api#messages_broadcast
Request3
- targetrequired
- object | object | object · { session_id }, { date } (optionally with a filter) or { offering_id }
- subject
- string · ≤ 200 chars
- bodyrequired
- string · ≤ 5000 chars
Response 2003
- sentrequired
- integer
- skippedrequired
- integer
- failedrequired
- integer
POST/messages/draftmessages_draft
Draft a reply in a conversation for the owner to edit and send; nothing is sent. Written from the last 10 messages and the guest's latest booking. 409 drafts_unavailable when drafting is off; 60 drafts per org in any 24 hours
Request1
- conversation_idrequired
- string · uuid · The conversation to draft a reply in
Response 2001
- textrequired
- string · The drafted reply, plain text, to review and edit before sending
Saved replies
GET/saved_repliessaved_replies_list
List the business's saved replies by title. With booking_id, or conversation_id (its guest and their booking under way or next), each comes with text: its body filled in, ready to send with messages_send
Request2
- booking_idquery
- string · uuid · Fill the replies in for this booking and its guest
- conversation_idquery
- string · uuid · Or for this conversation's guest and their booking under way or next
Response 2008
- datarequired
- object[]
- data[].idrequired
- string
- data[].org_idrequired
- string
- data[].titlerequired
- string · What the owner picks it by
- data[].bodyrequired
- string · The message as saved, with its {variables}
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].updated_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].textrequired
- string · The body filled in for booking_id or conversation_id, ready for messages_send; without them only {org} is filled in
POST/saved_repliessaved_replies_create
Save a reply the business can reuse. Its body can use {first_name}, {start_time}, {offering}, {meeting_point}, {org}, {booking_link}, which saved_replies_list fills in for a guest. Reference: https://daybooked.io/docs/api#saved_replies_create
Request2
- titlerequired
- string · ≤ 80 chars · What it's picked by, such as Directions
- bodyrequired
- string · ≤ 5000 chars · The message. {first_name}, {start_time}, {offering}, {meeting_point}, {org}, {booking_link} are filled in for a guest when it's used
Response 2016
- idrequired
- string
- org_idrequired
- string
- titlerequired
- string · What the owner picks it by
- bodyrequired
- string · The message as saved, with its {variables}
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- updated_atrequired
- string · ISO 8601 timestamp (UTC)
PATCH/saved_replies/{id}saved_replies_update
Change a saved reply's title or body. Reference: https://daybooked.io/docs/api#saved_replies_update
Request3
- idpathrequired
- string · uuid
- title
- string · ≤ 80 chars · What it's picked by, such as Directions
- body
- string · ≤ 5000 chars · The message. {first_name}, {start_time}, {offering}, {meeting_point}, {org}, {booking_link} are filled in for a guest when it's used
Response 2006
- idrequired
- string
- org_idrequired
- string
- titlerequired
- string · What the owner picks it by
- bodyrequired
- string · The message as saved, with its {variables}
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- updated_atrequired
- string · ISO 8601 timestamp (UTC)
DELETE/saved_replies/{id}saved_replies_delete
Delete a saved reply
Request1
- idpathrequired
- string · uuid
Response 2001
- okrequired
- true
Automations
GET/automationsautomations_list
The ops agent's automations (fill, brief, reminders; the weather call isn't available yet), each with its dial (off, ask, do_tell, do_quiet) and settings. Its guardrails (quiet hours, daily cap, refund ceiling) are on org_get
Response 2005
- datarequired
- object[]
- data[].automationrequired
- weather | fill | brief | reminders · fill: open or fill sessions · brief: the morning brief · reminders: before and after each booking · weather: not available yet
- data[].dialrequired
- off | ask | do_tell | do_quiet · off · ask: propose in the Inbox and wait · do_tell: act, then a card and a push · do_quiet: act and log
- data[].settingsrequired
- object · weather: { offerings: { <offering id>: limits }, default: limits }, where limits are maxWindKn and maxGustKn (knots), maxPrecipProb (%), minTempC and maxTempC (°C), noThunder, and minFlowCfs and maxFlowCfs (river flow) · fill: { full_pct (50–100, default 80): once a class time in the next month is this full, or has people on its waitlist, open one at the same time the next day, and email whoever waits for the full one (waitlist.offer) } · brief: { see_you (default true): offer a note to everyone booked today } · reminders (dial off or do_quiet: sent on their own, outside quiet hours): { before_24h, before_2h, after_6h (needs the org's review_url), before_24h_reply_id (a saved reply sent the day before; null = ours), unpaid_hold (default false): bookings_nudge for a guest whose hold lapsed unpaid at Checkout, in an org that takes payment at booking }
- data[].updated_atrequired
- string | null · null until it's first set
PATCH/automations/{automation}automations_update
Turn an automation's dial, or change its settings: the fields given replace those set
Request3
- automationpathrequired
- weather | fill | brief | reminders · fill: open or fill sessions · brief: the morning brief · reminders: before and after each booking · weather: not available yet
- dial
- off | ask | do_tell | do_quiet · off · ask: propose in the Inbox and wait · do_tell: act, then a card and a push · do_quiet: act and log
- settings
- object · weather: { offerings: { <offering id>: limits }, default: limits }, where limits are maxWindKn and maxGustKn (knots), maxPrecipProb (%), minTempC and maxTempC (°C), noThunder, and minFlowCfs and maxFlowCfs (river flow) · fill: { full_pct (50–100, default 80): once a class time in the next month is this full, or has people on its waitlist, open one at the same time the next day, and email whoever waits for the full one (waitlist.offer) } · brief: { see_you (default true): offer a note to everyone booked today } · reminders (dial off or do_quiet: sent on their own, outside quiet hours): { before_24h, before_2h, after_6h (needs the org's review_url), before_24h_reply_id (a saved reply sent the day before; null = ours), unpaid_hold (default false): bookings_nudge for a guest whose hold lapsed unpaid at Checkout, in an org that takes payment at booking }
Response 2004
- automationrequired
- weather | fill | brief | reminders · fill: open or fill sessions · brief: the morning brief · reminders: before and after each booking · weather: not available yet
- dialrequired
- off | ask | do_tell | do_quiet · off · ask: propose in the Inbox and wait · do_tell: act, then a card and a push · do_quiet: act and log
- settingsrequired
- object · weather: { offerings: { <offering id>: limits }, default: limits }, where limits are maxWindKn and maxGustKn (knots), maxPrecipProb (%), minTempC and maxTempC (°C), noThunder, and minFlowCfs and maxFlowCfs (river flow) · fill: { full_pct (50–100, default 80): once a class time in the next month is this full, or has people on its waitlist, open one at the same time the next day, and email whoever waits for the full one (waitlist.offer) } · brief: { see_you (default true): offer a note to everyone booked today } · reminders (dial off or do_quiet: sent on their own, outside quiet hours): { before_24h, before_2h, after_6h (needs the org's review_url), before_24h_reply_id (a saved reply sent the day before; null = ours), unpaid_hold (default false): bookings_nudge for a guest whose hold lapsed unpaid at Checkout, in an org that takes payment at booking }
- updated_atrequired
- string | null · null until it's first set
Proposals
GET/proposalsproposals_list
What the ops agent proposed or did, newest first. A pending one waits for proposals_approve (which runs its actions) or proposals_dismiss. Page with before=<next_before>.
Request4
- statusquery
- pending | done | failed | dismissed | expired | undone
- automationquery
- weather | fill | brief | reminders · fill: open or fill sessions · brief: the morning brief · reminders: before and after each booking · weather: not available yet
- limitquery
- integer · 1–500
- beforequery
- string · uuid · A proposal's id: the page continues with those made before it (pass next_before)
Response 20033
- datarequired
- object[]
- data[].idrequired
- string
- data[].automationrequired
- weather | fill | brief | reminders · fill: open or fill sessions · brief: the morning brief · reminders: before and after each booking · weather: not available yet
- data[].statusrequired
- pending | done | failed | dismissed | expired | undone · pending waits for proposals_approve or proposals_dismiss; approving runs it, so it lands on done or failed
- data[].dialrequired
- ask | do_tell | do_quiet · ask: it waited for a person · do_tell, do_quiet: the agent acted on its own
- data[].titlerequired
- string
- data[].dayrequired
- string · The local date it's for
- data[].session_idrequired
- string | null
- data[].booking_idrequired
- string | null
- data[].datarequired
- object · The brief: trips (today's sessions), unanswered threads and weather; held: "cap" or "money" when the agent waited instead of acting
- data[].actionsrequired
- object[] · Registry operations, run in order as the agent
- data[].actions[].kindrequired
- cancel_session | cancel_booking | move_booking | create_session | message | remind | nudge | offer_time
- data[].actions[].oprequired
- string · The operation it runs, e.g. sessions.create
- data[].actions[].inputrequired
- object · The operation's input
- data[].actions[].factsrequired
- object · What it's about and why: the session or booking, the reason, the refund, the drafted words
- data[].actions[].money
- boolean · It refunds
- data[].actions[].reversible
- boolean · Once done, proposals_undo can reverse it
- data[].actions[].result
- object
- data[].actions[].result.okrequired
- boolean
- data[].actions[].result.data
- any
- data[].actions[].result.error
- string
- data[].actions[].undo
- object
- data[].actions[].undo.oprequired
- string
- data[].actions[].undo.inputrequired
- object
- data[].moneyrequired
- boolean · An action refunds
- data[].reversiblerequired
- boolean · Done, and proposals_undo can reverse it
- data[].expires_atrequired
- string | null · ISO 8601 timestamp (UTC)
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
- data[].decided_atrequired
- string | null · ISO 8601 timestamp (UTC)
- data[].decided_byrequired
- string | null · dashboard, api, mcp or agent
- data[].done_atrequired
- string | null · ISO 8601 timestamp (UTC)
- data[].errorrequired
- string | null
- next_beforerequired
- string | null · Pass as before= for the next page; null after the last
POST/proposals/{id}/approveproposals_approve
Approve a pending proposal: its actions run now, in order, as the agent, stopping at the first that fails. draft rewords its message first
Request4
- idpathrequired
- string · uuid
- draft
- object · Replaces the words of its first message or reminder
- draft.subject
- string · ≤ 200 chars
- draft.bodyrequired
- string · ≤ 5000 chars
Response 20031
- idrequired
- string
- automationrequired
- weather | fill | brief | reminders · fill: open or fill sessions · brief: the morning brief · reminders: before and after each booking · weather: not available yet
- statusrequired
- pending | done | failed | dismissed | expired | undone · pending waits for proposals_approve or proposals_dismiss; approving runs it, so it lands on done or failed
- dialrequired
- ask | do_tell | do_quiet · ask: it waited for a person · do_tell, do_quiet: the agent acted on its own
- titlerequired
- string
- dayrequired
- string · The local date it's for
- session_idrequired
- string | null
- booking_idrequired
- string | null
- datarequired
- object · The brief: trips (today's sessions), unanswered threads and weather; held: "cap" or "money" when the agent waited instead of acting
- actionsrequired
- object[] · Registry operations, run in order as the agent
- actions[].kindrequired
- cancel_session | cancel_booking | move_booking | create_session | message | remind | nudge | offer_time
- actions[].oprequired
- string · The operation it runs, e.g. sessions.create
- actions[].inputrequired
- object · The operation's input
- actions[].factsrequired
- object · What it's about and why: the session or booking, the reason, the refund, the drafted words
- actions[].money
- boolean · It refunds
- actions[].reversible
- boolean · Once done, proposals_undo can reverse it
- actions[].result
- object
- actions[].result.okrequired
- boolean
- actions[].result.data
- any
- actions[].result.error
- string
- actions[].undo
- object
- actions[].undo.oprequired
- string
- actions[].undo.inputrequired
- object
- moneyrequired
- boolean · An action refunds
- reversiblerequired
- boolean · Done, and proposals_undo can reverse it
- expires_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- decided_atrequired
- string | null · ISO 8601 timestamp (UTC)
- decided_byrequired
- string | null · dashboard, api, mcp or agent
- done_atrequired
- string | null · ISO 8601 timestamp (UTC)
- errorrequired
- string | null
POST/proposals/{id}/dismissproposals_dismiss
Dismiss a pending proposal; nothing runs
Request1
- idpathrequired
- string · uuid
Response 20031
- idrequired
- string
- automationrequired
- weather | fill | brief | reminders · fill: open or fill sessions · brief: the morning brief · reminders: before and after each booking · weather: not available yet
- statusrequired
- pending | done | failed | dismissed | expired | undone · pending waits for proposals_approve or proposals_dismiss; approving runs it, so it lands on done or failed
- dialrequired
- ask | do_tell | do_quiet · ask: it waited for a person · do_tell, do_quiet: the agent acted on its own
- titlerequired
- string
- dayrequired
- string · The local date it's for
- session_idrequired
- string | null
- booking_idrequired
- string | null
- datarequired
- object · The brief: trips (today's sessions), unanswered threads and weather; held: "cap" or "money" when the agent waited instead of acting
- actionsrequired
- object[] · Registry operations, run in order as the agent
- actions[].kindrequired
- cancel_session | cancel_booking | move_booking | create_session | message | remind | nudge | offer_time
- actions[].oprequired
- string · The operation it runs, e.g. sessions.create
- actions[].inputrequired
- object · The operation's input
- actions[].factsrequired
- object · What it's about and why: the session or booking, the reason, the refund, the drafted words
- actions[].money
- boolean · It refunds
- actions[].reversible
- boolean · Once done, proposals_undo can reverse it
- actions[].result
- object
- actions[].result.okrequired
- boolean
- actions[].result.data
- any
- actions[].result.error
- string
- actions[].undo
- object
- actions[].undo.oprequired
- string
- actions[].undo.inputrequired
- object
- moneyrequired
- boolean · An action refunds
- reversiblerequired
- boolean · Done, and proposals_undo can reverse it
- expires_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- decided_atrequired
- string | null · ISO 8601 timestamp (UTC)
- decided_byrequired
- string | null · dashboard, api, mcp or agent
- done_atrequired
- string | null · ISO 8601 timestamp (UTC)
- errorrequired
- string | null
POST/proposals/{id}/undoproposals_undo
Undo a done proposal that opened a session: the session is cancelled, while nobody has booked it
Request1
- idpathrequired
- string · uuid
Response 20031
- idrequired
- string
- automationrequired
- weather | fill | brief | reminders · fill: open or fill sessions · brief: the morning brief · reminders: before and after each booking · weather: not available yet
- statusrequired
- pending | done | failed | dismissed | expired | undone · pending waits for proposals_approve or proposals_dismiss; approving runs it, so it lands on done or failed
- dialrequired
- ask | do_tell | do_quiet · ask: it waited for a person · do_tell, do_quiet: the agent acted on its own
- titlerequired
- string
- dayrequired
- string · The local date it's for
- session_idrequired
- string | null
- booking_idrequired
- string | null
- datarequired
- object · The brief: trips (today's sessions), unanswered threads and weather; held: "cap" or "money" when the agent waited instead of acting
- actionsrequired
- object[] · Registry operations, run in order as the agent
- actions[].kindrequired
- cancel_session | cancel_booking | move_booking | create_session | message | remind | nudge | offer_time
- actions[].oprequired
- string · The operation it runs, e.g. sessions.create
- actions[].inputrequired
- object · The operation's input
- actions[].factsrequired
- object · What it's about and why: the session or booking, the reason, the refund, the drafted words
- actions[].money
- boolean · It refunds
- actions[].reversible
- boolean · Once done, proposals_undo can reverse it
- actions[].result
- object
- actions[].result.okrequired
- boolean
- actions[].result.data
- any
- actions[].result.error
- string
- actions[].undo
- object
- actions[].undo.oprequired
- string
- actions[].undo.inputrequired
- object
- moneyrequired
- boolean · An action refunds
- reversiblerequired
- boolean · Done, and proposals_undo can reverse it
- expires_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- decided_atrequired
- string | null · ISO 8601 timestamp (UTC)
- decided_byrequired
- string | null · dashboard, api, mcp or agent
- done_atrequired
- string | null · ISO 8601 timestamp (UTC)
- errorrequired
- string | null
Customers
GET/customerscustomers_list
List customers, newest first; q searches name, email and phone. Page with before=<next_before>.
Request3
- qquery
- string · ≤ 100 chars
- limitquery
- integer · 1–500
- beforequery
- string · uuid · A customer's id: the page continues with those added before them (pass next_before)
Response 20010
- datarequired
- object[]
- data[].idrequired
- string
- data[].org_idrequired
- string
- data[].emailrequired
- string · Lowercase; unique within the org
- data[].namerequired
- string
- data[].phonerequired
- string
- data[].notesrequired
- string
- data[].metadatarequired
- any · Free-form JSON object for your own integrations
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
- next_beforerequired
- string | null · Pass as before= for the next page; null after the last
GET/customers/{id}customers_get
Get a customer with their bookings
Request1
- idpathrequired
- string · uuid
Response 20074
- idrequired
- string
- org_idrequired
- string
- emailrequired
- string · Lowercase; unique within the org
- namerequired
- string
- phonerequired
- string
- notesrequired
- string
- metadatarequired
- any · Free-form JSON object for your own integrations
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- bookingsrequired
- object[]
- bookings[].idrequired
- string
- bookings[].org_idrequired
- string
- bookings[].offering_idrequired
- string
- bookings[].session_idrequired
- string | null · Classes only; a course's, the first time it was booked from
- bookings[].series_id
- string | null · A course's booking: the calendar entry it holds a seat in every time of, from session_id's on. Null for a booking of one time
- bookings[].customer_idrequired
- string
- bookings[].starts_atrequired
- string · ISO 8601 timestamp (UTC)
- bookings[].ends_atrequired
- string · ISO 8601 timestamp (UTC)
- bookings[].quantityrequired
- integer · class: seats · appointment: people, 1 for one-on-one · rental: items
- bookings[].total_centsrequired
- integer · In the org's currency, in the currency's minor units (cents; whole yen for zero-decimal currencies): what's left to pay after a promo code
- bookings[].promo_code
- string | null · The promo code it was booked with, as stored; kept after the code is deleted. Null without one
- bookings[].discount_cents
- integer · What the promo code took off, in the currency's minor units (cents; whole yen for zero-decimal currencies); 0 without one
- bookings[].gift_card_id
- string | null · The gift card that paid part of it (gift_cards_get); null without one
- bookings[].gift_cents
- integer · What the gift card paid, in the currency's minor units (cents; whole yen for zero-decimal currencies), counted as paid: taken off the card once the booking is confirmed, back on it if it's cancelled; 0 without one
- bookings[].referencerequired
- string · Short code the guest sees, e.g. 0GWYRZ2V
- bookings[].statusrequired
- held | confirmed | cancelled · held, confirmed or cancelled; a hold keeps its place until expires_at
- bookings[].sourcerequired
- string · Where it was made: dashboard, api, mcp, widget, octo (a reseller, over /api/octo), or assistant (held for a guest over /api/mcp/book/{slug}, who confirms it)
- bookings[].notesrequired
- string
- bookings[].answers
- object · The guest's answers to its offering's questions, keyed by question id: text (a choice's option, as listed), or true or false for a yes or no
- bookings[].metadatarequired
- any · Free-form JSON object for your own integrations
- bookings[].cancelled_atrequired
- string | null · ISO 8601 timestamp (UTC)
- bookings[].created_atrequired
- string · ISO 8601 timestamp (UTC)
- bookings[].expires_atrequired
- string | null · Held bookings: when the hold stops keeping its place
- bookings[].handlerequired
- string · Opens the guest's own page, /b/{handle}: their messages, bookings and cancel. daybooked sends it only to the guest's email; never give it to whoever is booking, who may have typed someone else's email. bookings.resend emails it to the guest again
- bookings[].checkout_urlrequired
- string | null · Stripe Checkout for a hold being paid online
- bookings[].paid_atrequired
- string | null · When it was paid: online, or marked paid by hand (then payment_intent_id is null)
- bookings[].paid_cents
- integer | null · What's been paid so far, online and by hand, in the currency's minor units (cents; whole yen for zero-decimal currencies): less than total_cents after a deposit, the rest due at the start. Null on bookings from before deposits: the whole total once paid_at is set
- bookings[].payment_intent_idrequired
- string | null · The Stripe payment, when paid online
- bookings[].charged_cents
- integer | null · What its Stripe Checkout charged, a deposit or the whole total, in the currency's minor units (cents; whole yen for zero-decimal currencies): all that cancelling can refund. Null when not paid online, and on bookings from before deposits (the whole total)
- bookings[].refund_idrequired
- string | null · The Stripe refund of a payment made online, once Stripe took it (cancelling refunds in full, unless refund_cents says otherwise)
- bookings[].refund_cents
- integer | null · What cancelling refunds of a payment made online, as bookings.cancel's refund chose, in the currency's minor units (cents; whole yen for zero-decimal currencies): null the whole payment, 0 none (the business kept it), otherwise that part
- bookings[].refunded_atrequired
- string | null · When Stripe confirmed the refund; until then it's on its way
- bookings[].refund_failed_atrequired
- string | null · When the last try at the refund failed
- bookings[].refund_errorrequired
- string | null · Why the refund failed, as Stripe said
- bookings[].refund_next_atrequired
- string | null · When daybooked next looks at the refund (a pending one, or another try); null once refunded or failed for good
- bookings[].guest_cancel_hours
- integer | null · The window promised when it was booked: the guest may cancel on their page, or change its time, until this many hours before the start (or by the org's rule now, if kinder)
- bookings[].nudged_at
- string | null · When the guest of this lapsed, unpaid hold was emailed a link to finish booking (bookings_nudge), which goes once
- bookings[].choose_by
- string | null · Its time was called off with sessions_cancel and guests: "choose": it stays confirmed, holding no place, while its guest picks another time (bookings move it) or takes the refund, until the end of this day in the org's time zone. Past it, it is cancelled, refunding what was paid online. Null otherwise, and once it is cancelled
- bookings[].waiver_token
- string | null · When its offering asks guests to sign your waiver: the signing link for everyone on the booking, /w/{waiver_token}. It only lets someone sign
- bookings[].waiver
- object | null · bookings.get and bookings.list: how many signatures of your waiver it needs and has; null when its offering doesn't ask, or it's cancelled or a lapsed hold
- bookings[].confirmed_at
- string | null · When it was confirmed; null while held, and on bookings older than this field
- bookings[].updated_at
- string | null · When it last changed; null on bookings older than this field
- bookings[].reseller_reference
- string | null · A reseller's own reference for a booking it made over OCTO
- bookings[].cancel_reason
- string | null · Why a reseller cancelled it, in its words
- bookings[].checked_in_at
- string | null · When the guest was checked in at the door (a rental's guest: picked up), by hand on the roster or with bookings_set_attendance; null otherwise
- bookings[].no_show_at
- string | null · When it was marked a no-show, once its time had started; never set together with checked_in_at
- bookings[].previous
- object · bookings.move: where the booking was
- bookings[].previous.starts_atrequired
- string · ISO 8601 timestamp (UTC)
- bookings[].previous.ends_atrequired
- string · ISO 8601 timestamp (UTC)
- bookings[].previous.session_idrequired
- string | null
- bookings[].offeringrequired
- object
- bookings[].offering.idrequired
- string
- bookings[].offering.namerequired
- string
- bookings[].offering.kindrequired
- class | appointment | rental · class: sessions with seats, from its calendar · appointment: times from its calendar or weekly hours · rental: inventory over periods
- bookings[].offering.questions
- object[] · bookings.get and bookings.list: its questions, which answers answers by id
- bookings[].offering.questions[].idrequired
- string · bookings.create takes the answer to this question under this id
- bookings[].offering.questions[].labelrequired
- string · The question as guests read it
- bookings[].offering.questions[].typerequired
- string · text: a line in their words · yes_no: true or false · choice: one of its options
- bookings[].offering.questions[].options
- string[] · A choice's options: its answer is one of them, as listed
- bookings[].offering.questions[].requiredrequired
- boolean · Guests must answer it to book online
- bookings[].customerrequired
- object
- bookings[].customer.idrequired
- string
- bookings[].customer.namerequired
- string
- bookings[].customer.emailrequired
- string
- bookings[].customer.phonerequired
- string
POST/customerscustomers_upsert
Create a customer, or update the given fields when the email already exists
Request5
- name
- string · ≤ 120 chars
- phone
- string · ≤ 40 chars
- notes
- string · ≤ 5000 chars
- metadata
- object
- emailrequired
- string · email
Response 2008
- idrequired
- string
- org_idrequired
- string
- emailrequired
- string · Lowercase; unique within the org
- namerequired
- string
- phonerequired
- string
- notesrequired
- string
- metadatarequired
- any · Free-form JSON object for your own integrations
- created_atrequired
- string · ISO 8601 timestamp (UTC)
PATCH/customers/{id}customers_update
Update a customer's name, phone, notes or metadata
Request5
- idpathrequired
- string · uuid
- name
- string · ≤ 120 chars
- phone
- string · ≤ 40 chars
- notes
- string · ≤ 5000 chars
- metadata
- object
Response 2008
- idrequired
- string
- org_idrequired
- string
- emailrequired
- string · Lowercase; unique within the org
- namerequired
- string
- phonerequired
- string
- notesrequired
- string
- metadatarequired
- any · Free-form JSON object for your own integrations
- created_atrequired
- string · ISO 8601 timestamp (UTC)
DELETE/customers/{id}customers_delete
Erase a customer's personal data (name, email, phone, notes) on request; their bookings stay, anonymized
Request1
- idpathrequired
- string · uuid
Response 2001
- okrequired
- true
Org
GET/orgorg_get
Your organization: name, slug (booking page /book/{slug}), time zone, currency and how guest messages are answered
Response 20020
- idrequired
- string
- namerequired
- string
- slugrequired
- string · Booking page: /book/{slug}
- timezonerequired
- string · IANA time zone, e.g. America/Denver. Weekly hours and dates are local to it.
- currencyrequired
- string · ISO 4217 code in lowercase, e.g. usd
- reply_windowrequired
- string | null · When guests can expect a reply, e.g. "We reply by 9 AM"; part of the acknowledgement
- auto_ackrequired
- boolean · Emails a guest who writes "Thanks, we got your message", at most once a conversation a day
- away_noticerequired
- string | null · While set: shown on the booking page and sent with the acknowledgement
- guest_cancel_hours
- integer | null · Guests may cancel from their booking page until this many hours before the start, and change their time inside the same window; null: off, they write to you instead. Each booking keeps the window it was made with
- review_url
- string | null · Where guests leave a review; the ops agent's thank-you links it
- assistant_booking
- boolean · Assistants booking for a guest may hold places with no key, at /api/mcp/book/{slug}; each guest confirms by email
- gift_cards
- boolean · Gift cards are sold on the booking page (/book/{slug}/gift) while the business takes payments at booking
- brief_hour
- integer · The local hour of the ops agent's morning brief
- ops_daily_cap
- integer · The most the ops agent does on its own in 24 hours; past it, it asks
- quiet_from
- integer | null · Quiet hours start (local hour): the agent sends guests nothing on its own until quiet_to
- quiet_to
- integer | null · Quiet hours end (local hour)
- refund_ceiling_cents
- integer | null · The ops agent refunds on its own up to this; null means a refund always waits for approval
- setup_site_done_at
- string | null · When the go-live checklist's website step was done (the site code or booking link copied)
- setup_closed_at
- string | null · When the go-live checklist was closed for good; it no longer shows
- created_atrequired
- string · ISO 8601 timestamp (UTC)
PATCH/orgorg_update
Rename the organization, change its time zone (IANA, e.g. America/Denver) or currency, or set the reply window, auto-acknowledge and away notice guests see when they write
Request18
- name
- string · ≤ 80 chars
- timezone
- string · ≤ 64 chars
- currency
- string · ISO 4217, lowercase: one Stripe charges in, not the three-decimal BHD, JOD, KWD, OMR or TND. Amounts are in its minor units (cents; whole yen for zero-decimal currencies) and aren't converted
- reply_window
- string | null · e.g. "We reply by 9 AM"; null or "" clears it
- auto_ack
- boolean · Email guests who write "Thanks, we got your message", at most once a conversation a day
- away_notice
- string | null · Shown on the booking page and sent with the acknowledgement while set; null or "" clears it
- guest_cancel_hours
- integer | null · Guests may cancel from their booking page until this many hours before the start (online payments refunded in full), and change their time inside the same window (booking.moved, source widget); null turns both off. Bookings already made keep the window they were promised
- notify_new_booking
- boolean · Email the owner each new booking made online (default true); the morning brief sums up the day either way
- assistant_booking
- boolean · Let assistants booking for a guest hold places with no key, at /api/mcp/book/{slug} (default true); the guest confirms each hold by email
- gift_cards
- boolean · Sell gift cards on the booking page, /book/{slug}/gift (default false); only while the business takes payments at booking
- review_url
- string | "" | null · Where guests leave a review (https), linked in the thank-you; null or "" clears it
- brief_hour
- integer · 0–23 · The local hour of the morning brief
- ops_daily_cap
- integer · 1–500 · The most the agent does on its own in 24 hours; past it, it asks
- quiet_from
- integer | null · Quiet hours start (local hour): the agent sends guests nothing on its own until quiet_to; null for none
- quiet_to
- integer | null · Quiet hours end (local hour)
- refund_ceiling_cents
- integer | null · The agent refunds on its own up to this; null means a refund always waits for approval
- setup_site_done_at
- string | null · When the go-live checklist's website step was done (the site code or booking link copied); null reopens it
- setup_closed_at
- string | null · When the go-live checklist was closed for good; null shows it again
Response 20020
- idrequired
- string
- namerequired
- string
- slugrequired
- string · Booking page: /book/{slug}
- timezonerequired
- string · IANA time zone, e.g. America/Denver. Weekly hours and dates are local to it.
- currencyrequired
- string · ISO 4217 code in lowercase, e.g. usd
- reply_windowrequired
- string | null · When guests can expect a reply, e.g. "We reply by 9 AM"; part of the acknowledgement
- auto_ackrequired
- boolean · Emails a guest who writes "Thanks, we got your message", at most once a conversation a day
- away_noticerequired
- string | null · While set: shown on the booking page and sent with the acknowledgement
- guest_cancel_hours
- integer | null · Guests may cancel from their booking page until this many hours before the start, and change their time inside the same window; null: off, they write to you instead. Each booking keeps the window it was made with
- review_url
- string | null · Where guests leave a review; the ops agent's thank-you links it
- assistant_booking
- boolean · Assistants booking for a guest may hold places with no key, at /api/mcp/book/{slug}; each guest confirms by email
- gift_cards
- boolean · Gift cards are sold on the booking page (/book/{slug}/gift) while the business takes payments at booking
- brief_hour
- integer · The local hour of the ops agent's morning brief
- ops_daily_cap
- integer · The most the ops agent does on its own in 24 hours; past it, it asks
- quiet_from
- integer | null · Quiet hours start (local hour): the agent sends guests nothing on its own until quiet_to
- quiet_to
- integer | null · Quiet hours end (local hour)
- refund_ceiling_cents
- integer | null · The ops agent refunds on its own up to this; null means a refund always waits for approval
- setup_site_done_at
- string | null · When the go-live checklist's website step was done (the site code or booking link copied)
- setup_closed_at
- string | null · When the go-live checklist was closed for good; it no longer shows
- created_atrequired
- string · ISO 8601 timestamp (UTC)
GET/org/exportorg_export
Export all your data as JSON: org, offerings, hours, sessions, customers, bookings, waivers and their signatures, waitlist entries, conversations, messages, saved replies, promo codes, gift cards and their entries, automations, proposals, webhooks and the last 1000 events
Response 200The org, offerings, hours, sessions, customers, bookings, waivers and their signatures, waitlist entries, conversations, messages, saved replies, promo codes, gift cards (each with its balance) and their entries, automations, proposals, webhooks (no secrets) and the last 1000 events
Events
GET/eventsevents_list
Everything that happened, oldest first (order=desc for the newest first). Poll with after=<next_after> to follow along.
Request4
- afterquery
- integer · ≥ 0
- typequery
- string · ≤ 60 chars · e.g. booking.confirmed
- orderquery
- asc | desc · desc: the newest first, for a look at what just happened; next_after is then the newest served
- limitquery
- integer · 1–500
Response 2006
- datarequired
- object[]
- data[].idrequired
- integer · Increasing; poll with after=<id>
- data[].typerequired
- string · e.g. booking.confirmed, offering.updated
- data[].datarequired
- any · The resource after the change: the booking, session, offering, customer or org
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
- next_afterrequired
- integer · Pass as after= to get what happened next
Webhooks
GET/webhookswebhooks_list
List webhook endpoints and their last delivery status
Response 20010
- datarequired
- object[]
- data[].idrequired
- string
- data[].urlrequired
- string
- data[].eventsrequired
- string[] · Event types it receives; ["*"] means all
- data[].activerequired
- boolean · false once its endpoint answered 410 Gone, or the API key that made it was revoked: it gets no more events and doesn't count toward the 50
- data[].api_key_idrequired
- string | null · The API key that made it, whose revoking switches it off; null when no key did (the dashboard, an OAuth sign-in)
- data[].last_statusrequired
- integer | null · HTTP status of the last delivery; 0 = unreachable
- data[].last_error
- string | null · Why the last delivery failed, or why the webhook was switched off
- data[].last_attempt_atrequired
- string | null · ISO 8601 timestamp (UTC)
- data[].created_atrequired
- string · ISO 8601 timestamp (UTC)
POST/webhookswebhooks_create
Send events to an HTTPS URL, signed with HMAC-SHA256; up to 50 per org. Returns the signing secret once. Reference: https://daybooked.io/docs/api#webhooks_create
Request2
- urlrequired
- string · uri
- events
- string[] · ≤ 30 items · Event types, or ["*"] for all (default)
Response 20110
- idrequired
- string
- urlrequired
- string
- eventsrequired
- string[] · Event types it receives; ["*"] means all
- activerequired
- boolean · false once its endpoint answered 410 Gone, or the API key that made it was revoked: it gets no more events and doesn't count toward the 50
- api_key_idrequired
- string | null · The API key that made it, whose revoking switches it off; null when no key did (the dashboard, an OAuth sign-in)
- last_statusrequired
- integer | null · HTTP status of the last delivery; 0 = unreachable
- last_error
- string | null · Why the last delivery failed, or why the webhook was switched off
- last_attempt_atrequired
- string | null · ISO 8601 timestamp (UTC)
- created_atrequired
- string · ISO 8601 timestamp (UTC)
- secretrequired
- string · Verifies the Daybooked-Signature header. Shown once.
DELETE/webhooks/{id}webhooks_delete
Stop sending events to a webhook endpoint
Request1
- idpathrequired
- string · uuid
Response 2001
- okrequired
- true
Look
GET/looklook_get
The look of your booking page, widget and guests' booking pages: the template chosen, its colors, corners, type, tagline and logo, and the ten templates to choose from. live says whether guests see it (on any paid plan)
Response 20018
- liverequired
- boolean · Guests see it: the org is on a paid plan. On Free the booking page keeps daybooked's own look
- templaterequired
- string | null · The template chosen (an id from templates); null when the org hasn't chosen one
- colorsrequired
- object | null · The page's background, its cards, its text and its accent (buttons, the chosen time), with the org's changes
- cornersrequired
- integer | null · 0 square, 50 daybooked's own, 100 as round as it goes
- fontrequired
- string | null · The type pairing chosen in place of the template's own, if any
- taglinerequired
- string | null · A line under the business's name
- show_namerequired
- boolean · Whether the business's name shows beside the logo
- logorequired
- object | null
- templatesrequired
- object[] · The ten templates, from sticker collage to dark luxury, each with its own colors and corners
- templates[].idrequired
- string
- templates[].namerequired
- string
- templates[].moodrequired
- string · What it's like, in a few words
- templates[].colorsrequired
- object
- templates[].colors.backgroundrequired
- string · Six-digit hex, e.g. #0d99ff
- templates[].colors.cardrequired
- string · Six-digit hex, e.g. #0d99ff
- templates[].colors.textrequired
- string · Six-digit hex, e.g. #0d99ff
- templates[].colors.accentrequired
- string · Six-digit hex, e.g. #0d99ff
- templates[].cornersrequired
- integer
PATCH/looklook_update
Choose a template (ids from look_get) and change its colors, corners, type and tagline; guests see it at once. Pass only what changes; null puts a setting back to the template's own, and a new template resets colors, corners and font unless they're passed too. Text and accent colors are nudged if they wouldn't be readable. Paid plans only: a Free org gets 403 plan_required
Request7
- template
- studio | trailhead | grid | noir | zine | scrapbook | sunset | journal | midnight | bubblegum · The template. A new one resets colors, corners and font to its own unless they're passed too
- colors
- object | null · Any of background, card, text and accent, as six-digit hex. Text and the accent are nudged if they wouldn't read
- corners
- integer | null · 0 square, 50 daybooked's own, 100 as round as it goes
- font
- clean | geometric | bold | serif | elegant | rounded | hand | mono | null · A type pairing in place of the template's own
- tagline
- string | null · A line under the business's name
- show_name
- boolean | null · Show the name beside the logo. By default a wide logo stands in for it and a square icon sits beside it
- logo
- object | null · null removes the logo. Uploading one happens in the dashboard
Response 20018
- liverequired
- boolean · Guests see it: the org is on a paid plan. On Free the booking page keeps daybooked's own look
- templaterequired
- string | null · The template chosen (an id from templates); null when the org hasn't chosen one
- colorsrequired
- object | null · The page's background, its cards, its text and its accent (buttons, the chosen time), with the org's changes
- cornersrequired
- integer | null · 0 square, 50 daybooked's own, 100 as round as it goes
- fontrequired
- string | null · The type pairing chosen in place of the template's own, if any
- taglinerequired
- string | null · A line under the business's name
- show_namerequired
- boolean · Whether the business's name shows beside the logo
- logorequired
- object | null
- templatesrequired
- object[] · The ten templates, from sticker collage to dark luxury, each with its own colors and corners
- templates[].idrequired
- string
- templates[].namerequired
- string
- templates[].moodrequired
- string · What it's like, in a few words
- templates[].colorsrequired
- object
- templates[].colors.backgroundrequired
- string · Six-digit hex, e.g. #0d99ff
- templates[].colors.cardrequired
- string · Six-digit hex, e.g. #0d99ff
- templates[].colors.textrequired
- string · Six-digit hex, e.g. #0d99ff
- templates[].colors.accentrequired
- string · Six-digit hex, e.g. #0d99ff
- templates[].cornersrequired
- integer
Billing
GET/billingbilling_get
Your plan and this month's confirmed bookings against its limit (Free 25, Pro 1,000, Growth 5,000, Scale 15,000 a month). At the limit new bookings answer 402 plan_limit until the owner changes plan in the dashboard or the month turns
Response 2005
- planrequired
- free | pro | growth | scale · free, pro, growth or scale. Every paid plan adds payment at booking and the org's own look, and drops the daybooked mark
- limitrequired
- integer · Confirmed bookings the plan takes a month
- usedrequired
- integer · Bookings made this month in the org's time zone that confirmed, cancelled since or not
- pctrequired
- integer · used as a percentage of limit: 100 at the limit, and past it after a downgrade
- pausedrequired
- boolean · At the limit: new bookings answer 402 plan_limit until the plan changes or the month turns
Reports
GET/reports/{month}reports_month
A month's figures for bookings that start in the month on the org's clock: confirmed bookings going ahead, their guests and revenue_cents (what they're booked for; a cancelled booking counts nothing), no-shows and check-ins among them, live holds and cancellations; then by_offering (most revenue first, with a class's seats offered and how full they were) and by_source (where bookings came from). Counted by the database, so they hold at any volume
Request1
- monthpathrequired
- string · The month, YYYY-MM, e.g. 2026-10
Response 20024
- monthrequired
- string · The month, YYYY-MM, on the org's clock
- fromrequired
- string · The month's first instant, its first midnight in the org's time zone
- torequired
- string · The next month's first instant: the month is from up to, not including, to
- currencyrequired
- string · The org's currency, which the amounts are in (ISO 4217, lower case)
- totalsrequired
- object
- totals.bookingsrequired
- integer · Confirmed bookings starting in the month whose time is going ahead (not one called off with its guest picking another time)
- totals.guestsrequired
- integer · Their seats, people or items: the sum of their quantity
- totals.revenue_centsrequired
- integer · What they're booked for (their total_cents, after any promo code); a cancelled booking counts nothing, in the currency's minor units (cents; whole yen for zero-decimal currencies)
- totals.no_showsrequired
- integer · Of those bookings, the ones marked no-show
- totals.checked_inrequired
- integer · Of those bookings, the ones checked in (a rental's: picked up)
- totals.heldrequired
- integer · Holds starting in the month that still keep their place
- totals.cancelledrequired
- integer · Bookings starting in the month that were cancelled
- by_offeringrequired
- object[] · Each offering with bookings in the month, and each class with times in it, most revenue first
- by_offering[].offering_idrequired
- string
- by_offering[].namerequired
- string
- by_offering[].kindrequired
- class | appointment | rental
- by_offering[].bookingsrequired
- integer · Its confirmed bookings going ahead in the month
- by_offering[].guestsrequired
- integer · Their quantity
- by_offering[].revenue_centsrequired
- integer · What they're booked for, in the currency's minor units (cents; whole yen for zero-decimal currencies)
- by_offering[].seats_offeredrequired
- integer | null · A class: the seats of its scheduled sessions in the month; null for the other kinds
- by_offering[].fillrequired
- number | null · A class: guests over seats_offered, 0.68 for 68% (to 4 places); null for the other kinds
- by_sourcerequired
- object[] · Where the month's bookings came from, most first
- by_source[].sourcerequired
- string · Where they were made: widget, dashboard, api, mcp, octo or assistant
- by_source[].bookingsrequired
- integer · Confirmed bookings going ahead