Desarrolladores

Conecta cualquier canal a la recepción que nunca apaga la luz.

Lo que Alzio expone hoy para integradores: mensajes entrantes omnicanal, widget web, motor de reservas público, disponibilidad en vivo y calendario iCal. Solo endpoints en producción.

Base URLhttps://api.alzio.co

01

Introducción

Todas las rutas viven bajo https://api.alzio.co, reciben y responden JSON en UTF-8 (Content-Type: application/json) salvo el script del widget y el feed iCal. Los errores responden con un código HTTP y un cuerpo { "error": "…" }.

Cada hotel en Alzio es una propiedad. Según el endpoint la identificas por su propertyId (UUID) o por su slug (por ejemplo mi-hotel). Ambos te los entrega el equipo de Alzio al darte acceso.

02

Autenticación y límites

SuperficieAutenticación
Mensajes entrantesHeader x-inbound-secret con el secreto propio de cada hotel (lo genera el administrador en el panel)
Catálogo de canalesPública, informativa
Widget y API de chatPública; se identifica la propiedad por slug o id
Motor de reservas y disponibilidad en vivoPública; CORS abierto para usarla desde el sitio del hotel
Feed iCalToken privado en la URL del feed

Límites de uso: 1.500 solicitudes cada 15 minutos por IP en toda la API. La API de chat además limita a 20 mensajes por minuto por sesión y 60 por minuto por IP. Al superarlos recibes 429.

Guarda el secreto de mensajes entrantes solo en tu servidor. Nunca lo pongas en código de navegador.

Secreto por hotel

Cada hotel tiene su propio secreto de mensajes entrantes. Lo genera un administrador en Configuración → Conexiones → Integraciones · API de mensajes entrantes con el botón Generar secreto. El secreto completo se muestra una sola vez: cópialo en ese momento y guárdalo en tu servidor o gestor de secretos. Después el panel solo muestra sus últimos 4 caracteres.

  • El secreto de un hotel solo sirve para el propertyId de ese hotel: no abre la API de otros hoteles.
  • El mismo secreto protege POST /api/applications/intake (postulaciones desde formularios), donde el hotel se identifica con property_id en el cuerpo.
  • Rotar secreto genera uno nuevo y el anterior deja de funcionar de inmediato. Actualiza tus integraciones (Zapier, formularios, parsers de correo) justo después de rotarlo.
  • Envíalo siempre en el header x-inbound-secret. El parámetro ?secret= en la URL sigue aceptándose por compatibilidad, pero queda en registros de servidores y proxies: no lo uses en integraciones nuevas.
  • Hoteles sin secreto propio siguen aceptando temporalmente el secreto global que entregaba Alzio. Ese modo está en desuso: genera el secreto de tu hotel y migra tus integraciones.

03

Mensajes entrantes (omnicanal)

POST/api/inbound/:propertyIdx-inbound-secret

Un contrato único para que cualquier canal alimente al agente de Ventas: correo, mensajes de OTAs, Google, foros, transcripciones de llamadas o un canal propio. Alzio corre el agente con el contexto del hotel y te devuelve la respuesta para que la entregues por el mismo medio. Si el canal es de la familia Meta (whatsapp, instagram, facebook, instagram_comment, facebook_comment), Alzio además la envía solo.

WhatsApp, Instagram y Facebook ya llegan a Alzio por su conexión nativa: no necesitas este endpoint para ellos.

Cuerpo

CampoTipoDescripción
channelstringClave del canal (ver catálogo). Si no existe, se trata como generic.
sender_idstringIdentificador estable del remitente. Agrupa la conversación.
sender_namestring · opcionalNombre visible del huésped.
textstringMensaje del huésped. Obligatorio, máximo 6.000 caracteres.
thread_idstring · opcionalSe usa como identificador si no envías sender_id.
Solicitud · curl
curl -X POST https://api.alzio.co/api/inbound/<propertyId> \
  -H "Content-Type: application/json" \
  -H "x-inbound-secret: <secreto-de-tu-hotel>" \
  -d '{
    "channel": "email",
    "sender_id": "ana@correo.com",
    "sender_name": "Ana",
    "text": "Hola, ¿tienen habitación doble del 12 al 14 de octubre?"
  }'
