---
title: "Bookings and Catalog API Reference"
description: "Manage bookings, specialists, products and services through the Public API: read the calendar, create and update appointments, and sync Google Calendar."
canonical_url: https://chatfuel.com/docs/public-api/bookings-and-catalog
markdown_url: https://chatfuel.com/docs/public-api/bookings-and-catalog.md
last_updated: 2026-10-06
lang: en
site: https://chatfuel.com/docs
llms_txt: https://chatfuel.com/llms.txt
---

# Bookings and Catalog API Reference

Manage bookings, specialists, products and services through the Public API: read the calendar, create and update appointments, and sync Google Calendar.

The bookings and catalog part of the Chatfuel Public API covers what Fuely AI sells and schedules: products and services in the catalog, specialists with their working hours, and the bookings in the calendar. An integration can mirror bookings to another system, create appointments from a website or CRM, and keep the catalog in sync with a store. Reading works for **Agent** virtual users; creating and changing anything needs **Editor**.

## How to read bookings [#how-to-read-bookings]

```graphql
type Bot {
  # Agent. Bookings in the time range.
  bookingsV2(startTime: Time!, endTime: Time!): [BookingBase!]!
  bookingV2(id: BookingID!): BookingBase!
  # A booking contact without a chat, found by phone number.
  inlineContact(phoneNumber: String!): BookingInlineContact
}
```

```graphql
query Week($botID: BotID!) {
  bot(id: $botID) {
    bookingsV2(startTime: "2026-10-12T00:00:00Z", endTime: "2026-10-19T00:00:00Z") {
      id
      startTime
      endTime
      status          # Pending, Reschedule, Confirmed, Canceled, Attended, NoShow
      service { ... on GoodsService { id title } }
      specialist { id }
    }
  }
}
```

Times are RFC 3339 timestamps. A booking is linked either to an existing contact (`contactID`) or to an inline contact with a name and phone number, for people who booked without chatting with the bot.

## How to create and change bookings [#how-to-create-and-change-bookings]

```graphql
type Mutation {
  # Editor. Errors: BookingStartTimeRequired, BookingEndTimeRequired, BookingInvalidDuration,
  # BookingEndTimeBeforeStartTime, BookingContactPlatformNotAllowed
  bookingCreateV2(botID: BotID!, req: BookingInput!): BookingBase!
  bookingUpdateV2(botID: BotID!, id: BookingID!, req: BookingUpdateInput!): BookingBase!
  # Editor. Confirm, cancel or mark as attended or no-show.
  bookingStatusResolveV2(botID: BotID!, bookingID: BookingID!, status: BookingStatus!): BookingBase!
  bookingDeleteV2(botID: BotID!, id: BookingID!): BookingBase!
  # Editor. Errors: BookingInlineContactNoteTooLong
  bookingInlineContactSetNote(id: InlineContactID!, note: String): BookingInlineContact!
}

input BookingInput {
  contactID: ContactID                       # an existing contact, or
  inlineContact: BookingInlineContactInput   # { name, phoneNumber, note, countryCode }
  serviceID: GoodsItemID
  specialistID: SpecialistID
  startTime: Time!
  endTime: Time!
}
```

```graphql
mutation Book($botID: BotID!, $serviceID: GoodsItemID!, $specialistID: SpecialistID!) {
  bookingCreateV2(
    botID: $botID
    req: {
      inlineContact: { name: "Ana Souza", phoneNumber: "+5511999990000", countryCode: "BR" }
      serviceID: $serviceID
      specialistID: $specialistID
      startTime: "2026-10-14T13:00:00Z"
      endTime: "2026-10-14T14:00:00Z"
    }
  ) { id status }
}
```

## Booking subscriptions [#booking-subscriptions]

```graphql
type Subscription {
  # Agent.
  bookingAdded(botID: BotID!): Booking!
  bookingUpdated(botID: BotID!): Booking!
  bookingDeleted(botID: BotID!): BookingID!
}
```

## How to manage specialists [#how-to-manage-specialists]

Specialists are the people or resources a booking is made with, each with a profile, a weekly schedule and the services they provide. Read them with `bot.specialists` and `bot.specialist(id:)` (**Agent**).

