Skip to content
Beta

Reference Bookings and services

Bookings and services

List and fetch a team's bookings, and list the services its customers can book.

Overview

A booking is an appointment on the team's calendar. Its kind says where it came from:

  • service_booking: booked for a bookable service, by the AI, a customer or someone on the team. service names the service.
  • calendar_event: an event from the team's connected calendar.
  • external_import: synced from an external booking system, or read from a booking portal's email.

status is scheduled, rescheduled, cancelled, postponed, attended, no_show or team_no_show. Only people record attendance. source says who booked it: ai, customer or operator. meeting_type is online, in_person or phone. Payments are not exported.

A reschedule shows up in one of two ways. The same booking is updated when someone on the team moves it in Totem, when the AI moves a booking held in an external booking system such as Koibox, when that system reports a move, or when a booking portal's email does: starts_at and ends_at hold the new time, and the previous time is not exported. Its status becomes rescheduled, although a move that an external booking system reports can leave the status unchanged. When the AI reschedules any other booking, it creates a new one: the old booking ends as cancelled, with rescheduled_to pointing to the new one, and the new one points back with rescheduled_from. For a few seconds after that kind of reschedule, the old booking can still read scheduled. A change made directly in Google Calendar or Outlook may not reach the Totem booking. A booking rescheduled before Totem started recording these links may lack either link, as Data coverage explains.

A bookable service is something customers can book with the team, such as a first consultation. GET /v1/booking_services returns every service of the team, each with its meeting_type, in one response that takes no limit or cursor. Services are not in the changes feed: read the list when you start syncing a team, when a booking names a service you do not know, and at least once a day. A deleted service drops out of the list while its bookings keep naming its id: do not re-read the list for an id it did not resolve last time, and if you show service names on older bookings, keep the name from an earlier read. Disabled services stay listed, with nothing that marks them as disabled.

Use GET /v1/bookings and GET /v1/bookings/{id} to look bookings up; GET /v1/bookings?lead= lists one lead's bookings. To keep a copy, follow the changes feed: Keep a copy in sync explains it.

List bookings

GET /v1/bookings

Returns a page of the team's bookings: appointments for a bookable service, events from the connected calendar and bookings imported from other systems, each with its status and times. Pass lead for one lead's bookings.

Scopes
calendar:read
Rate limit
Sync

Query parameters

  • limit integer Range 1–100 Default 25

    Items per page, 1–100. Defaults to 25.

  • cursor string 1–512 chars

    The next_cursor of the previous page. Omit it for the first page.

  • lead string ID prefix lead_…

    Only the bookings linked to this lead: every item's lead is this id. A lead of another team, or one that does not exist, matches nothing.

Headers

  • Totem-Team string Conditional ID prefix team_…

    The team to read, as a team_… id. Omit it when the key reads one team; it is required when the key reads several (400 team_required). When you send it, it must name a team the key reads: a malformed id gets 400 invalid_request, and a team outside the key gets 404 team_not_accessible, as does a request without it once the key reads no team at all.

Returns

Returns a list of Booking objects.

  • object string

    Always list.

  • data Array<Booking>

    The items of this page.

  • has_more boolean

    true when another page follows: fetch it with next_cursor, even if this page holds fewer items than limit.

  • next_cursor string Nullable

    Opaque cursor for the next page, or null on the last page. Never parse it.

Errors

+ 12 common errors

GET /v1/bookings
curl 'https://api.totemstudio.ai/v1/bookings?limit=25' \
  -H "Authorization: Bearer $TOTEM_API_KEY" \
  -H "Totem-Team: $TOTEM_TEAM_ID"
