Saltar al contenido
GuestMakerDesarrolladores
Vista generalDocumentaciónEventosSDKSandboxNovedades
EN/ES
Solicitar acceso
Vista generalDocumentaciónEventosSDKSandboxNovedades
Solicitar acceso

Documentación

NovedadesProbar el sandbox

Desarrolla con GuestMaker

Documentación de la API

Autentica tu integración, sincroniza datos de huéspedes y reservas y recibe actualizaciones mediante webhooks.

Versión 1.0 de la API
URL base: www.guestmaker.ai
En esta página
Inicio rápidoAutenticaciónAPI de reservasAPI de huéspedesAPI de eventosAPI de campos personalizadosAPI de CDPAPI de fidelizaciónSuscripción a la newsletterWebhooksCTI / TelefoníaModelos de datosCRM B2BGestión de erroresLímites de solicitudesBuenas prácticas

Inicio rápido

Crea una clave de API, elige tu hotel y envía tu primera solicitud.

1

Obtén tus credenciales de API

Solicita acceso a la API mediante nuestro formulario para socios o contacta con tu responsable de cuenta. Recibirás:

  • Una clave de API que empieza por gmkr_
  • Los ID de tus hoteles desde Ajustes → Hoteles
  • Documentación de los permisos disponibles
2

Realiza tu primera llamada a la API

Crea una reserva con los datos del huésped. Esta llamada crea la reserva, vincula los huéspedes a un hotel y activa recorridos automáticos.

curl -X POST https://www.guestmaker.ai/api/v1/reservations \
  -H "Authorization: Bearer gmkr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "reservation_id": "RES-2026-001234",
    "confirmation_number": "CONF-ABC123",
    "hotel_name": "Grand Hotel",
    "check_in": "2026-03-15",
    "check_out": "2026-03-18",
    "status": "confirmed",
    "source": "pms",
    "amount": 450.00,
    "amount_net": 371.90,
    "currency": "EUR",
    "channel": "booking.com",
    "market_segment": "LEISURE",
    "agency_code": "AGY-001",
    "external_created_at": "2026-01-20T14:30:00+01:00",
    "external_updated_at": "2026-02-05T09:15:00+01:00",
    "guests": [
      {
        "first_name": "John",
        "last_name": "Doe",
        "email": "john@example.com",
        "phone": "+1234567890",
        "is_holder": true,
        "pax_type": "adult",
        "opt_in_status": "opted_in",
        "nationality": "US",
        "language": "en",
        "document_type": "passport",
        "document_number": "AB1234567"
      },
      {
        "first_name": "Jane",
        "last_name": "Doe",
        "pax_type": "adult"
      }
    ],
    "stays": [
      {
        "start_date": "2026-03-15",
        "end_date": "2026-03-18",
        "room_type": "Deluxe Suite",
        "room_number": "301",
        "board_type": "BB",
        "adults": 2
      }
    ]
  }'

3

Comprueba la respuesta

Una respuesta correcta incluye el ID del contacto y el ID del evento:

{
  "success": true,
  "data": {
    "reservation_id": "550e8400-e29b-41d4-a716-446655440002",
    "contact_id": "550e8400-e29b-41d4-a716-446655440000",
    "hotel_id": "550e8400-e29b-41d4-a716-446655440001",
    "is_new_contact": true,
    "event_id": "550e8400-e29b-41d4-a716-446655440003",
    "message": "Reservation created successfully"
  }
}

4

Configura webhooks (opcional)

Configura endpoints de webhook en tu panel para recibir avisos en tiempo real cuando los huéspedes respondan o terminen los recorridos.

5

Explora toda la API

Sigue leyendo para conocer los eventos, webhooks, gestión de errores y buenas prácticas para integraciones en producción.

Probar en el sandboxSolicitar acceso a la API

Autenticación

Las solicitudes de la API principal v1 requieren autenticación con un token Bearer en la cabecera Authorization.

Authorization: Bearer gmkr_your_api_key

Formato de la clave de API

Las claves de la API principal tienen el prefijo gmkr_. Recibes tu clave de API al configurar la integración con nosotros.

Permisos disponibles

AlcanceDescripción
guests:readLeer datos de huéspedes y contactos
guests:writeCrear o actualizar huéspedes con reservas
events:writeEnviar eventos para activar recorridos
bookings:readLeer datos de reservas
reservations:writeCrear o actualizar reservas mediante API
conversions:writeInformar de conversiones de reservas para atribuirlas a campañas
custom_fields:writeRegistrar y leer definiciones de campos personalizados
webhooks:manageConfigurar webhooks salientes
cdp:readLeer perfiles y datos de reservas de CDP
cdp:writeIncorporar reservas a la plataforma de datos de clientes
b2b:readLeer cuentas y oportunidades B2B
b2b:writeCrear o actualizar cuentas, contactos y oportunidades B2B
surveys:writeEnviar respuestas de encuestas antiguas de Hotelinking a Encuestas
*Acceso completo (todos los permisos)

Buenas prácticas de seguridad

  • Nunca expongas una clave de API secreta en código del cliente. La excepción es una clave pública de navegador (gme_pk_…) para eventos web: está diseñada para incluirse en una página y solo funciona desde los sitios web que permitas.
  • Guarda tu clave de API en variables de entorno
  • Rota tu clave de API periódicamente
  • Usa listas de IP permitidas cuando sea posible
  • Solicita solo los permisos que necesites

Protege tu clave de API

Tu clave de API da acceso a los datos de tu cuenta. Trátala como una contraseña y nunca la compartas públicamente.

API de reservas

Crea y actualiza reservas desde tu PMS o motor de reservas. Admite varios huéspedes por reserva, estancias por habitación y extras. Diseñada para integraciones empresariales de PMS con sincronización completa de datos.

Permiso obligatorio

reservations:write

Cuerpo de la solicitud

ParámetroTipoObligatorioDescripción
reservation_idstring
Obligatorio
ID único de reserva de tu PMS (se usa para identificar la reserva al insertar o actualizar)
confirmation_numberstringOpcionalCódigo de confirmación o localizador (puede compartirse entre reservas)
booking_idstringOpcionalID de reserva principal (para agrupar varias reservas)
hotel_idstringOpcionalUUID del hotel (se requiere hotel_id, hotel_code o hotel_name)
hotel_codestringOpcionalCódigo del hotel (alternativa a hotel_id)
hotel_namestringOpcionalNombre del hotel (alternativa a hotel_id)
check_instring
Obligatorio
Fecha de entrada (YYYY-MM-DD)
check_outstring
Obligatorio
Fecha de salida (YYYY-MM-DD)
booking_datestringOpcionalFecha en que se hizo la reserva (YYYY-MM-DD)
statusstringOpcionalEstado de reserva: confirmed, pending (motor de reservas a la espera de confirmación de pago), modified, cancelled, no_show, checked_in, checked_out
channelstringOpcionalCanal de reserva (p. ej., booking.com, expedia, direct)
sourcestringOpcionalTipo de sistema que envió los datos: pms, booking_engine, crm, channel_manager, website, etc. Por defecto, "api"
companystringOpcionalEmpresa de la reserva corporativa
amountnumberOpcionalImporte total de la reserva (bruto)
amount_netnumberOpcionalImporte total de la reserva (neto, antes de impuestos)
currencystringOpcionalCódigo de moneda ISO 4217 (p. ej., EUR, USD)
market_segmentstringOpcionalCódigo de segmento de mercado del PMS (p. ej., "LEISURE", "CORPORATE")
agencystringOpcionalNombre de la agencia, turoperador u OTA que vende (p. ej., "BOOKING.COM", "EASYJET HOLIDAYS"). Máx. 200 caracteres
agency_codestringOpcionalCódigo de agencia de viajes del PMS, cuando la fuente lo envía. Máx. 100 caracteres
nightsnumberOpcionalNúmero de noches (se acepta, pero no se guarda: se calcula automáticamente a partir de las fechas)
external_created_atstringOpcionalMarca de tiempo de creación en el PMS (ISO 8601 con zona horaria)
external_updated_atstringOpcionalMarca de tiempo de última actualización en el PMS (ISO 8601 con zona horaria)
guestsarray
Obligatorio
Array de huéspedes (1-20). Consulta el objeto Guest más abajo.
staysarrayOpcionalArray de estancias por habitación (máx. 10). Consulta el objeto Stay más abajo.
extrasarrayOpcionalArray de extras y cargos (máx. 100). Consulta el objeto Extra más abajo.
commentsstringOpcionalNotas internas o solicitudes especiales
metadataobjectOpcionalDatos personalizados de clave y valor

Objeto Guest