```graphql
type Mutation {
  # Editor. Errors: SpecialistNameNotUnique, SpecialistFirstNameRequired, SpecialistFirstNameTooLong, …
  specialistCreate(botID: BotID!, info: SpecialistInfoInput!): Bot!
  specialistUpdate(botID: BotID!, specialistID: SpecialistID!, info: SpecialistInfoInput!): Specialist!
  specialistDelete(botID: BotID!, specialistID: SpecialistID!): Bot!
}

input SpecialistInfoInput {
  profile: SpecialistProfileInput!
  schedule: SpecialistScheduleInput!
  goodsServices: [GoodsItemID!]!
}
```

## How to connect a specialist's Google Calendar [#how-to-connect-a-specialists-google-calendar]

A specialist's Google Calendar keeps their availability in sync with the rest of their schedule. The calendar owner connects it through a link, so nobody shares Google credentials:

```graphql
type Mutation {
  # Editor. Creates a link the calendar owner opens to connect their Google Calendar.
  specialistCreateGoogleCalendarConnectionLink(botID: BotID!, specialistID: SpecialistID!): SpecialistGoogleCalendarLink!
  specialistDeleteGoogleCalendarConnectionLink(botID: BotID!, specialistID: SpecialistID!): Bot!
  # Editor. Starts a sync; follow its progress with taskUpdated. Errors: SpecialistDoesNotExist
  specialistStartGoogleCalendarSync(botID: BotID!, specialistID: SpecialistID!): Task!
  specialistDisconnectGoogleCalendar(botID: BotID!, specialistID: SpecialistID!, googleCalendarID: GoogleCalendarID!): Specialist!
}
```

`bot.availableGoogleCalendars`, the calendars of your own Google account, is **Personal token only**. [Files and tasks](https://chatfuel.com/docs/public-api/files-and-tasks) describes `Task` and `taskUpdated`.

## How to manage products and services [#how-to-manage-products-and-services]

The catalog holds products and services that Fuely AI can recommend and book. Read it with `bot.goodsCatalog`, `bot.goodsProduct(id:)` and `bot.goodsService(id:)` (**Agent**).

```graphql
type Mutation {
  # Editor. Errors: GoodsItemsTooMuchForBot, GoodsItemTitleRequired, GoodsItemTitleNotUnique,
  # GoodsItemTitleTooShort, GoodsItemTitleTooLong, GoodsItemDescriptionTooLong, …
  goodsProductCreate(botID: BotID!, product: GoodsProductInput!): Bot!
  goodsProductUpdate(botID: BotID!, itemID: GoodsItemID!, product: GoodsProductInput!): GoodsProduct!
  goodsProductDelete(botID: BotID!, itemID: GoodsItemID!): Bot!
  goodsServiceCreate(botID: BotID!, service: GoodsServiceInput!): Bot!
  goodsServiceUpdate(botID: BotID!, itemID: GoodsItemID!, service: GoodsServiceInput!): GoodsService!
  goodsServiceDelete(botID: BotID!, itemID: GoodsItemID!): Bot!
}

input GoodsProductInput {
  title: String!
  description: String!
  price: GoodsItemPriceInput      # { amount: "199.90", currency: … }
  images: [FileID!]!
  isAvailable: Boolean!
}

input GoodsServiceInput {
  title: String!
  description: String!
  price: GoodsItemPriceInput
  images: [FileID!]!
  durationSeconds: Int!
  isAvailable: Boolean!
}
```

Upload product images first, as described in [making requests](https://chatfuel.com/docs/public-api/requests), and pass their file IDs in `images`. Titles must be unique within the catalog. Update mutations replace the whole item, so send every field.

## Common issues [#common-issues]

### "BookingContactPlatformNotAllowed" [#bookingcontactplatformnotallowed]

The contact is on a channel bookings don't support. Use a contact from a supported channel, or book with an `inlineContact` by phone number.

### "GoodsItemTitleNotUnique" [#goodsitemtitlenotunique]

Another product or service already has this title. Titles are compared within the whole catalog of the bot.

### "NotEnoughPermissions" when an Agent creates a booking [#notenoughpermissions-when-an-agent-creates-a-booking]

Agents can read bookings, specialists and the catalog but can't change them. Use an Editor virtual user.