Response · 200JSON
{
  "object": "list",
  "data": [
    {
      "id": "bkg_r72EfbRNUzuqORFJR0O8HxAwEXd93jGUTYMaMMX3ttMKHRR9ADk3N7Cr3NSuY0",
      "object": "booking",
      "livemode": false,
      "team": "team_r9uYrIW4gSFJJ6hZQ9ip1UIpPaAD1CF7NR",
      "lead": "lead_r72EfbRNUzuqORFJR0O8HxAwEXd93jGUTYMaMMXKSF0QbLS8CiUKJpEP34LFQG",
      "kind": "service_booking",
      "service": "svc_h42kgwwJGPzsm2Zoy1A1RBv1KIrX5",
      "status": "scheduled",
      "starts_at": "2026-10-06T15:00:00.000Z",
      "ends_at": "2026-10-06T15:30:00.000Z",
      "meeting_type": "in_person",
      "source": "ai",
      "rescheduled_from": null,
      "rescheduled_to": null,
      "created_at": "2026-10-01T09:01:00.000Z",
      "version": 1,
      "updated_at": "2026-10-01T09:01:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Get a booking

GET /v1/bookings/{id}

Returns one booking by its id. A booking this key cannot read, or one that was removed, answers 404 resource_missing.

Scopes
calendar:read
Rate limit
Read

Path parameters

  • id string Required ID prefix bkg_…

    The booking's public id.

Returns

Returns a Booking object.

Errors

+ 12 common errors

GET /v1/bookings/{id}
curl 'https://api.totemstudio.ai/v1/bookings/bkg_r72EfbRNUzuqORFJR0O8HxAwEXd93jGUTYMaMMX3ttMKHRR9ADk3N7Cr3NSuY0' \
  -H "Authorization: Bearer $TOTEM_API_KEY"
Response · 200JSON
{
  "id": "bkg_r72EfbRNUzuqORFJR0O8HxAwEXd93jGUTYMaMMX3ttMKHRR9ADk3N7Cr3NSuY0",
  "object": "booking",
  "livemode": false,
  "team": "team_r9uYrIW4gSFJJ6hZQ9ip1UIpPaAD1CF7NR",
  "lead": "lead_r72EfbRNUzuqORFJR0O8HxAwEXd93jGUTYMaMMXKSF0QbLS8CiUKJpEP34LFQG",
  "kind": "service_booking",
  "service": "svc_h42kgwwJGPzsm2Zoy1A1RBv1KIrX5",
  "status": "scheduled",
  "starts_at": "2026-10-06T15:00:00.000Z",
  "ends_at": "2026-10-06T15:30:00.000Z",
  "meeting_type": "in_person",
  "source": "ai",
  "rescheduled_from": null,
  "rescheduled_to": null,
  "created_at": "2026-10-01T09:01:00.000Z",
  "version": 1,
  "updated_at": "2026-10-01T09:01:02.000Z"
}

List bookable services

GET /v1/booking_services

Lists every bookable service of the team in one response that is never paged and takes no limit or cursor. Bookable services are not in the changes feed: read this list when you start syncing a team, again when a booking names a service you do not know, and at least once a day. A deleted service drops out of the list while its bookings keep naming its id, so keep a service name you need from an earlier read.

Scopes
calendar:read
Rate limit
Sync

Headers

  • Totem-Team string Conditional ID prefix team_…

    The team to read, as a team_… id. Omit it when the key reads one team; it is required when the key reads several (400 team_required). When you send it, it must name a team the key reads: a malformed id gets 400 invalid_request, and a team outside the key gets 404 team_not_accessible, as does a request without it once the key reads no team at all.

Returns

Returns a list of BookingService objects.

  • object string

    Always list.

  • data Array<BookingService>

    Every bookable service of the team.

  • has_more boolean

    Always false: this list is never paged.

  • next_cursor null Nullable

    Always null: there is no next page.

Errors

+ 12 common errors

GET /v1/booking_services
curl 'https://api.totemstudio.ai/v1/booking_services' \
  -H "Authorization: Bearer $TOTEM_API_KEY" \
  -H "Totem-Team: $TOTEM_TEAM_ID"
Response · 200JSON
{
  "object": "list",
  "data": [
    {
      "id": "svc_h42kgwwJGPzsm2Zoy1A1RBv1KIrX5",
      "object": "booking_service",
      "livemode": false,
      "team": "team_r9uYrIW4gSFJJ6hZQ9ip1UIpPaAD1CF7NR",
      "name": "First visit",
      "meeting_type": "in_person"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

The Booking object

A booking and its kind: an appointment for a bookable service, an event from the connected calendar, or a booking imported from another system.

Attributes

  • id string ID prefix bkg_…

    Public id of the record.

  • object string

    Always booking.

  • livemode boolean

    true for real data; false in example data.

  • team string ID prefix team_…

    The team this record belongs to.

  • lead string Nullable ID prefix lead_…

    The lead this booking belongs to, or null for a booking without a lead or when the lead no longer exists. Names and contact details appear only on the lead.

  • kind string

    service_booking (booked for a bookable service, by the AI, a customer or a person), calendar_event (an event from the connected calendar) or external_import (synced from an external booking system or read from a portal email). A booking from an origin this version does not know is reported as calendar_event.

    Possible values
    • service_booking
    • calendar_event
    • external_import
  • service string Nullable ID prefix svc_…

    The booked service (see /booking_services) on a service_booking; null otherwise.

  • status string Nullable

    scheduled, rescheduled, cancelled, postponed, attended, no_show or team_no_show (attendance is recorded only by people); null for a value this version does not know. rescheduled means the booking was moved in place and its times are the new ones; a booking the AI replaced with a new one reads cancelled, with rescheduled_to set.

    Possible values
    • scheduled
    • rescheduled
    • cancelled
    • postponed
    • attended
    • no_show
    • team_no_show
  • starts_at string Nullable Format date-time

    When the booking starts (UTC).

  • ends_at string Nullable Format date-time

    When the booking ends (UTC).

  • meeting_type string Nullable

    online, in_person or phone; null when not stored.

    Possible values
    • online
    • in_person
    • phone
  • source string Nullable

    Who booked it: ai, customer or operator; null when not recorded.

    Possible values
    • ai
    • customer
    • operator
  • rescheduled_from string Nullable ID prefix bkg_…

    The booking this one replaced in a reschedule, or null. For a few seconds the replaced booking can still read scheduled; bookings rescheduled before Totem started recording this link may not have it.

  • rescheduled_to string Nullable ID prefix bkg_…

    The booking that replaced this one in a reschedule, or null. When it is set, this booking reads cancelled.

  • created_at string Nullable Format date-time

    When the booking was recorded in Totem (UTC).

  • version integer Range ≥ 1

    Increases every time one of the record's exported fields changes. Apply a change only when its version is greater than the one you hold.

  • updated_at string Format date-time

    When Totem recorded this version (UTC). It is not the time the business event happened.

Booking · exampleJSON
{
  "id": "bkg_r72EfbRNUzuqORFJR0O8HxAwEXd93jGUTYMaMMX3ttMKHRR9ADk3N7Cr3NSuY0",
  "object": "booking",
  "livemode": false,
  "team": "team_r9uYrIW4gSFJJ6hZQ9ip1UIpPaAD1CF7NR",
  "lead": "lead_r72EfbRNUzuqORFJR0O8HxAwEXd93jGUTYMaMMXKSF0QbLS8CiUKJpEP34LFQG",
  "kind": "service_booking",
  "service": "svc_h42kgwwJGPzsm2Zoy1A1RBv1KIrX5",
  "status": "scheduled",
  "starts_at": "2026-10-06T15:00:00.000Z",
  "ends_at": "2026-10-06T15:30:00.000Z",
  "meeting_type": "in_person",
  "source": "ai",
  "rescheduled_from": null,
  "rescheduled_to": null,
  "created_at": "2026-10-01T09:01:00.000Z",
  "version": 1,
  "updated_at": "2026-10-01T09:01:02.000Z"
}

The BookingService object

A service customers can book, with its meeting type.

Attributes

  • id string ID prefix svc_…

    Public id of the record.

  • object string

    Always booking_service.

  • livemode boolean

    true for real data; false in example data.

  • team string ID prefix team_…

    The team this record belongs to.

  • name string Nullable ≥ 1 chars

    The service's name, or null when none is stored.

  • meeting_type string

    How the service happens: online (the default when none is stored), in_person or phone.

    Possible values
    • online
    • in_person
    • phone
BookingService · exampleJSON
{
  "id": "svc_h42kgwwJGPzsm2Zoy1A1RBv1KIrX5",
  "object": "booking_service",
  "livemode": false,
  "team": "team_r9uYrIW4gSFJJ6hZQ9ip1UIpPaAD1CF7NR",
  "name": "First visit",
  "meeting_type": "in_person"
}

API version 1.0a