ParámetroTipoObligatorioDescripción
first_namestring
Obligatorio
Nombre del huésped
last_namestringOpcionalApellidos del huésped
emailstringOpcionalDirección de correo electrónico del huésped. Se requiere email o phone para crear o identificar un contacto.
phonestringOpcionalNúmero de teléfono en formato E.164. Se requiere email o phone para crear o identificar un contacto.
is_holderbooleanOpcionalSi es el huésped principal o quien hace la reserva
pax_typestringOpcionalTipo de pasajero: adult, child, infant
date_of_birthstringOpcionalFecha de nacimiento (YYYY-MM-DD)
genderstringOpcionalGénero del huésped: male, female, other, prefer_not_to_say
nationalitystringOpcionalCódigo de país ISO 3166-1 alpha-2
document_typestringOpcionalTipo de documento de identidad: passport, national_id, drivers_license, other
document_numberstringOpcionalNúmero del documento de identidad (máx. 50 caracteres)
addressobjectOpcionalDirección postal del huésped. Todos los subcampos son opcionales: street (máx. 300), city (200), postal_code (40), province (200), state (200), country (ISO 3166-1 alpha-2 o alpha-3, normalizado a alpha-2). Los valores largos se truncan y los no reconocidos se descartan: una dirección mal formada nunca provoca el rechazo de la reserva. Los subcampos omitidos se mantienen sin cambios, en lugar de borrarse. En España, province es el código INE de dos dígitos ("07" para Baleares). Aquí country es el país de RESIDENCIA, no la nacionalidad.
email_consentbooleanOpcionalConsentimiento de marketing por correo electrónico comunicado por el PMS. Tiene prioridad sobre la configuración de consentimiento automático de CDP.
whatsapp_marketing_consentbooleanOpcionalConsentimiento de marketing por WhatsApp o teléfono comunicado por el PMS. Tiene prioridad sobre la configuración de consentimiento automático de CDP.
languagestringOpcionalCódigo de idioma del huésped (p. ej., "en", "es", "fr"). Por defecto, "en" para contactos nuevos.
pre_checkin_completed_atstringOpcionalMarca de tiempo ISO 8601 (con desplazamiento horario) en que este huésped completó el registro previo u online en el portal del PMS o motor de reservas. Omítela o envía null si aún no lo ha completado.
pre_checkin_sourcestringOpcionalDónde se completó el registro previo (p. ej., "mews", "cloudbeds", "apaleo", "self_service"). Máx. 50 caracteres.

Objeto Stay

ParámetroTipoObligatorioDescripción
start_datestring
Obligatorio
Fecha de inicio de estancia (YYYY-MM-DD)
end_datestring
Obligatorio
Fecha de fin de estancia (YYYY-MM-DD)
room_typestringOpcionalTipo o categoría de habitación
room_numberstringOpcionalNúmero de habitación asignada
board_typestringOpcionalRégimen: RO (solo alojamiento), BB (alojamiento y desayuno), HB (media pensión), FB (pensión completa), AI (todo incluido)
rate_codestringOpcionalCódigo o plan de tarifa
adultsnumberOpcionalNúmero de adultos
childrennumberOpcionalNúmero de niños
babiesnumberOpcionalNúmero de bebés

Objeto Extra

ParámetroTipoObligatorioDescripción
namestring
Obligatorio
Descripción del cargo
amountnumber
Obligatorio
Importe del cargo
codestringOpcionalCódigo del cargo del PMS
quantitynumberOpcionalCantidad (por defecto: 1)
datestringOpcionalFecha del cargo (YYYY-MM-DD)
notesstringOpcionalNotas adicionales

Ejemplo de solicitud

curl -X POST https://www.guestmaker.ai/api/v1/reservations \
  -H "Authorization: Bearer gmkr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "reservation_id": "RES-2026-001234",
    "confirmation_number": "CONF-ABC123",
    "hotel_name": "Grand Hotel",
    "check_in": "2026-03-15",
    "check_out": "2026-03-18",
    "status": "confirmed",
    "source": "pms",
    "amount": 450.00,
    "amount_net": 371.90,
    "currency": "EUR",
    "channel": "booking.com",
    "market_segment": "LEISURE",
    "agency_code": "AGY-001",
    "external_created_at": "2026-01-20T14:30:00+01:00",
    "external_updated_at": "2026-02-05T09:15:00+01:00",
    "guests": [
      {
        "first_name": "John",
        "last_name": "Doe",
        "email": "john@example.com",
        "phone": "+1234567890",
        "is_holder": true,
        "pax_type": "adult",
        "opt_in_status": "opted_in",
        "nationality": "US",
        "language": "en",
        "document_type": "passport",
        "document_number": "AB1234567"
      },
      {
        "first_name": "Jane",
        "last_name": "Doe",
        "pax_type": "adult"
      }
    ],
    "stays": [
      {
        "start_date": "2026-03-15",
        "end_date": "2026-03-18",
        "room_type": "Deluxe Suite",
        "room_number": "301",
        "board_type": "BB",
        "adults": 2
      }
    ]
  }'

Respuesta

{
  "success": true,
  "data": {
    "reservation_id": "550e8400-e29b-41d4-a716-446655440000",
    "external_reservation_id": "RES-2026-001234",
    "is_new": true,
    "hotel_id": "550e8400-e29b-41d4-a716-446655440001",
    "contacts": [
      {
        "contact_id": "550e8400-e29b-41d4-a716-446655440002",
        "phone": "+1234567890",
        "email": "john@example.com",
        "is_new": true,
        "is_holder": true
      },
      {
        "contact_id": null,
        "phone": null,
        "email": null,
        "is_new": false,
        "is_holder": false
      }
    ],
    "warnings": []
  }
}

Creación de contactos

Los huéspedes con un teléfono válido se crean como contactos en GuestMaker. Los huéspedes sin teléfono se guardan en la reserva, pero no pueden recibir mensajes de WhatsApp. La respuesta indica qué huéspedes se han creado como contactos mediante contact_id.

Comportamiento de inserción y actualización

El campo reservation_id es el identificador único de tu PMS. Enviar de nuevo el mismo reservation_id actualiza la reserva existente sin duplicarla. Sincroniza desde tu PMS sin llevar un registro de las reservas ya existentes.

Valores de estado de reserva
Valores de estado y su significado
EstadoDescripciónEtapa del huésped
confirmedReserva confirmadaAntes de la llegada
pendingMotor de reservas a la espera de confirmación de pagoAntes de la llegada
modifiedReserva modificada tras la confirmaciónAntes de la llegada
checked_inEl huésped ha llegadoAlojado
checked_outEl huésped ha salidoDespués de la estancia
cancelledReserva canceladaNo aplicable
no_showEl huésped no se ha presentadoNo aplicable

API de huéspedes

Crea y gestiona contactos de huéspedes con sus datos de reserva. Se vinculan automáticamente a hoteles para conversaciones con IA y automatización de recorridos.

Cuerpo de la solicitud

ParámetroTipoObligatorioDescripción
phonestring
Obligatorio
Número de teléfono en formato E.164 (p. ej., +1234567890)
first_namestring
Obligatorio
Nombre del huésped
last_namestring
Obligatorio
Apellidos del huésped
emailstringOpcionalDirección de correo electrónico del huésped
languagestringOpcionalCódigo de idioma preferido (p. ej., en, es, fr). Por defecto: en
tagsstring[]OpcionalArray de etiquetas para segmentación
custom_fieldsobjectOpcionalPares de clave y valor que coincidan con tus definiciones registradas de campos personalizados. Consulta la configuración en la API de campos personalizados.
hotel_namestringOpcionalNombre del hotel al que vincular el huésped
hotel_codestringOpcionalCódigo del hotel (alternativa a hotel_name)
sourcestringOpcionalTipo de sistema que envió los datos: pms, booking_engine, crm, channel_manager, website, etc. Por defecto, "api"
bookingobjectOpcionalDatos de la reserva (ver más abajo)
trigger_eventbooleanOpcionalActivar el evento booking.created (por defecto: true)
update_if_existsbooleanOpcionalActualizar el contacto existente por teléfono (por defecto: true)
opt_in_statusstringOpcionalCampo antiguo (obsoleto). Usa whatsapp_marketing_consent.
whatsapp_marketing_consentbooleanOpcionalConsentimiento de marketing por WhatsApp (por defecto: false). Si es true, el huésped recibe mensajes de marketing por WhatsApp.
email_consentbooleanOpcionalConsentimiento de marketing por correo electrónico (por defecto: false). Si es true, el huésped recibe correos de marketing.
date_of_birthstringOpcionalFecha de nacimiento del huésped (YYYY-MM-DD)
genderstringOpcionalGénero del huésped: male, female, other, prefer_not_to_say
nationalitystringOpcionalCódigo de país ISO 3166-1 alpha-2 (p. ej., US, ES, GB)
document_typestringOpcionalTipo de documento de identidad: passport, national_id, drivers_license, other
document_numberstringOpcionalNúmero del documento de identidad (máx. 50 caracteres)
addressobjectOpcionalDirección postal del huésped. Todos los subcampos son opcionales: street (máx. 300), city (200), postal_code (40), province (200), state (200), country (ISO 3166-1 alpha-2 o alpha-3, normalizado a alpha-2). Los valores largos se truncan y los no reconocidos se descartan: una dirección mal formada nunca provoca el rechazo de la solicitud. Los subcampos omitidos se mantienen sin cambios, en lugar de borrarse. En España, province es el código INE de dos dígitos ("07" para Baleares). Aquí country es el país de RESIDENCIA, no la nacionalidad.
subscription_statusstringOpcionalEstado de suscripción a comunicaciones: active, unsubscribed
communication_preferencesobjectOpcionalPreferencias de comunicación detalladas (ver más abajo)
consent_sourcestringOpcionalTu identificador del lugar donde se obtuvo el consentimiento
consent_timestampstringOpcionalMarca de tiempo ISO 8601 de cuándo se dio el consentimiento

Objeto Booking

ParámetroTipoObligatorioDescripción
booking_idstring
Obligatorio
ID de reserva principal (agrupa varias reservas, p. ej., una reserva de Expedia con 4 habitaciones)
reservation_idstringOpcionalCódigo de reserva o localizador individual (por defecto, booking_id si no se indica)
check_instring
Obligatorio
Fecha de entrada (YYYY-MM-DD)
check_outstring
Obligatorio
Fecha de salida (YYYY-MM-DD)
room_typestringOpcionalTipo o categoría de habitación
room_numberstringOpcionalNúmero de habitación asignada (si se conoce)
rate_planstringOpcionalNombre del plan de tarifa
board_typestringOpcionalRégimen: RO (solo alojamiento), BB (alojamiento y desayuno), HB (media pensión), FB (pensión completa), AI (todo incluido)
booking_channelstringOpcionalCódigo de canal original del PMS (p. ej., BDC, EXP). Se guarda como booking_channel_code. Se resuelve automáticamente a un nombre legible y tipo de canal (direct/ota/tour_operator) si la cuenta tiene asignaciones configuradas.
total_amountnumberOpcionalImporte total de la reserva
currencystringOpcionalCódigo de moneda (por defecto: EUR)
statusstringOpcionalConfirmed, Modified, CheckedIn, CheckedOut, Cancelled, NoShow
guestsarrayOpcionalHuéspedes adicionales de la reserva (consulta Huéspedes de la reserva más abajo)
extrasarrayOpcionalExtras de la reserva, como spa, minibar o restaurante (consulta Extras de la reserva más abajo)