Respuesta · 200
{
  "reply": "¡Hola, Ana! Sí tenemos disponibilidad del 12 al 14 de octubre…",
  "channel": "email",
  "channel_status": "bridge",
  "delivery": "return",
  "sent": false,
  "conversation_id": "5b0c…",
  "images": [],
  "send_error": null
}

delivery vale auto cuando Alzio ya envió la respuesta y return cuando la debe entregar tu integración. Si un humano del hotel tomó la conversación, la respuesta es { "reply": null, "paused": true, … } y no debes contestar nada.

CódigoCuándo
400propertyId no es un UUID, falta text o supera 6.000 caracteres.
401Secreto ausente o inválido, o secreto de otro hotel. Si el hotel ya tiene secreto propio, el secreto global deja de servir.
404property_not_found.
503El hotel no tiene secreto propio y el servidor no tiene secreto global configurado.

04

Catálogo de canales

GET/api/inbound/channelsPública

Lista las claves de canal que acepta channel, con su estado y cómo sale la respuesta.

Solicitud · curl
curl https://api.alzio.co/api/inbound/channels
Respuesta · 200 (extracto)
{
  "channels": {
    "whatsapp": { "label": "WhatsApp", "icon": "💬", "outbound": "meta", "status": "live" },
    "web":      { "label": "Sitio web", "icon": "🌐", "outbound": "inline", "status": "live" },
    "email":    { "label": "Email", "icon": "✉️", "outbound": "return", "status": "bridge" },
    "booking":  { "label": "Booking.com", "icon": "🏨", "outbound": "return", "status": "bridge" },
    "phone":    { "label": "Llamada", "icon": "📞", "outbound": "return", "status": "voice" },
    "generic":  { "label": "Otro canal", "icon": "🔗", "outbound": "return", "status": "bridge" }
  }
}
outboundSignificado
meta · meta_commentAlzio envía la respuesta por la API de Meta (mensaje directo o respuesta a comentario).
inline · returnLa respuesta vuelve en el cuerpo y la entrega quien llamó.

Claves disponibles: whatsapp, instagram, facebook, instagram_comment, facebook_comment, web, widget, email, phone, tiktok, booking, airbnb, expedia, hostelworld, despegar, google, tripadvisor, forum y generic.

05

Widget web

GET/embed.js?tenant=:slugPública

Un chat del agente de Ventas para el sitio del hotel, con el nombre, logo y colores configurados en Alzio. Pega el script antes de </body>.

HTML
<script>
  window.AlzioConfig = {
    property: 'mi-hotel',  // slug de la propiedad (opcional)
    language: 'es',        // es | en | pt | fr | de
    autoOpen: false        // abre el chat a los 8 s
  };
</script>
<script src="https://api.alzio.co/embed.js?tenant=mi-hotel" async></script>

El script se cachea 5 minutos: los cambios de marca en el panel se ven en ese tiempo.

06

API de chat

Es la API que usa el widget. Sirve para construir tu propia interfaz de chat.

POST/api/chat/initPública

Crea una sesión y devuelve el saludo en el idioma pedido.

Solicitud · curl
curl -X POST https://api.alzio.co/api/chat/init \
  -H "Content-Type: application/json" \
  -d '{ "property_slug": "mi-hotel", "language": "es" }'
Respuesta · 200
{
  "session_id": "8f3a…",
  "greeting": "¡Hola! Soy el asistente de Mi Hotel. ¿En qué te puedo ayudar hoy?",
  "property_slug": "mi-hotel"
}
POST/api/chatPública
CampoTipoDescripción
messagestringMensaje del huésped. Obligatorio.
session_idstring · opcionalEl de /init. Si no lo envías, se crea uno nuevo.
property_slug o property_idstringPropiedad activa. Uno de los dos es obligatorio.
utm_source, utm_medium, utm_campaignstring · opcionalAtribución de la conversación.
Solicitud · curl
curl -X POST https://api.alzio.co/api/chat \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "8f3a…",
    "property_slug": "mi-hotel",
    "message": "¿Cuánto cuesta una noche para dos personas?"
  }'
Respuesta · 200
{
  "reply": "Para dos personas tenemos…",
  "message": "Para dos personas tenemos…",
  "session_id": "8f3a…",
  "conversation_id": "c41d…",
  "booking": null,
  "response_time_ms": 5210,
  "escalated": false,
  "escalation_id": null,
  "escalation_reason": null,
  "tools_used": ["check_availability"],
  "language": "es"
}

