Webhooks

Tabla de contenidos

Introducción

Los webhooks permiten que un sistema externo (PMS, CRM, CDP, motor de reservas…) reciba en tiempo real los cambios que se producen en Fideltour, sin tener que consultar la API periódicamente.

Cuando ocurre un evento en Fideltour (se crea o actualiza un contacto, cambia su nivel de loyalty, se registra una reserva…), Hotel Data Hub (HDH) lo recibe y lo reenvía mediante una petición POST a la URL que el sistema externo nos haya indicado.

Los webhooks son el camino de Fideltour hacia el sistema externo. Para el camino contrario (enviar datos a Fideltour) se usan los endpoints de la API: Contactos, Movimientos, Consentimientos y Loyalty.

Cómo se activan

En las integraciones con sistemas externos, el equipo de integraciones de HDH da de alta los webhooks manualmente (las suscripciones por REST hooks descritas en Zapier y n8n son exclusivas de esas aplicaciones). Para activarlos, el sistema externo nos facilita:

  • La URL a la que quiere recibir cada tipo de webhook. Puede ser la misma para todos o una distinta por tipo.
  • Los tipos de webhook que necesita (ver tabla).
  • La cadena hotelera de la que quiere recibir los eventos.
  • Credenciales de autenticación básica (usuario y contraseña), solo si las necesita para los tipos que la admiten (ver Funcionamiento del envío).

Una vez configurados, los eventos empiezan a llegar en cuanto se producen; no se envía el histórico.

Funcionamiento del envío

  • Método y formato: POST con cuerpo JSON (Content-Type: application/json).
  • Un evento por petición: cada petición contiene un único objeto JSON (un contacto o un movimiento), nunca una lista.
  • Respuesta esperada: el sistema externo debe responder con un 200. Cualquier otro código, un error de red o la falta de respuesta se registra en HDH como envío fallido.
  • Tiempo de espera: 5 segundos para establecer la conexión y 30 segundos para recibir la respuesta. Recomendamos responder 200 en cuanto se recibe el evento y procesarlo después de forma asíncrona.
  • Sin reintentos: un envío fallido no se reintenta. Si el sistema externo necesita recuperar un dato perdido, puede consultarlo en la API de Contactos o de Movimientos.
  • Orden: los eventos se envían de forma asíncrona y no se garantiza el orden de llegada.
  • Autenticación: por defecto las peticiones no llevan autenticación. Los tipos Cambio de nivel de loyalty e Información de loyalty actualizada pueden enviarse con autenticación básica (Authorization: Basic …) si se nos facilitan usuario y contraseña.

Tipos de webhook disponibles

Tipo Cuándo se lanza Contenido
Contacto creado Se crea un contacto en Fideltour Ficha completa del contacto + hotel_chain
Contacto actualizado Fideltour notifica una actualización del contacto Ficha completa del contacto + hotel_chain
Contacto dado de baja El contacto se da de baja de las comunicaciones comerciales Payload reducido (event: "unsubscribe")
Cambio de nivel de loyalty El contacto cambia de nivel en el programa de fidelización Payload reducido (event: "level_updated")
Información de loyalty actualizada Cambian los datos de loyalty del contacto (puntos, nivel, tarjeta…) Ficha completa del contacto + hotel_chain + event: "loyalty_updated"
Email inválido El email del contacto pasa a estado inválido (rebote, dirección incorrecta…) Ficha completa del contacto + hotel_chain + event: "email_invalid"
Movimiento creado Se crea un movimiento (reserva, estancia…) en Fideltour Ficha completa del movimiento (incluye hotel_chain)
Movimiento actualizado Fideltour notifica una actualización del movimiento (estado, fechas, importe…) Ficha completa del movimiento (incluye hotel_chain)

En todos los payloads, hotel_chain es el código de la cadena hotelera en Fideltour.

Payloads

Los ejemplos usan datos ficticios. Los campos que son identificadores numéricos (province, town, level, custom_tags, hotels, room_type, regime, agency…) hacen referencia a objetos de Fideltour; su descripción está en las páginas de Contactos y Movimientos.

Fideltour puede añadir campos nuevos al contacto o al movimiento con el tiempo. Recomendamos que el sistema externo ignore los campos que no conozca en lugar de rechazar la petición.

Contacto creado y contacto actualizado