Array de huéspedes de la reserva

ParámetroTipoObligatorioDescripción
first_namestring
Obligatorio
Nombre del huésped
last_namestringOpcionalApellidos del huésped
emailstringOpcionalDirección de correo electrónico del huésped
is_holderbooleanOpcionalSi este huésped es el titular de la reserva (por defecto: false)
pax_typestringOpcionalAdult, Child o Infant
relationship_to_holderstringOpcionalSpouse, Child, Colleague, Friend, etc.
pre_checkin_completed_atstringOpcionalMarca de tiempo ISO 8601 (con desplazamiento horario) en que este acompañante completó el registro previo u online.
pre_checkin_sourcestringOpcionalDónde se completó el registro previo (p. ej., "mews", "cloudbeds", "self_service"). Máx. 50 caracteres.

Array de extras de la reserva

ParámetroTipoObligatorioDescripción
namestring
Obligatorio
Nombre del extra (p. ej., servicios de spa, minibar, restaurante)
amountnumber
Obligatorio
Importe cobrado
quantitynumberOpcionalCantidad (por defecto: 1)
notesstringOpcionalNotas o descripción adicionales

Objeto de preferencias de comunicación (antiguo)

Preferencias de comunicación antiguas. Es preferible usar los campos booleanos whatsapp_marketing_consent y email_consent directamente en el objeto del huésped.

ParámetroTipoObligatorioDescripción
marketingbooleanOpcionalConsentimiento para recibir mensajes de marketing (promociones, ofertas). Por defecto: false. Se asigna a whatsapp_marketing_consent.
utilitybooleanOpcionalLos mensajes de utilidad (confirmaciones de reserva, recordatorios) siempre se entregan. Este campo se ignora.

Nota: Cuando un huésped se da de baja mediante el chat de WhatsApp, puede dejar de recibir todas las comunicaciones o solo los mensajes de marketing, manteniendo los de utilidad.

Ejemplo de solicitud

curl -X POST https://www.guestmaker.ai/api/v1/guests \
  -H "Authorization: Bearer gmkr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+1234567890",
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@example.com",
    "nationality": "US",
    "document_type": "passport",
    "document_number": "AB1234567",
    "source": "pms",
    "hotel_name": "Grand Hotel",
    "booking": {
      "booking_id": "BK-12345",
      "check_in": "2026-03-15",
      "check_out": "2026-03-18",
      "room_type": "Deluxe Suite",
      "total_amount": 450.00,
      "status": "Confirmed"
    }
  }'

Respuesta

{
  "success": true,
  "data": {
    "contact_id": "550e8400-e29b-41d4-a716-446655440000",
    "is_new": true,
    "hotel_id": "550e8400-e29b-41d4-a716-446655440001",
    "reservation_id": "550e8400-e29b-41d4-a716-446655440002",
    "event_id": "550e8400-e29b-41d4-a716-446655440003",
    "message": "Guest created successfully"
  }
}

API de eventos

Envía eventos para activar recorridos automáticos. Se comparan con los activadores de los recorridos activos para iniciar conversaciones automatizadas de WhatsApp.

Cuerpo de la solicitud

ParámetroTipoObligatorioDescripción
event_typestring
Obligatorio
Identificador del tipo de evento (p. ej., guest.checked_in)
payloadobject
Obligatorio
Datos del evento disponibles en el contexto del recorrido
contact_idstringOpcionalUUID del contacto (si se conoce)
guest_phonestringOpcionalNúmero de teléfono para identificar al contacto (E.164)
hotel_idstringOpcionalUUID del hotel (si se conoce)
hotel_namestringOpcionalNombre del hotel para resolver hotel_id
hotel_codestringOpcionalCódigo del hotel para resolver hotel_id
idempotency_keystringOpcionalClave única para evitar eventos duplicados
sourcestringOpcionalIdentificador del sistema de origen para seguimiento

Tipos de evento estándar

El sistema reconoce estos tipos de evento estándar. También puedes crear tipos personalizados.

booking.created

Nueva reserva recibida

booking.updated

Reserva modificada

booking.cancelled

Reserva cancelada

guest.checked_in

Huésped llegado

guest.checked_out

Huésped salido

guest.message

El huésped ha enviado un mensaje

payment.received

Pago confirmado

review.requested

Reseña solicitada

Los tipos de evento personalizados deben seguir el patrón category.action (por ejemplo, spa.appointment_booked)

Ejemplo de solicitud

curl -X POST https://www.guestmaker.ai/api/v1/events \
  -H "Authorization: Bearer gmkr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "guest.checked_in",
    "guest_phone": "+1234567890",
    "hotel_name": "Grand Hotel",
    "payload": {
      "room_number": "301",
      "checked_in_at": "2026-03-15T14:30:00Z"
    },
    "idempotency_key": "checkin-BK-12345"
  }'

Respuesta

{
  "success": true,
  "data": {
    "event_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "accepted",
    "contact_id": "550e8400-e29b-41d4-a716-446655440001",
    "hotel_id": "550e8400-e29b-41d4-a716-446655440002",
    "matching_journeys": 2,
    "created_at": "2026-03-15T14:30:00Z",
    "message": "Event accepted and queued for processing"
  }
}

Idempotencia

Incluye siempre un idempotency_key para evitar eventos duplicados. Si envías la misma clave de idempotencia dos veces, la segunda solicitud devuelve el evento original.

API de campos personalizados

Define campos personalizados para ampliar los perfiles de huéspedes con datos de tu integración. Estos campos aparecen en el editor de segmentos, para que los equipos del hotel creen segmentos específicos a partir de tus datos.

Permiso obligatorio

custom_fields:write

Cuerpo de la solicitud

ParámetroTipoObligatorioDescripción
fieldsarray
Obligatorio
Array de definiciones de campos (máx. 50)
fields[].field_keystring
Obligatorio
Clave única (minúsculas, a-z, 0-9, guiones bajos; debe empezar por una letra)
fields[].field_labelstring
Obligatorio
Etiqueta visible para el personal del hotel
fields[].field_typestring
Obligatorio
Uno de: string, text, number, boolean, date, datetime, select, multiselect
fields[].optionsstring[]OpcionalObligatorio para tipos select/multiselect
fields[].descriptionstringOpcionalTexto de ayuda para el personal del hotel
fields[].is_requiredbooleanOpcionalSi el campo debe tener un valor (por defecto: false)
fields[].is_visiblebooleanOpcionalMostrar en la interfaz de datos del contacto (por defecto: true)
fields[].display_ordernumberOpcionalOrden dentro de tus campos (por defecto: 0)

Ejemplo de solicitud

curl -X POST https://www.guestmaker.ai/api/v1/fields \
  -H "Authorization: Bearer gmkr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": [
      {
        "field_key": "loyalty_tier",
        "field_label": "Loyalty Tier",
        "field_type": "select",
        "options": ["Bronze", "Silver", "Gold", "Platinum"],
        "description": "Guest loyalty program tier"
      },
      {
        "field_key": "loyalty_points",
        "field_label": "Loyalty Points",
        "field_type": "number",
        "description": "Current loyalty point balance"
      },
      {
        "field_key": "member_since",
        "field_label": "Member Since",
        "field_type": "date"
      }
    ]
  }'

Respuesta

{
  "success": true,
  "data": {
    "fields": [
      { "field_key": "loyalty_tier", "field_label": "Loyalty Tier", "field_type": "select", "created_at": "2026-01-31T10:00:00Z", "updated_at": "2026-01-31T10:00:00Z" },
      { "field_key": "loyalty_points", "field_label": "Loyalty Points", "field_type": "number", "created_at": "2026-01-31T10:00:00Z", "updated_at": "2026-01-31T10:00:00Z" },
      { "field_key": "member_since", "field_label": "Member Since", "field_type": "date", "created_at": "2026-01-31T10:00:00Z", "updated_at": "2026-01-31T10:00:00Z" }
    ],
    "message": "3 field definition(s) created/updated successfully"
  }
}

Integración con segmentos

Los campos personalizados establecidos mediante la API de huéspedes (objeto custom_fields) se almacenan automáticamente según las definiciones de campo correspondientes. El personal del hotel puede usarlos en el editor de segmentos, en la categoría «Campos personalizados», para crear audiencias específicas.

Referencia de tipos de campo
Tipos de campo admitidos y sus valores esperados
TipoDescripciónValor de ejemplo
stringTexto corto (una línea)"John Doe"
textTexto largo (varias líneas)"Special dietary requirements..."
numberValor numérico1500
booleanTrue/falsetrue
dateFecha (YYYY-MM-DD)"2026-03-15"
datetimeFecha y hora (ISO 8601)"2026-03-15T14:30:00Z"
selectUna opción de la lista"Gold"
multiselectVarias opciones de la lista["spa", "golf"]

API de CDP

La API de la plataforma de datos de clientes permite seguir visitantes anónimos, resolver identidades e incorporar reservas tras completar la compra. Sigue a los visitantes del sitio web, vincúlalos a identidades conocidas e incorpora datos de reservas para consolidar perfiles en tu grupo hotelero.

