---
title: "Referencia de la API de reservas y catálogo"
description: "Gestiona reservas, especialistas, productos y servicios con la Public API: lee el calendario, crea y actualiza citas y sincroniza Google Calendar."
canonical_url: https://chatfuel.com/es/docs/public-api/bookings-and-catalog
markdown_url: https://chatfuel.com/es/docs/public-api/bookings-and-catalog.md
last_updated: 2026-10-06
lang: es
site: https://chatfuel.com/docs
llms_txt: https://chatfuel.com/llms.txt
---

# Referencia de la API de reservas y catálogo

Gestiona reservas, especialistas, productos y servicios con la Public API: lee el calendario, crea y actualiza citas y sincroniza Google Calendar.

La parte de reservas y catálogo de la Public API de Chatfuel cubre lo que Fuely AI vende y agenda: los productos y servicios del catálogo, los especialistas con su horario de trabajo y las reservas del calendario. Una integración puede replicar las reservas en otro sistema, crear citas desde un sitio web o un CRM y mantener el catálogo sincronizado con una tienda. La lectura funciona para usuarios virtuales **Agent**; para crear o cambiar cualquier cosa se necesita **Editor**.

## Cómo leer las reservas [#cómo-leer-las-reservas]

```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 }
    }
  }
}
```

Las horas son marcas de tiempo RFC 3339. Una reserva está vinculada a un contacto existente (`contactID`) o a un contacto inline con nombre y número de teléfono, para las personas que reservaron sin chatear con el bot.

## Cómo crear y cambiar reservas [#cómo-crear-y-cambiar-reservas]

```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 }
}
```

## Suscripciones de reservas [#suscripciones-de-reservas]

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

## Cómo gestionar especialistas [#cómo-gestionar-especialistas]

Los especialistas son las personas o los recursos con los que se hace una reserva, cada uno con un perfil, un horario semanal y los servicios que ofrece. Léelos con `bot.specialists` y `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!]!
}
```

## Cómo conectar el Google Calendar de un especialista [#cómo-conectar-el-google-calendar-de-un-especialista]

El Google Calendar de un especialista mantiene su disponibilidad sincronizada con el resto de su agenda. El dueño del calendario lo conecta mediante un enlace, así nadie comparte credenciales de Google:

```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`, que devuelve los calendarios de tu propia cuenta de Google, es **Solo token personal**. [Archivos y tareas](https://chatfuel.com/es/docs/public-api/files-and-tasks) describe `Task` y `taskUpdated`.

## Cómo gestionar productos y servicios [#cómo-gestionar-productos-y-servicios]

El catálogo contiene los productos y servicios que Fuely AI puede recomendar y reservar. Léelo con `bot.goodsCatalog`, `bot.goodsProduct(id:)` y `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!
}
```

Primero sube las imágenes de los productos, como se describe en [cómo hacer solicitudes](https://chatfuel.com/es/docs/public-api/requests), y pasa sus IDs de archivo en `images`. Los títulos deben ser únicos dentro del catálogo. Las mutaciones de actualización reemplazan el elemento completo, así que envía todos los campos.

## Problemas comunes [#problemas-comunes]

### "BookingContactPlatformNotAllowed" [#bookingcontactplatformnotallowed]

El contacto está en un canal que no admite reservas. Usa un contacto de un canal compatible o reserva con un `inlineContact` por número de teléfono.

### "GoodsItemTitleNotUnique" [#goodsitemtitlenotunique]

Otro producto o servicio ya tiene este título. Los títulos se comparan dentro de todo el catálogo del bot.

### "NotEnoughPermissions" cuando un Agent crea una reserva [#notenoughpermissions-cuando-un-agent-crea-una-reserva]

Un usuario virtual Agent puede leer reservas, especialistas y el catálogo, pero no puede cambiarlos. Usa un usuario virtual Editor.
