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.

Plain text

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