SDK GuestMaker.js

Para el seguimiento web, usa el SDK GuestMaker.js, que gestiona los ID de visitante, los lotes de eventos y el seguimiento automático de páginas vistas. Consulta las instrucciones de configuración en la página de SDK.

Restricciones de dominio

Si hay restricciones de dominio en los ajustes de CDP, el endpoint de eventos valida la cabecera Origin frente a la lista de dominios permitidos. Las solicitudes de orígenes no permitidos se rechazan con un error 403.

Permiso obligatorio

cdp:write

Requiere activar el seguimiento de visitantes en los ajustes de CDP.

Cuerpo de la solicitud

ParámetroTipoObligatorioDescripción
visitor_idstring
Obligatorio
Identificador del visitante anónimo (de la cookie del SDK)
session_idstring
Obligatorio
Identificador de sesión (de sessionStorage del SDK)
deviceobjectOpcional{ type: "desktop"|"mobile"|"tablet", browser, os, language }
utmobjectOpcional{ source, medium, campaign, term, content }
referrerstringOpcionalURL de referencia HTTP
eventsarray
Obligatorio
Array de objetos de evento (1-100). Consulta el objeto Event más abajo.

Objeto Event

ParámetroTipoObligatorioDescripción
typestring
Obligatorio
Tipo de evento: page_view, scroll, click, form_start, form_submit, identify, custom
urlstringOpcionalURL de la página (se elimina el dominio en el servidor por privacidad)
titlestringOpcionalTítulo de la página
dataobjectOpcionalDatos personalizados del evento (p. ej., profundidad de desplazamiento, elemento pulsado)
tsstring
Obligatorio
Marca de tiempo ISO 8601

Ejemplo de solicitud

curl -X POST https://www.guestmaker.ai/api/v1/cdp/events \
  -H "Authorization: Bearer gmkr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "visitor_id": "vis_abc123def456",
    "session_id": "sess_789xyz",
    "device": {
      "type": "desktop",
      "browser": "Chrome 120",
      "os": "Windows 11",
      "language": "en-US"
    },
    "utm": {
      "source": "google",
      "medium": "cpc",
      "campaign": "summer-2026"
    },
    "referrer": "https://www.google.com/search?q=luxury+hotels",
    "events": [
      {
        "type": "page_view",
        "url": "/rooms/deluxe-suite",
        "title": "Deluxe Suite | Grand Hotel",
        "ts": "2026-02-19T14:30:00.000Z"
      },
      {
        "type": "scroll",
        "url": "/rooms/deluxe-suite",
        "data": { "depth": 75 },
        "ts": "2026-02-19T14:30:45.000Z"
      },
      {
        "type": "click",
        "url": "/rooms/deluxe-suite",
        "data": { "element": "book-now-btn", "text": "Book Now" },
        "ts": "2026-02-19T14:31:02.000Z"
      }
    ]
  }'

Respuesta (202 Accepted)

{
  "success": true,
  "data": {
    "accepted": 3
  }
}

API de fidelización

El programa de fidelización ofrece dos modelos de integración: elige según quién actúa. Tu backend puede actuar en nombre del hotel mediante la API REST, o el huésped puede iniciar sesión con el SSO de fidelización. La mayoría de las integraciones de motores de reservas usan ambos.

De servidor a servidor

API REST de servidor

Tu backend actúa en nombre del hotel con una clave de API. Busca cualquier huésped por correo electrónico; da de alta, concede, canjea y sincroniza puntos y crédito monetario.

Autenticación · Authorization: Bearer <api_key>
Endpoints más abajo
Inicio de sesión del huésped · OIDC

SSO de fidelización (OIDC)

El huésped inicia sesión con su cuenta de fidelización (OAuth2 + PKCE). Consulta solo su nivel, saldo e historial para personalizar el proceso de reserva.

Autenticación · tokens por huésped (id_token + token de acceso Bearer)
Guía de integración

¿No sabes cuál elegir? Usa la API REST cuando tu servidor actúa en nombre del hotel (sincronización PMS, concesión, canje, crédito monetario). Usa SSO de fidelización cuando un huésped inicia sesión en tu sitio y personalizas para él. El saldo y el historial están disponibles en ambos modelos: mismos datos, distinto límite de confianza.

Parámetros de consulta

ParámetroTipoObligatorioDescripción
emailstring
Obligatorio
Dirección de correo electrónico del huésped

Respuesta (socio encontrado)

{
  "success": true,
  "data": {
    "is_member": true,
    "member_summary": {
      "member_id": "uuid",
      "tier_name": "Gold",
      "tier_slug": "gold",
      "points_balance": 1500,
      "lifetime_points": 3000,
      "joined_at": "2025-01-15T10:30:00Z"
    }
  }
}

Respuesta (no es socio)

{
  "success": true,
  "data": {
    "is_member": false,
    "member_summary": null
  }
}

Más endpoints REST: misma autenticación Bearer y estructura de respuesta, agrupados para completar la referencia.
Obtención y ajustes guests:write
  • POST /api/v1/loyalty/actions: concede una bonificación por una acción ajena a la estancia (reseña, encuesta o descarga de la app)
  • POST /api/v1/loyalty/points/confirm: confirma unos puntos pendientes y los incorpora al saldo disponible
  • POST /api/v1/loyalty/points/void: anula unos puntos pendientes antes de confirmarlos
  • POST /api/v1/loyalty/reverse: revierte los puntos ganados ante una cancelación o si el huésped no se presenta
  • POST /api/v1/loyalty/apply-discount: usa puntos como descuento monetario en una reserva o TPV. reference_id es un metadato, no una clave de reintento; reenviar la solicitud puede descontar puntos de nuevo
  • POST /api/v1/loyalty/redeem-free-night: canjea puntos por un código de bono de noche gratis. La entrega mediante engine_api no está implementada y devuelve 501
Avanzado
  • GET /api/v1/loyalty/conversion: calculadora de puntos ↔ dinero, con permiso guests:read
  • GET /api/v1/loyalty/households · POST: saldo compartido del hogar y canje conjunto
  • GET /api/v1/loyalty/liability: informe de obligaciones por puntos y estado del programa, con permiso guests:read
  • POST /api/v1/loyalty/experiences/bid: puja con puntos por una experiencia en subasta

Autenticación y permisos

Autentica cada llamada REST con Authorization: Bearer <api_key>: la cuenta se obtiene de la clave y no requiere una cabecera de slug adicional. Los endpoints de lectura (check, member, rewards, tiers, transactions, calculate, conversion, cálculo de crédito monetario e instantánea de reserva) requieren el permiso guests:read; los de escritura (enroll, points, redeem y retención, confirmación, liberación y reversión de crédito monetario) requieren guests:write. Todos comparten el límite de transporte estándar v1 de 2000 solicitudes/minuto, además del límite propio de tu clave (1000/minuto por defecto).

SDK JavaScript disponible

Un SDK JavaScript incorpora los endpoints principales de fidelización con inyección de cabeceras y gestión de errores. Mantén las claves de API privadas en tu servidor.

Crédito monetario

Nuevo

Permite a los socios gastar sus puntos como crédito monetario en reservas directas, cargos durante la estancia y al salir. Ciclo de cálculo → retención → confirmación/liberación/caducidad: consulta las páginas detalladas para ver toda la integración.

Vista general

Diagrama del ciclo, áreas de aplicación, códigos de error y lista de OTA excluidas.

Motor de reservas

Inserta <script> en 5 minutos, con un callback de aplicación.

PMS

/reservation-snapshot + 5 webhooks HMAC para sincronizar saldos en tiempo real.

Endpoints y permisos obligatorios
Métodos de la API de crédito monetario, permisos y comportamiento
EndpointAlcanceComportamiento
GET /api/v1/loyalty/credit/quoteguests:readLeer saldo disponible y opciones predefinidas
POST /api/v1/loyalty/credit/holdguests:writeReserve points atomically; external_reference_id identifies retries
POST /api/v1/loyalty/credit/confirmguests:writeConfirmar el descuento de puntos de una retención
POST /api/v1/loyalty/credit/releaseguests:writeRelease a hold; released: true does not prove an active hold was found
POST /api/v1/loyalty/credit/reverseguests:writeReturn confirmed points after cancellation; reconcile before retrying
GET /api/v1/loyalty/reservation-snapshotguests:readLeer el saldo del socio y el historial de crédito de la reserva

SSO de fidelización (OIDC)

GuestMaker es un proveedor estándar de identidad OpenID Connect para huéspedes de fidelización. Tu sitio web permite iniciar sesión con la cuenta de fidelización mediante Authorization Code + PKCE y consulta nivel, saldo de puntos e historial para personalizar el proceso de reserva.

Guía de integración

El flujo, permisos y declaraciones, requisitos de seguridad obligatorios, modelo de tokens y endpoints.

Inicio rápido para motores de reservas

Guía para copiar y pegar, independiente del framework: URL de autorización, PKCE, intercambio de tokens, verificación de id_token y lectura de datos del socio.

Endpoints (Authorization Code + PKCE)
  • GET /api/oidc/.well-known/openid-configuration: descubrimiento (carga los endpoints y las JWKS desde aquí)
  • GET /api/oidc/auth: autorización (redirección del navegador, PKCE S256)
  • POST /api/oidc/token: intercambio de tokens (client_secret_basic)
  • GET /api/oidc/jwks: claves públicas de firma RS256
  • GET /api/loyalty/me/balance: nivel y puntos del socio (Bearer)
  • GET /api/loyalty/me/transactions: historial de puntos (Bearer)

Suscripción a la newsletter