Ficha completa del contacto, tal y como está en Fideltour, más hotel_chain. Algunos campos útiles:

  • custom_tags / custom_tags_name: etiquetas del contacto (identificadores y nombres).
  • subscribed, gdpr_consent_personalized_commercial, whatsapp_subscribed_commercial, sms_subscribed_commercial…: estado de los consentimientos (ver Consentimientos).
  • email_status: 0 = nuevo, 1 = válido, 2 = verificado, 3 = rebotado, 4 = rebote permanente.
  • last_sent, last_opened, last_click: fecha del último email enviado, abierto y con clic.
  • external_object_id: identificador del contacto en el sistema externo, si se informó al crearlo.
  • custom_fields: campos personalizados de la cadena.
{
  "id": 12345678,
  "hotel_chain": "ABCD",
  "external_object_id": "PN-000123",
  "name": "Laura",
  "surname": "García López",
  "email": "laura.garcia@example.com",
  "email_status": 1,
  "phone1": "+34 600000000",
  "phone1_e164": "+34600000000",
  "gender": 2,
  "birthday": "1985-03-12",
  "language": "ES",
  "country": "ES",
  "province": 100001,
  "town": 200001,
  "zone": null,
  "address": "Calle Mayor 1",
  "post_code": "07001",
  "identification_document_type": 1,
  "identification_number": "00000000T",
  "business_name": null,
  "company_name": null,
  "work_place": null,
  "business_address": null,
  "fiscal_address": null,
  "source": 4,
  "notes": null,
  "photo": null,
  "subscribed": true,
  "date_subscribed": "2026-01-15T10:20:30.000000",
  "modification_date_subscribed": "2026-01-15T10:20:30.000000",
  "unsubscribe_reason": null,
  "gdpr_consent_personalized_commercial": false,
  "whatsapp_status": 0,
  "whatsapp_enabled": true,
  "whatsapp_subscribed_commercial": true,
  "whatsapp_subscribed_commercial_personalized": false,
  "sms_status": 0,
  "sms_enabled": true,
  "sms_subscribed_commercial": true,
  "sms_subscribed_commercial_personalized": false,
  "has_webpush_device": false,
  "last_hlr_status": null,
  "last_hlr_validated_at": null,
  "custom_tags": [300001, 300002],
  "custom_tags_name": ["Familia", "Repetidor"],
  "topics": [],
  "hotels": [1001, 1002],
  "level": 400001,
  "level_name": "Gold",
  "loyalty_card_number": "0000000012345678",
  "has_password": true,
  "points": 120,
  "level_points": 120,
  "value": 1,
  "loyalty_nights": 4,
  "loyalty_bookings": 1,
  "loyalty_last_booking_date": "2026-08-20",
  "loyalty_custom_tag_timestamp": null,
  "last_level_review": null,
  "kicked_out_loyalty": null,
  "is_profile_completed": false,
  "total_trips": 3,
  "total_bookings": 2,
  "review": null,
  "promo_code": null,
  "app_user_id": null,
  "last_sent": "2026-10-01T09:00:00.000000",
  "last_opened": "2026-10-01T10:30:00.000000",
  "last_click": null,
  "last_conversion": null,
  "company": null,
  "is_active": true,
  "created_at": "2026-01-15T10:20:30.000000",
  "updated_at": "2026-10-01T10:30:00.000000",
  "custom_fields": {}
}

Contacto dado de baja

{
  "hotel_chain": "ABCD",
  "contact": 12345678,
  "email": "laura.garcia@example.com",
  "event": "unsubscribe"
}

contact es el identificador del contacto en Fideltour. Si se necesita el resto de la ficha, se puede consultar en la API de Contactos.

Cambio de nivel de loyalty

{
  "hotel_chain": "ABCD",
  "contact": 12345678,
  "email": "laura.garcia@example.com",
  "level": 400001,
  "level_name": "Gold",
  "event": "level_updated"
}

Información de loyalty actualizada

Ficha completa del contacto (igual que en Contacto creado y contacto actualizado), con los datos de loyalty actualizados (level, level_name, points, level_points, loyalty_card_number…), más:

{
  "hotel_chain": "ABCD",
  "event": "loyalty_updated"
}

Email inválido

Ficha completa del contacto (igual que en Contacto creado y contacto actualizado), con el nuevo email_status, más:

{
  "hotel_chain": "ABCD",
  "event": "email_invalid"
}

Movimiento creado y movimiento actualizado

Ficha completa del movimiento tal y como está en Fideltour. Algunos campos útiles:

  • contact / contact_email: contacto al que pertenece el movimiento.
  • hotel: hotel del movimiento en Fideltour.
  • booking_type, status y sub_status: tipo y estado del movimiento (ver Movimientos).
  • localizer y trip_localizer: localizador de la reserva y del viaje.
  • external_object_id: identificador del movimiento en el sistema de origen.
{
  "id": 1000001,
  "hotel_chain": "ABCD",
  "hotel": 1001,
  "contact": 12345678,
  "contact_email": "laura.garcia@example.com",
  "contact_is_active": true,
  "booking_type": 0,
  "status": 1,
  "sub_status": 2,
  "localizer": "RES-2026-000123",
  "trip_localizer": "RES-2026-000123",
  "external_object_id": "RES-2026-000123",
  "trip": 500001,
  "date": "2026-10-01T12:00:00",
  "entrance": "2026-12-01",
  "departure": "2026-12-05",
  "is_checkin_realized": false,
  "is_checkout_realized": false,
  "adults": 2,
  "juniors": 0,
  "childs": 1,
  "babies": 0,
  "amount": "850.00",
  "currency": "EUR",
  "room_number": null,
  "room_type": 600001,
  "contracted_room_type": null,
  "upgraded_room_type": null,
  "regime": 700001,
  "contracted_regime": null,
  "upgraded_regime": null,
  "fare_type": 800001,
  "category": null,
  "agency": null,
  "trip_agency": null,
  "event_type": null,
  "package": null,
  "offer": null,
  "promo_code": null,
  "input_channel": 4,
  "original_input_channel": null,
  "complex": null,
  "stay_complex": null,
  "trip_billing_complex": null,
  "trip_billing_room_type": null,
  "trip_stay_complex": null,
  "trip_stay_room_type": null,
  "total_rooms": null,
  "level": null,
  "notes": null,
  "url": null,
  "mac_addr": null,
  "link_click": null,
  "is_from_quote": null,
  "is_processed_loyalty": false,
  "trustyou_sent": false,
  "updated_at": "2026-10-01T12:00:00.000000",
  "custom_fields": {}
}