Errores: 400 sin mensaje o sin propiedad, 404 propiedad inexistente, 403 propiedad inactiva, 429 por límite de uso.

07

Motor de reservas público

Para un motor de reservas propio sobre el inventario que el hotel maneja en Alzio. El precio siempre se calcula en el servidor.

GET/api/public/book/:slugPública

Datos de la propiedad y sus tipos de habitación activos.

Respuesta · 200
{
  "property": {
    "id": "…", "name": "Mi Hotel", "brand_name": "Mi Hotel",
    "brand_logo_url": "https://…", "brand_primary_color": "#0A1628",
    "location": "Cartagena", "maps_url": "https://…",
    "languages": ["es", "en"], "whatsapp_number": "+57…"
  },
  "room_types": [
    { "id": "…", "name": "Doble", "slug": "doble", "description": "…",
      "capacity": 2, "base_price": 320000,
      "amenities": ["wifi"], "photos": ["https://…"] }
  ]
}
POST/api/public/book/:slug/availabilityPública
Solicitud · curl
curl -X POST https://api.alzio.co/api/public/book/mi-hotel/availability \
  -H "Content-Type: application/json" \
  -d '{ "check_in": "2026-10-12", "check_out": "2026-10-14", "adults": 2 }'
Respuesta · 200
{
  "available": [
    { "room_id": "…", "room_number": "101", "room_name": "Doble vista al mar",
      "room_type": { "id": "…", "name": "Doble", "base_price": 320000 },
      "price_per_night": 320000, "total": 640000, "nights": 2 }
  ],
  "nights": 2,
  "check_in": "2026-10-12",
  "check_out": "2026-10-14"
}
POST/api/public/book/:slug/reservePública
CampoTipoDescripción
room_idstringObligatorio. Sale de /availability.
check_in, check_outfecha AAAA-MM-DDObligatorios. check_out posterior a check_in.
guest_first_name, guest_emailstringObligatorios.
guest_last_name, guest_phonestring · opcionalDatos del titular.
guest_document_type, guest_document_number, guest_nationalitystring · opcionalDocumento del titular.
adults, childrennúmero · opcionalPor defecto 1 adulto y 0 niños.
special_requestsstring · opcionalSolicitudes especiales.
Respuesta · 201
{
  "reservation": { "id": "…", "status": "confirmed", "total_amount": 640000, "currency": "COP", "…": "…" },
  "payment_link": "https://checkout.wompi.co/p/?…",
  "confirmation_number": "RV-1A2B3C4D",
  "message": "Reserva confirmada para Ana. Completa el pago en el enlace."
}

payment_link puede venir en null si no hay pasarela configurada. Errores: 400 campos o fechas inválidas, 404 propiedad o habitación inexistente, 409 habitación ocupada o sin precio.

08

Disponibilidad en vivo (LobbyPMS)

Para propiedades que usan LobbyPMS: Alzio consulta el PMS en vivo por ti, así tu sitio no necesita credenciales ni IP autorizada. Solo lectura.

GET/api/public/lobby/:slug/availabilityPública
Solicitud · curl
curl "https://api.alzio.co/api/public/lobby/mi-hotel/availability?check_in=2026-10-12&check_out=2026-10-14&adults=2&children=0"
Respuesta · 200
{
  "ok": true,
  "source": "lobbypms",
  "slug": "mi-hotel",
  "check_in": "2026-10-12",
  "check_out": "2026-10-14",
  "data": { "…": "respuesta de disponibilidad de LobbyPMS" }
}
GET/api/public/lobby/:slug/roomsPública

Catálogo de categorías en vivo. Respuestas con caché de borde (2 min disponibilidad, 10 min categorías). Si LobbyPMS falla responde 502 con { "ok": false } para que tu sitio use su respaldo.

09

Calendario iCal

GET/api/ical/:propertyId/:token.icsToken en la URL

Feed text/calendar con las reservas de la propiedad, listo para suscribirlo en una OTA o calendario. La URL completa la copia el hotel desde su panel de Alzio; un token inválido responde 403.

10

Solicita acceso

Para integrar mensajes entrantes necesitas el propertyId y el secreto de tu hotel (lo generas tú en el panel). Para el widget, el motor de reservas y la disponibilidad en vivo, el slug de la propiedad. Cuéntanos qué quieres conectar.

Solicita acceso