Inserta un formulario de suscripción a la newsletter en tu sitio web. Los suscriptores confirmados se convierten en contactos con consentimiento de marketing, para recibir automáticamente tus campañas periódicas. Primero configura y activa el widget en Ajustes → Correo electrónico → Suscripción a la newsletter, y copia tu clave publicable de la pestaña Instalar. Estas rutas aceptan dos modos de autenticación: una clave publicable gm_pub_… para inserciones en navegador (puede incluirse en el HTML; el Origin de la solicitud debe coincidir con tu lista de dominios permitidos), o una clave de API secreta gmkr_… para llamadas de servidor a servidor (por ejemplo, un motor de reservas). Las solicitudes con clave secreta se validan con la propia clave y omiten la comprobación de Origin. Consulta Autenticación más abajo.

Instalación rápida (sin código)

<div data-gm-newsletter
     data-token="gm_pub_your_publishable_key"
     data-fields="email"></div>
<script src="https://www.guestmaker.ai/sdk/guestmaker.js" async></script>

O crea tu propia interfaz y llama al SDK sin interfaz:

GuestMaker.newsletter.subscribe({
  email: 'guest@example.com',
  token: 'gm_pub_your_publishable_key'
}).then(function (r) {
  // r.status === 'pending' | 'subscribed'
})

Usa siempre el host https://www.guestmaker.ai: el dominio raíz redirige y elimina la cabecera de autenticación.

Autenticación

Frontend (widget de navegador): clave publicable como token Bearer (Authorization: Bearer gm_pub_…). El host indicado en Origin/Referer debe figurar en tu lista de dominios permitidos; si no, se rechaza la solicitud con 403. Esta es la vía que usan el widget insertable y el SDK.

Backend (de servidor a servidor): clave secreta como token Bearer (Authorization: Bearer gmkr_…) con el permiso guests:write. Úsalo para suscribir desde tu servidor (sin Origin de navegador): la clave secreta acredita la solicitud, por lo que se omiten la lista de orígenes permitidos y Turnstile. Nunca expongas una clave gmkr_… en código del cliente.

En ambos casos, primero debe activarse el widget de newsletter en Ajustes → Correo electrónico → Suscripción a la newsletter; un 403 con Newsletter signup not enabled indica que aún no existe una configuración activa.

Ejemplo de backend (de servidor a servidor)

curl -X POST https://www.guestmaker.ai/api/v1/newsletter/subscribe \
  -H "Authorization: Bearer gmkr_your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "guest@example.com",
    "consent": true,
    "source": "booking_engine"
  }'

Cuerpo de la solicitud

ParámetroTipoObligatorioDescripción
emailstring
Obligatorio
Correo electrónico del suscriptor (máx. 254)
consenttrue
Obligatorio
Explicit consent; rejected if absent or false
first_namestringOpcionalSolo se guarda si el campo first_name está activado en tu configuración
languagestringOpcionalISO 639-1 (máx. 10), normalizado a minúsculas
hotel_idUUIDOpcionalProperty of interest; validated against your active hotels
sourcestringOpcionalEtiqueta libre de procedencia (máx. 200)
turnstile_tokenstringOpcionalToken de Cloudflare Turnstile, cuando Turnstile está activado
_hpstringOpcionalHoneypot: must be empty; a non-empty value is silently treated as a bot

Respuesta (200)

{ "status": "pending" }

pending = correo de confirmación de doble opt-in enviado; subscribed = opt-in simple, disponible para marketing inmediatamente. La respuesta es idéntica para direcciones nuevas, pendientes o ya confirmadas, sin revelar si son miembros.

Webhooks

Recibe avisos en tiempo real cuando ocurran eventos en la plataforma. Configura los endpoints de webhook en los ajustes del panel.

Eventos de webhook disponibles
Eventos que pueden entregarse a tus endpoints de webhook
message.receivedMensaje entrante
message.sentMensaje saliente enviado
message.deliveredMensaje entregado
message.readMensaje leído por el destinatario
contact.createdNuevo contacto añadido
contact.updatedDatos del contacto modificados
contact.deletedContacto eliminado
conversation.createdNueva conversación iniciada
conversation.closedConversación cerrada
journey.startedAutomatización del recorrido iniciada
journey.completedAutomatización del recorrido terminada
journey.failedError de ejecución del recorrido
broadcast.sentCampaña enviada
broadcast.completedCampaña terminada
reservation.checked_inEntrada del huésped (comprobación diaria de fechas: ver nota)
reservation.checked_outSalida del huésped (comprobación diaria de fechas: ver nota)

Nota: horarios de reservation.checked_in / checked_out. Se activan con una comprobación diaria al llegar la fecha de entrada o salida del huésped; no se activan en tiempo real. Cada entrega incluye un objeto scheduled_for con la hora local prevista de entrada o salida, para programar acciones en tu sistema. Las horas son configurables por cuenta (por defecto: entrada 15:00, salida 12:00 y zona horaria del hotel).

Formato del payload de webhook
Todos los webhooks usan este formato común
{
  "event_type": "contact.created",
  "timestamp": "2026-03-15T10:30:00Z",
  "data": {
    "contact": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "phone": "+1234567890",
      "first_name": "John",
      "last_name": "Doe",
      "email": "john@example.com",
      "hotel_id": "550e8400-e29b-41d4-a716-446655440001"
    }
  }
}

Los eventos de reserva incluyen la reserva, el huésped y la indicación scheduled_for:

{
  "event_type": "reservation.checked_in",
  "timestamp": "2026-07-10T03:12:08Z",
  "data": {
    "reservation": {
      "id": "…", "hotel_id": "…", "status": "CheckedIn",
      "check_in": "2026-07-10", "check_out": "2026-07-12",
      "localizer_code": "ABC123", "booking_id": "…",
      "source": "…", "booking_channel": "…", "total_value": 540, "currency": "EUR"
    },
    "contact": {
      "id": "…", "first_name": "John", "last_name": "Doe",
      "email": "john@example.com", "phone": "+34600000000",
      "language": "en", "nationality": "GB"
    },
    "scheduled_for": {
      "date": "2026-07-10", "local_time": "15:00",
      "timezone": "Europe/Madrid", "iso": "2026-07-10T13:00:00.000Z"
    }
  }
}

Cabeceras de seguridad
Cabeceras incluidas en cada solicitud de webhook
ParámetroTipoObligatorioDescripción
X-Webhook-Signaturestring
Obligatorio
HMAC-SHA256 signature: sha256=...
X-Webhook-Eventstring
Obligatorio
El tipo de evento que se entrega
X-Webhook-Deliverystring
Obligatorio
ID único de entrega (UUID)
X-Webhook-Timestampstring
Obligatorio
Marca de tiempo ISO 8601 del evento
Verificación de firmas
Verifica siempre las firmas de los webhooks para comprobar la autenticidad de las solicitudes
const crypto = require('crypto');

// Sign over `timestamp + "." + rawBody` (the timestamp is signed for replay
// resistance). Verify against the RAW request body, never a re-serialized object.
function verifyWebhookSignature(rawBody, timestamp, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex');

  const wanted = Buffer.from(`sha256=${expected}`);
  const actual = Buffer.from(signature || '');
  return actual.length === wanted.length && crypto.timingSafeEqual(actual, wanted);
}

// Capture the raw body (do NOT re-serialize req.body):
app.use('/webhook', express.raw({ type: 'application/json' }));
app.post('/webhook', (req, res) => {
  const rawBody = req.body.toString('utf8');
  const timestamp = req.headers['x-webhook-timestamp'];
  const signature = req.headers['x-webhook-signature'];

  if (!verifyWebhookSignature(rawBody, timestamp, signature, 'your_webhook_secret')) {
    return res.status(401).send('Invalid signature');
  }
  // Retries retain the original event timestamp.
  // Use stable payload identifiers for idempotent processing.

  const { event_type, data } = JSON.parse(rawBody);
  console.log(`Received event: ${event_type}`, data);

  res.status(200).send('OK');
});

CTI / Telefonía

Conecta tu centro de llamadas a GuestMaker para abrir fichas en llamadas entrantes, llamar con un clic, grabar e incorporar un historial de llamadas por contacto. Todos los proveedores usan el mismo contrato unificado: conecta una vez y tus agentes tendrán la misma experiencia con Ringover u otro proveedor compatible.

Configuración
Conectar un proveedor de CTI a GuestMaker

Paso 1. En el panel, abre Settings → Integrations → {Provider} y pulsa Conectar.

Paso 2. Pega las credenciales de tu proveedor (clave de API para Ringover, flujo de consentimiento OAuth para Teams). GuestMaker valida las credenciales y devuelve para cada cuenta una URL de webhook y Token de autorización.

Paso 3. En el panel de tu proveedor, configura un webhook con esa URL y token. Activa estos eventos: call_ringing, call_answered, call_hangup, call_missed y record_available.

Paso 4. Pulsa Probar conexión: una llamada entrante simulada abre la ficha en tu panel.

Paso 5. Configura los modos de apertura de ficha (navegación automática, aviso, pestaña nueva) y la posición del widget. Los agentes se vinculan automáticamente por correo electrónico desde la lista de usuarios de tu proveedor.

Eventos de webhook
Eventos del ciclo de llamada que GuestMaker acepta de todos los proveedores de CTI
call_ringingLlamada sonando: activa la búsqueda de contacto y la apertura de ficha
call_answeredLlamada atendida por un agente
call_hangupLlamada terminada (incluye duración en segundos)
call_missedLlamada sin respuesta
record_availableURL de grabación disponible
call_completedUn registro después de la llamada (metadatos + transcripción/resumen opcional): consulta Envío de llamadas completadas más abajo
Autenticación de webhook
Autenticación con token Bearer en la cabecera Authorization, comparado de forma segura frente a ataques de temporización en cada solicitud
POST /api/webhooks/cti
Authorization: Bearer <your_webhook_token>
Content-Type: application/json

{
  "event_type": "call_ringing",
  "call_id": "ringover-abc-123",
  "user_id": "ringover-user-42",
  "from_number": "+34612345678",
  "to_number": "+34900111222",
  "direction": "inbound"
}

Tu token corresponde a una integración, que identifica la cuenta y el proveedor. Por eso esta URL única funciona para todos los proveedores, sin necesidad de un slug de proveedor. La forma específica /api/webhooks/cti/{provider} es equivalente y sigue siendo compatible.

Los nombres de campo se aceptan en snake_case o camelCase, y también pueden estar anidados en un objeto data. Límite por cuenta: 100 solicitudes/minuto.

Envío de llamadas completadas (call_completed)
Envía un registro por llamada terminada: para proveedores que envían los datos después de colgar, en lugar de los eventos en tiempo real o junto a ellos

Envía mediante POST un evento call_completed por llamada terminada. Vuelve a enviar el mismo call_id más adelante para actualizar el registro y adjuntar la transcripción cuando termine. Si hay transcripción, se extrae información para la memoria de IA del huésped.

POST /api/webhooks/cti
Authorization: Bearer <your_webhook_token>
Content-Type: application/json

{
  "event": "call_completed",
  "call_id": "zn-8f3a2c91",
  "direction": "inbound",
  "from": "+34600111222",
  "to": "+34971000000",
  "agent": { "id": "zoon-user-42", "email": "agent@hotel.com" },
  "caller": { "name": "María García", "email": "maria@example.com" },
  "started_at": "2026-07-16T10:31:04Z",
  "answered_at": "2026-07-16T10:31:12Z",
  "ended_at": "2026-07-16T10:35:49Z",
  "outcome": "completed",
  "recording_url": "https://rec.example.com/zn-8f3a2c91.mp3",
  "summary": "Guest asked about a late checkout on the 18th.",
  "transcript": [
    { "speaker": "guest", "text": "Hola, quería un late checkout.", "offset_ms": 0 },
    { "speaker": "agent", "text": "Claro, dígame su habitación.", "offset_ms": 4200 }
  ]
}

Cuerpo de la solicitud

ParámetroTipoObligatorioDescripción
eventstring
Obligatorio
El literal "call_completed".
call_idstring
Obligatorio
Tu ID único estable: la única clave de idempotencia, específica por (cuenta, proveedor).
directionstring
Obligatorio
inbound o outbound. Omítelo por completo para enviar una actualización de contenido (ver más abajo).
from / tostring
Obligatorio
Números E.164. El lado del huésped (from en entrantes, to en salientes) identifica o crea un contacto.
started_at / ended_atstring
Obligatorio
ISO 8601. A full record missing either is dropped; a content patch does not need them.
answered_atstringOpcionalISO 8601. Ausente o null significa que la llamada nunca se atendió.
duration_secondsnumberOpcionalSe calcula a partir de ended_at − (answered_at o started_at) si se omite.
agentobjectOpcional{ id, email }: matched to the GuestMaker user who handled the call. An email in either field lets us resolve the user without a manual mapping.
callerobjectOpcional{ name | first_name/last_name, email }: the guest's known details. Fills blank contact fields only; never overwrites.
outcomestringOpcionalcompleted | missed | no_answer | voicemail | texto libre. missed, no_answer y voicemail guardan la llamada como perdida.
recording_urlstringOpcionalSe guarda sin cambios y se muestra como enlace de reproducción en el contacto. El audio permanece en tus servidores.
transcriptarrayOpcional[{ speaker, text, offset_ms? }]: feeds guest-memory extraction. Capped at 500 turns / 200,000 characters; oversized pushes are truncated, not rejected.
transcript_textstringOpcionalAlternativa en texto plano. Las líneas con prefijo Guest:/Agent: se separan en turnos si se detectan al menos dos.
summarystringOpcionalTu resumen de IA: se muestra en cursiva bajo la llamada en el historial del contacto.
language, metadatastring, objectOpcionalMerged into the call's metadata. Existing keys are kept; only keys present in the push are added or overwritten.

Datos adicionales del llamante. El objeto opcional caller solo rellena los campos vacíos de nombre y correo del contacto identificado; nunca sobrescribe datos existentes. Se rechazan etiquetas del operador ("MOBILE CALLER", "Número privado") y nombres de relleno. Un correo solo se aplica si es válido y no pertenece a otro contacto.

Idempotencia. Volver a enviar el mismo call_id actualiza el registro con la lógica de COALESCE: los campos opcionales que no incluya un reenvío nunca borran contenido guardado. La extracción de memoria del huésped solo se ejecuta la primera vez que llega una transcripción.

Actualizaciones de contenido. La grabación y la transcripción suelen terminar minutos después de la llamada. No necesitas reenviar todo el registro: envía call_id y solo el contenido nuevo, omitiendo direction, from/to y las marcas de tiempo. La actualización combina recording_url, transcript, summary, outcome y caller en la llamada existente sin modificar nada más. Envía tantas actualizaciones como necesites. Solo combinan contenido y nunca crean una llamada; envía primero el registro completo al colgar. Se descarta una actualización si no encuentra un call_id coincidente.

Respuestas. 200 {"received": true} (procesado de forma asíncrona), 401 token incorrecto, 400 JSON inválido, 429 límite superado (las cargas históricas deben espaciarse y respetar los reintentos).

Panel de CTI insertado (SDK v1)
Comunicación bidireccional entre un panel de CTI insertado en el panel de control y GuestMaker
<script src="https://www.guestmaker.ai/cti/sdk/v1.js"></script>
<script>
  const gm = await GuestMakerCTI.connect({
    hostOrigin: "https://www.guestmaker.ai"
  });

  gm.agentEmail;  // the GuestMaker user signed in right now
  gm.locale;      // "es"

  await gm.openContactByPhone("+34661024890");
  gm.on("clickToCall", ({ phone }) => dialer.call(phone));
</script>

Métodos (panel → GuestMaker)

ParámetroTipoObligatorioDescripción
setPanelMode(mode){ mode }
Obligatorio
mode es "docked", "collapsed" o "hidden". Devuelve el modo aplicado, que puede ser distinto si el host lo rechaza.
lookupContact(phone){ found, contactId?, displayName? }
Obligatorio
Teléfono E.164. Identificación del llamante de solo lectura: indica si existe un contacto y su nombre visible, sin cambiar el panel. Solo el nombre: nunca correo electrónico, reservas ni historial.
openContactByPhone(phone){ found, contactId? }
Obligatorio
E.164 phone. Opens the guest's record on a hit; does not navigate on a miss.
screenPop(params){ found, contactId?, popped }Opcional{ phone, callId?, direction?, state? }. Announces a live call in this browser and honours the tenant's screen-pop settings. popped reports whether anything actually happened.
openContactSearch(query){ shown }OpcionalTexto libre, máx. 200 caracteres. Abre la lista de contactos con la búsqueda rellenada. No devuelve registros.
openCreateContact({ phone }){ shown }OpcionalAbre el formulario de creación de contacto rellenado. Una persona debe guardarlo: la llamada no escribe nada.

Eventos (GuestMaker → panel)

ParámetroTipoObligatorioDescripción
clickToCall{ phone, contactId? }OpcionalUn agente ha pulsado un número de teléfono en el panel.
panelModeChanged{ mode }OpcionalEl agente ha contraído o restaurado el panel desde nuestra interfaz, para mantener el tuyo sincronizado.

Códigos de error

ParámetroTipoObligatorioDescripción
UNKNOWN_METHODhostOpcionalNo es un método de esta versión del protocolo.
INVALID_PARAMShostOpcionalFailed validation; the message names the offending field.
NOT_FOUNDhostOpcionalSolicitud bien formada, sin coincidencias.
NOT_PERMITTEDhostOpcionalOrigen o cuenta sin permiso para realizar esa llamada.
TIMEOUTsdkOpcionalSin respuesta en 10 segundos. Se genera localmente, no en el host.

El protocolo es el contrato. El SDK simplifica el uso: puedes implementar los mensajes directamente. Cada mensaje incluye gmcti: 1; una solicitud es { gmcti, id, type: "request", method, params } y la respuesta devuelve tu id sin cambios.

Acciones, sin datos del huésped. Las respuestas incluyen booleanos, identificadores y el estado aplicado; nunca nombres, correos electrónicos, reservas ni historial. Si necesitas datos de contacto en tus sistemas, usa GET /api/v1/guests?phone= de servidor a servidor con una clave guests:read. También funciona sin ninguna pestaña del navegador abierta.

Antes de conectar. Envíanos el origen exacto desde el que se sirve tu panel: lo añadimos a las listas permitidas del intercambio de mensajes y de nuestra CSP. No se carga nada hasta que lo hagamos.

Modos de apertura de ficha
Tres opciones independientes, configuradas por cuenta
ParámetroTipoObligatorioDescripción
auto_navigatebooleanOpcionalDefault true. Current tab navigates to /contacts/{id} on ring.
notificationbooleanOpcionalPor defecto, true. Aviso deslizante con nombre del llamante y botón Abrir contacto.
new_tabbooleanOpcionalDefault false. Opens /contacts/{id} in a background tab.
widget_positionstringOpcionalPosición del widget SDK del proveedor: 'bottom-right' (por defecto) o 'bottom-left'.
Contactos creados automáticamente
Qué ocurre cuando llama un número desconocido

Los números entrantes desconocidos se normalizan a E.164 y se buscan en los contactos de tu cuenta. Si no hay coincidencia, GuestMaker crea un contacto mínimo con source = '{provider}' (por ejemplo, 'ringover'). Se abre la ficha con is_new_contact: true para que el agente vea un registro nuevo.

Nota: los teléfonos se comparan por igualdad exacta en E.164. Los proveedores que envían números nacionales sin código de país pueden generar contactos duplicados. Normaliza antes del envío siempre que sea posible.

Modelos de datos

Referencia de las estructuras de datos usadas en toda la API.

Objeto Contact
Representa a un huésped o contacto en el sistema
{
  "id": "uuid",                    // Unique identifier
  "phone": "+1234567890",          // Phone in E.164 format
  "phone_normalized": "1234567890", // Normalized phone (digits only)
  "first_name": "John",
  "last_name": "Doe",
  "email": "john@example.com",
  "language": "en",                // ISO 639-1 language code
  "tags": ["vip", "returning"],    // Array of tags
  "custom_fields": {},             // Custom key-value pairs
  "opt_in_status": "opted_in",     // Legacy (deprecated). Use consent booleans below.
  "subscription_status": "active", // active | unsubscribed (hard block)
  "whatsapp_marketing_consent": true,  // WhatsApp marketing gate
  "email_consent": true,           // Email marketing master gate
  "guest_stage": "pre_stay",       // unknown | pre_stay | during_stay | post_stay
  "hotel_id": "uuid",              // Linked hotel
  "current_reservation_id": "uuid", // Active reservation
  "source": "pms",                 // System type: pms, booking_engine, crm, etc.

  // Personal data fields
  "date_of_birth": "1985-06-15",   // YYYY-MM-DD format
  "gender": "male",                // male | female | other | prefer_not_to_say
  "nationality": "US",             // ISO 3166-1 alpha-2 code
  "document_type": "passport",     // passport | national_id | drivers_license | other
  "document_number": "AB1234567",  // ID document number

  // Consent & subscription fields
  "subscription_status": "active", // active | unsubscribed
  "opted_out_at": null,            // Timestamp when unsubscribed
  "consent_source": "api",         // Where consent was collected
  "consent_partner_id": "uuid",    // Integration partner who collected consent
  "consent_updated_at": "2024-03-01T10:00:00Z",

  "created_at": "2024-03-01T10:00:00Z",
  "updated_at": "2024-03-01T10:00:00Z"
}

Objeto Reservation
Representa una reserva
{
  "id": "uuid",
  "tenant_id": "uuid",
  "hotel_id": "uuid",
  "localizer_code": "BK-12345",    // Your external booking ID
  "external_id": "BK-12345",       // External system reference
  "source": "hotelinking",         // Canonical origin (e.g. "neobookings", "roiback", "hotelinking", "manual")
  "source_code": "hotelinking",    // Raw value sent by producer (preserved for audit)
  "source_type": "pms",            // pms | booking_engine | manual | api | import
  "attribution_source": null,      // Marketing attribution: e.g. "google_ads", "meta_ads", "booking_com" (null if not supplied)
  "status": "Confirmed",           // Confirmed | Modified | CheckedIn | CheckedOut | Cancelled | NoShow
  "check_in": "2026-03-15",        // Check-in date
  "check_out": "2026-03-18",       // Check-out date
  "nights": 3,                     // Calculated nights
  "room_type": "Deluxe Suite",
  "room_number": "405",
  "board_type": "BB",
  "rate_plan": "Best Available",
  "total_value": 450.00,
  "currency": "EUR",
  "adults": 2,
  "children": 0,
  "notes": "Late checkout requested",
  "created_at": "2024-03-01T10:00:00Z",
  "updated_at": "2024-03-01T10:00:00Z"
}

Ciclo de etapas del huésped
Seguimiento automático de etapas según las fechas de reserva
1
unknown

Sin datos de reserva

2
pre_stay

Antes de la entrada

3
during_stay

En el hotel

4
post_stay

Después de la salida

Las etapas del huésped se actualizan automáticamente mediante una tarea cron diaria y al recibir eventos de reserva. El asistente de IA usa la etapa para personalizar las conversaciones.

CRM B2B

Incorpora agencias de viajes, turoperadores y cuentas corporativas como entidades B2B. Las cuentas admiten jerarquía de matriz y filiales (hasta 3 niveles), condiciones comerciales (comisiones, crédito y códigos promocionales) e identificadores que permiten atribuir automáticamente las reservas a cuentas. Los contactos B2B son contactos de huéspedes normales marcados con contact_type: "b2b" y vinculados a cuentas.

Permisos y requisitos del módulo
b2b:read
Obligatorio para endpoints GET
b2b:write
Obligatorio para endpoints POST / PATCH

Todos los endpoints /api/v1/b2b/* requieren que el módulo de CRM B2B esté activado para tu cuenta. Las solicitudes sin él devuelven 403 MODULE_NOT_ENABLED. Contacta con tu responsable de cuenta para activar el módulo.

Permiso obligatorio

b2b:write

Cuerpo de la solicitud

ParámetroTipoObligatorioDescripción
legal_namestring
Obligatorio
Razón social (máx. 200 caracteres)
trade_namestringOpcionalNombre comercial o de marca
tax_idstringOpcionalCIF/NIF o identificación fiscal internacional. Único por cuenta (sin distinguir mayúsculas): se usa para identificar registros al insertar o actualizar y en referencias parent_account
iata_codestringOpcionalCódigo IATA de agencia: también identifica coincidencias para atribuir reservas
sectorstringOpcionalSector de actividad (texto libre)
profilestringOpcionalcorporate o mice (por defecto: corporate). Determina el flujo de oportunidades y los bloques de cuenta aplicables
account_typestringOpcionaltravel_agency, tour_operator, dmc, incentive_agency, corporate_booking, corporate, event_organizer, other
sourcestringOpcionalProcedencia de la cuenta (texto libre)
websitestringOpcionalURL del sitio web de la empresa
email_domainsstring[]OpcionalHasta 20 dominios (p. ej., @acme.com). Los correos de titulares de reserva en estos dominios generan sugerencias de atribución
billing_addressobjectOpcionalDirección fiscal (consulta el objeto Billing Address más abajo)
billing_detailsobjectOpcionalMapa de cadenas de clave y valor (p. ej., invoice_email, notas de IVA)
parent_accountobjectOpcionalReference to an existing parent account (see Account Reference Object below). Must resolve (422 PARENT_NOT_FOUND); hierarchy max 3 levels (422 HIERARCHY_TOO_DEEP)
statusstringOpcionalprospect, active, inactive (por defecto: active)
promo_codesstring[]OpcionalHasta 50 códigos promocionales o de tarifa (p. ej., CORP_ACME2026). Se comparan con los códigos de tarifa de reservas para atribuirlas
commitment_room_nightsnumberOpcionalCompromiso anual contratado de noches de habitación
contract_start_datestringOpcionalInicio del contrato (YYYY-MM-DD)
contract_end_datestringOpcionalFin del contrato (YYYY-MM-DD): activa avisos de renovación
payment_methodstringOpcionalcredit o direct
credit_limitnumberOpcionalImporte del límite de crédito
payment_daysnumberOpcionalPlazo de pago en días (0–365)
cancellation_policystringOpcionalPolítica de cancelación acordada (máx. 2000 caracteres)
commission_ratenumberOpcionalPorcentaje de comisión sobre alojamiento (0–100). Las cuentas filiales lo heredan de la matriz si no está definido
commission_settlementstringOpcionaldeducted_invoice o post_checkout
external_idstringOpcionalTu identificador de PMS/CRM. Único por cuenta: clave principal para insertar o actualizar cuando se indica
channel_manager_codestringOpcionalCódigo de agencia del channel manager (identificador de coincidencia)
crs_codestringOpcionalCódigo de agencia del CRS (identificador de coincidencia)
mirai_agency_idstringOpcionalID de agencia de Mirai Pro (identificador de coincidencia)
custom_fieldsobjectOpcionalPares libres de clave y valor

Objeto Billing Address

ParámetroTipoObligatorioDescripción
line1stringOpcionalLínea de dirección 1
line2stringOpcionalLínea de dirección 2
citystringOpcionalCiudad
regionstringOpcionalRegión / estado / provincia
postal_codestringOpcionalCódigo postal
countrystringOpcionalISO 3166-1 alpha-2 en mayúsculas (p. ej., ES, US)

Objeto Account Reference

Lo utiliza parent_account aquí, account en oportunidades y b2b_account al incorporar huéspedes. Se requiere al menos un identificador. Orden de resolución: id → external_id → tax_id → iata_code.

ParámetroTipoObligatorioDescripción
idstringOpcionalUUID de cuenta de GuestMaker
external_idstringOpcionalTu identificador de PMS/CRM
tax_idstringOpcionalIdentificación fiscal (comparación sin distinguir mayúsculas)
iata_codestringOpcionalCódigo IATA de agencia

Ejemplo de solicitud

curl -X POST https://www.guestmaker.ai/api/v1/b2b/accounts \
  -H "Authorization: Bearer gmkr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "legal_name": "Viajes Mediterraneo S.L.",
    "trade_name": "Viajes Mediterraneo",
    "tax_id": "B12345678",
    "iata_code": "78212345",
    "profile": "corporate",
    "account_type": "travel_agency",
    "email_domains": ["@viajesmediterraneo.com"],
    "billing_address": {
      "line1": "Calle Gran Via 28",
      "city": "Madrid",
      "postal_code": "28013",
      "country": "ES"
    },
    "commission_rate": 10,
    "commission_settlement": "post_checkout",
    "payment_method": "credit",
    "credit_limit": 50000,
    "payment_days": 30,
    "promo_codes": ["AGMED2026"],
    "commitment_room_nights": 1500,
    "contract_start_date": "2026-01-01",
    "contract_end_date": "2026-12-31",
    "parent_account": { "tax_id": "B87654321" },
    "external_id": "PMS-AG-0042"
  }'

Respuesta

201 cuando se ha creado una cuenta nueva; 200 cuando se ha actualizado una existente.

{
  "success": true,
  "data": {
    "account_id": "550e8400-e29b-41d4-a716-446655440000",
    "is_new": true,
    "message": "Account created successfully"
  }
}

Identificación y atribución
Cómo se vinculan automáticamente las reservas a cuentas B2B para informar de la producción

Cada reserva incorporada se compara con los identificadores de tus cuentas por orden estricto de prioridad. Prevalece la primera coincidencia; nunca se sobrescriben los vínculos manuales del panel.

1

Código de agencia

El código de agencia o canal de la reserva coincide con iata_code, channel_manager_code, crs_code o external_id de una cuenta: vinculación automática.

2

Código promocional / de tarifa

El código de tarifa de la estancia coincide con uno de los promo_codes de la cuenta (o de una oportunidad corporativa abierta): vinculación automática.

3

ID de agencia de Mirai

El identificador de agencia de Mirai del origen de la reserva coincide con mirai_agency_id: vinculación automática.

4

Dominio de correo electrónico (solo sugerencia)

El dominio del correo del titular aparece en email_domains de una cuenta: se muestra como sugerencia para confirmación humana, nunca se vincula automáticamente.

Cuantos más identificadores envíes en las cuentas (IATA, códigos de channel manager, códigos promocionales, dominios de correo), mayor será la cobertura de atribución automática.

Códigos de error B2B
400 Bad Request

Cuerpo de solicitud o parámetros de consulta inválidos

VALIDATION_ERROR
401 Unauthorized

Clave de API inválida o ausente

UNAUTHORIZED
403 Forbidden

El módulo de CRM B2B no está activado para esta cuenta (también FORBIDDEN si la clave no tiene el permiso b2b)

MODULE_NOT_ENABLED
404 Not Found

El ID de cuenta no existe para esta cuenta de cliente

NOT_FOUND
422 Unprocessable

La referencia parent_account no identifica una cuenta existente

PARENT_NOT_FOUND
422 Unprocessable

Vincular la matriz superaría los 3 niveles de jerarquía de cuentas

HIERARCHY_TOO_DEEP
422 Unprocessable

Vincular la matriz crearía un ciclo en la jerarquía

HIERARCHY_CYCLE
422 Unprocessable

Oportunidades: la referencia de cuenta no identifica una cuenta existente

ACCOUNT_NOT_FOUND
422 Unprocessable

Oportunidades: no existe un pipeline para el tipo de flujo (no se han creado los valores predeterminados del módulo)

NO_PIPELINE
429 Too Many Requests

Límite de solicitudes superado

RATE_LIMITED

Gestión de errores

Formato de respuesta de error
{
  "success": false,
  "error": {
    "message": "Validation failed",
    "code": "VALIDATION_ERROR",
    "details": [
      { "field": "phone", "message": "Phone number is required" },
      { "field": "first_name", "message": "First name is required" }
    ]
  }
}

Códigos de estado HTTP
200 OK

Solicitud correcta

201 Created

Recurso creado correctamente

202 Accepted

Solicitud aceptada para procesamiento asíncrono

400 Bad Request

Parámetros de solicitud inválidos

VALIDATION_ERROR
401 Unauthorized

Clave de API inválida o ausente

UNAUTHORIZED
403 Forbidden

Permisos insuficientes

FORBIDDEN
404 Not Found

Recurso no encontrado

NOT_FOUND
409 Conflict

El recurso ya existe

CONFLICT
422 Unprocessable

Se entiende la solicitud, pero no puede procesarse

UNPROCESSABLE
429 Too Many Requests

Límite de solicitudes superado

RATE_LIMITED
500 Internal Error

Error del servidor

INTERNAL_ERROR
503 Service Unavailable

Servicio temporalmente no disponible

SERVICE_UNAVAILABLE

Límites de solicitudes

Las solicitudes de API tienen límites por clave de API. El límite predeterminado es 1,000 solicitudes por minuto.

Cabeceras de límite de solicitudes

ParámetroTipoObligatorioDescripción
X-RateLimit-Limitnumber
Obligatorio
Máximo de solicitudes por minuto
X-RateLimit-Remainingnumber
Obligatorio
Solicitudes restantes en el intervalo actual
X-RateLimit-Resetnumber
Obligatorio
Marca de tiempo Unix en que se restablece el límite

Respuesta de límite de solicitudes

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1710507600
Retry-After: 45

{
  "success": false,
  "error": {
    "message": "Rate limit exceeded. Please retry after 45 seconds.",
    "code": "RATE_LIMITED"
  }
}

¿Necesitas límites más altos?

Contacta con nosotros para hablar de límites más altos para tu integración. Dependen de la clave de API y del endpoint; las rutas principales v1 también aplican un control por IP de 2,000 solicitudes/minuto. Los eventos web tienen sus propios límites por fuente.

Buenas prácticas

Idempotencia

Para POST /api/v1/events, incluye un valor estable de idempotency_key al reintentar el mismo evento. Los demás endpoints tienen sus propias reglas de reintento e idempotencia.

  • Usa una clave única y determinista (por ejemplo, checkin-{booking_id})
  • Los eventos principales comparan la clave con eventos almacenados; no existe una ventana universal de 24 horas
  • Un evento principal duplicado devuelve su ID con status: "duplicate"
Gestión de errores

Gestiona estos casos de fallo en tu integración:

  • Reintenta los errores 5xx transitorios con espera progresiva según las reglas de idempotencia del endpoint
  • Ante un HTTP 429, respeta Retry-After. Corrige los demás errores 4xx antes de reintentar
  • Registra las respuestas de error para depurar
  • Revisa los códigos de error y los resultados de cada elemento del lote; los formatos de respuesta varían por familia de API
  • Elige tiempos de espera adecuados para el endpoint y evita envíos duplicados concurrentes
Fiabilidad de los webhooks

Asegura la fiabilidad de tus endpoints de webhook:

  • Confirma cuanto antes los payloads verificados con una respuesta 2xx
  • Procesa los webhooks de forma asíncrona si es necesario
  • Configura un secreto de firma de webhook y verifica la firma antes de procesar
  • Implementa procesamiento idempotente (los webhooks pueden entregarse más de una vez)
  • Usa identificadores estables del payload para procesar de forma idempotente. X-Webhook-Delivery identifica un intento
Formato del número de teléfono

Usa siempre el formato E.164 para teléfonos:

  • Empieza por + y código de país (p. ej., +1 para EE. UU., +34 para España)
  • Sin espacios, guiones ni paréntesis
  • Codifica el + como %2B en los parámetros de consulta de la URL
  • Ejemplo: +34612345678 (España)
Pruebas

Usa nuestro sandbox para desarrollar y probar:

  • Usa el modo simulado para respuestas de ejemplo. El modo real envía solicitudes reales con tu clave de API
  • Prueba todos los escenarios de error (validación, autenticación, límites)
  • Usa el sandbox interactivo en /developers/sandbox
  • Prueba la verificación de firmas de webhook en local
Guía de incorporación masiva
Patrones recomendados para incorporar grandes volúmenes de contactos y reservas

Flujo de integración recomendado

  1. Registra las definiciones de campos personalizados mediante POST /api/v1/fields (una vez)
  2. Envía datos de huéspedes y reservas mediante POST /api/v1/guests
  3. Activa eventos del ciclo mediante POST /api/v1/events

Concurrencia y rendimiento

  • Envía hasta 10 solicitudes concurrentes para obtener el mejor rendimiento
  • Límite predeterminado: 1000 solicitudes/min (contacta con nosotros para límites más altos)
  • Supervisa X-RateLimit-Remaining para respetar los límites
  • Implementa espera exponencial ante respuestas 429 (2 s, 4 s, 8 s y 16 s)

Deduplicación e idempotencia

  • El endpoint de huéspedes usa deduplicación por teléfono: enviar el mismo número actualiza el contacto existente
  • Establece update_if_exists: true (por defecto) para insertar o actualizar de forma segura
  • La deduplicación de reservas se limita al hotel y prueba primero reservation_id (guardado como external_id); si no, usa booking_id. Envía el mismo reservation_id para actualizar una línea de habitación y un valor compartido de booking_id para agrupar las habitaciones de una misma reserva
  • El endpoint de eventos usa idempotency_key para deduplicar; sigue el contrato de reintento documentado del endpoint

Consejos de rendimiento

  • Usa hotel_code en lugar de hotel_name para buscar hoteles más rápido
  • Registra las definiciones de campos personalizados antes de enviar los datos del huésped
  • Incluye custom_fields en la solicitud de huésped para rellenar tanto el almacenamiento JSONB como el editor de segmentos
  • Los datos de reserva activan automáticamente el cálculo de etapa del huésped y los eventos de recorrido

Migración inicial de datos

Para migraciones iniciales de más de 100K contactos, contacta con nuestro equipo para aumentar temporalmente los límites y acordar una ventana de incorporación. Podemos supervisar el proceso en tiempo real para garantizar la integridad de los datos.

¿Todo listo para integrar?

Solicita acceso a la API para obtener tus credenciales y empezar a desarrollar.

GuestMaker

El CRM con IA omnicanal
para grupos hoteleros.

● de Hotelinking ↗
DESARROLLARInicio rápidoReferencia de la APIAutenticaciónWebhooksSandbox de API
EXPLORAREventos webSDK y bibliotecasFidelización y SSOCrédito monetarioNovedades
CONECTARSolicitar acceso a la APIPlataforma GuestMakerIntegraciones
© 2026 GuestMaker · Hotelinking, S.L.Palma de Mallorca, España
PrivacidadCondicionesAviso legal