API Civitatis (2.0.2)

El presente documento define la funcionalidad y especificaciones básicas para hacer uso del API público de Civitatis relativo a la reserva de actividades y traslados.

Audiencia

El objetivo de este documento es proporcionar a agentes externos información relativa al funcionamiento del API, con el fin de evaluar y desarrollar la integración en su sitio web.

Introducción

Civitatis provee de un interfaz de programación de aplicaciones (API) que proporciona acceso a información y funcionalidad relacionada con la representación y reserva de los productos que ofrece. A continuación se detalla el flujo completo de reserva y los recursos disponibles.

Gestión de Errores de Seguridad y Límites de Peticiones

Se listan los posibles códigos de respuesta a continuación

401 Unauthorized

Este código de respuesta indica que la solicitud no está autorizada. Puede deberse a problemas de autenticación con el token. Se recomienda verificar la validez y vigencia del token utilizado en la solicitud.

406 Not Acceptable

Cuando se recibe este código, significa que la solicitud ha sido bloqueada por el WAF ( Firewall de Aplicaciones Web ) debido a su naturaleza maliciosa o sospechosa.

HTTP 429 Too Many Requests

Este código indica que la solicitud ha sido bloqueada por el CDN al superar el límite máximo de peticiones por segundo. Actualmente, el límite está configurado en 20 peticiones por segundo durante 1 minuto, es decir, 1200 peticiones por minuto.

Changelog

FechaTipoDescripción
2026-10-27FeatPUT /cart/{cartId}/checkout devuelve ahora 400 cuando un traslado del carrito no se puede pre-reservar, con ese traslado en itemErrors[] (activityId null, code PREBOOK_FAILED, retryable false), el mismo error que ya daba una actividad. Hasta ahora ese caso respondía 200 y el traslado se quedaba sin reserva. Quita el traslado o vuelve a añadirlo antes de reintentar.
2026-10-14FeatSe ha extendido itemErrors[] a la respuesta 400 de PUT /cart/{cartId} (añadir un ítem a un carrito existente), con el mismo formato y reglas que ya tenía checkout. Hasta ahora, si el carrito contenía un ítem que ya no se podía reservar, respondía 400 sin indicar cuál, y el cliente no podía saber qué quitar. Es aditivo: errors no cambia; errorId pasa a ser 51, como en los demás endpoints del carrito que informan itemErrors.
2026-09-30FeatSe han añadido los campos opcionales fromAddress, fromPlaceId, toAddress y toPlaceId al payload de traslado de POST /transfers/cart y PUT /transfers/cart/{cartId}. Si se envían, el carrito muestra la dirección elegida en lugar de la zona y, en zonas de hotel, la prerrellena en el checkout web. Aditivo: sin ellos no cambia nada. Un valor que no sea string o de más de 255 caracteres devuelve 422.
2026-09-29Feat/cart/{cartId}/confirm documenta ahora el 400 que se devuelve cuando el precio de una reserva ha cambiado desde que se creó el carrito (errorId 51, Price changed, please update the cart.). No se cobra nada: vuelve a crear o actualiza el carrito para obtener el precio actual y confirma de nuevo.
2026-09-23Feat/cart/{cartId}/confirm devuelve ahora 409 Conflict (errorId 57) cuando ya hay otra confirmación del mismo carrito en curso. Así se evita que un carrito confirmado dos veces en paralelo se cobre dos veces. Confirma cada carrito una sola vez.
2026-09-23FeatSe ha extendido itemErrors[] a las respuestas 400 de POST /cart/{cartId}/confirm y GET /cart/{cartId}, con el mismo formato y reglas que ya tenía checkout. Se ha publicado además la tabla de códigos conocidos (PAST_DATE, SOLD_OUT, INSUFFICIENT_ADVANCE, PAX_ABOVE_MAX, ACTIVITY_INACTIVE, CURRENCY_NOT_ALLOWED, BOOKING_EXPIRED, ALREADY_PAID, TRANSFER_UNAVAILABLE, TRANSFER_DATE_INVALID, PREBOOK_FAILED, UNKNOWN = no reintentable; UPSTREAM_ERROR = reintentable), marcada como informativa y no normativa.
2026-09-22FeatSe ha añadido el campo itemErrors[] a la respuesta 400 de PUT /cart/{cartId}/checkout: identifica qué ítem del carrito falló (itemId, activityId) y por qué (code, retryable), para no tener que reintentar a ciegas. Aditivo — errors no cambia. code es una lista abierta (trata cualquier valor desconocido como UNKNOWN); la señal normativa para reintentar es retryable, no la lista de códigos.
2026-09-11FixSe han retirado de la documentación los endpoints Legacy de calendario (/findByCoord/calendar, /activities/{id}/calendar, /destinations/{id}/calendar, /zones/{id}/calendar), obsoletos y sustituidos por el Calendario V2 (/calendar/activities, /calendar/activities/{activityId}). Los atributos availability y quotaAvailable (exclusivos del calendario Legacy) ya no se documentan.
2026-09-04FixSe ha ampliado a 12 meses la ventana de calendario que se consulta para construir la respuesta de /activities/{activityId}/checkoutData y de /activities/{activityId}/checkoutData/modalities (antes 7 y 2 meses respectivamente). Las actividades cuya primera fecha disponible caía fuera de esa ventana devolvían 404 aunque fuesen reservables; ahora responden 200. El 404 se mantiene con el mismo significado cuando la actividad no tiene ninguna fecha disponible en los próximos 12 meses.
2026-08-21FeatSe ha agregado el campo cartId en el schema Voucher de /bookings/{cartId}/items: se devuelve siempre nuestro cartId, aunque la petición se haya hecho con el agencyCartId propio de la agencia, para poder usarlo en el resto de endpoints que aceptan cartId. Además se aclara que itemId ya coincide con el bookingId (no hace falta un campo bookingId aparte).
2026-08-21FixCorregido el schema Voucher de /bookings/{cartId}/items: documentaba un campo url (string) que no existe en la respuesta real; el endpoint devuelve urls (array de strings, puede incluir varios documentos) y además el campo booleano hasDeferredVoucher, que no estaba documentado.
2026-08-19FixCorregido el schema de /activities/{activityId}/checkoutData/modalities: typology es un string (no un integer), se documenta el campo labelKey (antes ausente), options[].id es un integer (no string), y description de cada modalidad es un string (antes documentado como object). También se documenta el campo agencyCommission, y se añaden ejemplos reales distinguiendo actividad integrada/no integrada y modalidad en error.
2026-08-18FixCorregido el nombre de dos parámetros en /pois/{poiId}/activities: se documentaban como category y subCategory (singular), pero el endpoint espera categories y subCategories (plural, IDs separados por coma, semántica OR), igual que el resto de endpoints de listado. Enviados en singular no filtraban nada y la respuesta volvía completa, sin error. Si tu integración con este endpoint usa los nombres en singular, cámbialos al plural.
2026-08-18FeatEl buscador /search acepta ahora los mismos filtros que los endpoints de listado: categories, subCategories (IDs separados por coma, semántica OR), maxPrice (entero en céntimos, límite inclusivo), features (semántica AND, las mismas claves que publica la faceta features), guideLang y la ventana de disponibilidad startDate/endDate/startTime/endTime (se necesitan ambas fechas). A diferencia de los otros endpoints, viajan en el cuerpo de la petición, no en la query, igual que sortBy. Un valor inválido devuelve 400 en lugar de ignorarse; activityCurrency, que hasta ahora se aceptaba sin efecto, filtra. Dos matices importantes: los filtros se aplican sobre los resultados más relevantes que devuelve el buscador, no sobre el catálogo completo, así que pueden devolver pocos resultados —o ninguno— aunque existan más coincidencias fuera de ese conjunto (para filtrar el catálogo completo de una ubicación, usa los endpoints de destino, zona, POI o coordenada); y el orden por relevancia se mantiene, ya que filtrar elimina resultados pero nunca los reordena.
2026-08-17FeatLos cuatro endpoints de listado de actividades (/destinations/{id}/activities, /zones/{zoneId}/activities, /findByCoord, /pois/{poiId}/activities) aceptan ahora cuatro filtros que antes solo estaban disponibles a través de los contadores agregados: maxPrice (entero en céntimos de la moneda pedida, límite inclusivo, comparado contra el mismo precio que la respuesta expone en minimumPrice); features (claves de características separadas por coma, semántica AND, las mismas claves que publica la faceta features); la ventana de disponibilidad startDate/endDate/startTime/endTime (se necesitan ambas fechas, y un rango de fechas sin hora filtra a lo largo de todo el día); y agencyId (la agencia cuya cartera de productos filtra la respuesta, para llamantes con token de servicio sin agencia en el token — nunca afecta a los precios). Un valor inválido devuelve 400 en lugar de ignorarse. Los filtros de precio y características se aplican también a los addons de eSIM y seguro cuando la respuesta los incluye.
2026-08-14FeatNuevo endpoint /pois/{poiId}/activities: obtiene las actividades asociadas a un POI (punto de interés, identificado por su Google Place ID), con los mismos parámetros y estructura de respuesta que los endpoints de listado por destino y zona (paginación opcional page/limit, sortBy, category/subCategory, guideLang, include=localization).
2026-08-11FeatNuevo endpoint /filters: devuelve los contadores agregados (facets) de una localizacion —total, destinos, categorias, subcategorias, caracteristicas, idiomas de guia y rangos de precio y duracion— para poder pintar los filtros de una pantalla de venta con el numero de resultados de cada opcion. Requiere pedir antes el listado de la misma localizacion: lee una proyeccion cacheada que escriben los endpoints de listado, asi que sin ese paso previo responde 404. Ademas, los cuatro endpoints de listado (/destinations/{id}/activities, /zones/{zoneId}/activities, /findByCoord, /search) aceptan ahora paginacion opcional (page, limit, con cabeceras X-Total-Count, X-Page, X-Limit y Link), ordenacion (sortBy — en el cuerpo en el caso de /search) y el bloque opcional localization via include=localization; sus actividades incluyen los campos popularity e isGoldenTour, y lang acepta los codigos regionales br, mx y ar.
2026-08-07FeatSe ha documentado el endpoint /activities/{activityId}/checkoutData/modalities (no documentado hasta ahora) y se ha aclarado el significado del código 404 en este endpoint y en /activities/{activityId}/checkoutData: indica que la actividad no tiene fechas disponibles para reservar en el rango consultado (o que la actividad no existe), y no representa un fallo del servicio.
2026-07-23FeatSe ha documentado el array tags (ya existente) en la respuesta de actividades (endpoints /destinations/{id}/activities, /zones/{zoneId}/activities, /findByCoord, /search, /activities/{id}) y se ha añadido el nuevo valor SMALL_GROUP ("Grupo de hasta 12 personas") para actividades de grupo reducido (máximo 12 participantes). Diseñado para agencias B2B.
2026-08-28FixCorregida la duplicación de /v2 en la ruta del endpoint /transfers/destinations/{destinationId}/vehicles.
2026-08-28FixCorregida la base URL de los endpoints Traslados v3: se sirven bajo /v3 y no bajo /v2.
2026-06-30FeatYa está disponible Traslados v3: un nuevo flujo Cotizar → Reservar → Pagar con los endpoints /v3/transfers/quotes, /v3/transfers/quotes/{quoteId} y /v3/transfers/bookings. El flujo de traslados anterior (búsqueda → carrito → checkout) queda Legacy y se mantiene únicamente por compatibilidad con integraciones existentes.
2026-06-22FeatNuevo endpoint /activities/resolve que resuelve el activity_id a partir de una URL canónica de Civitatis.
2026-05-19FeatSe ha añadido un nuevo endpoint /additional-questions/typologies para exponer el catálogo de tipologías disponibles para preguntas adicionales en actividades. Retorna tipologías activas ordenadas por ID. Diseñado para agencias B2B para construir mapeos estáticos en sus integraciones.
2026-05-07FeatSe ha añadido el atributo typology en los elementos del array booking de la respuesta del endpoint /activities/{activityId}/checkoutData.
2026-04-15FeatSe ha agregado el campo booleano hasDeferredVoucher en los endpoints /activities/{id}, /cart/{cartId}/confirm y /bookings/activities/{bookingId}.
2026-03-25FeatSe ha agregado el campo status en el endpoint /bookings/activities/{bookingId}.
2025-12-27FeatSe ha agregado el campo booleano isTopActivity en los endpoints de listado de actividades. Endpoints afectados: /destinations/{id}/activities, /zones/{zoneId}/activities, /findByCoord, /search.
2025-06-10FeatSe ha agregado la informacion de los proveedores en el detalle de la actividad de los endpoints /activities/{id}, /destinations/{id}/activities, /zones/{zoneId}/activities, /search, /findByCoord.
2025-05-27FixSe ha eliminado el texto entre paréntesis (paréntesis incluidos) en el endpoint /activities/{id}.
2025-05-05FeatSe han agregado los parámetros opcionales "iataCodeFrom" y "iataCodeTo" en el endpoint /transfers/{cityId}/zones. Estos parámetros permiten filtrar los resultados utilizando los códigos IATA de los aeropuertos de origen y destino. Además, en el endpoint /transfers/{cityId}/zones ahora es posible filtrar tanto por zoneId como por código IATA, brindando mayor flexibilidad y precisión en las consultas relacionadas con zonas y aeropuertos.
2025-04-24FeatSe ha agregado la propiedad vehicleType en el listado de vehículos. /transfers/{cityId}/zones/{zoneFrom}/{zoneTo}/vehicles
2025-04-22FeatSe ha agregado el campo group en el objeto rates, en los endpoints de los nuevos calendarios de actividades. El campo indica el número mínimo y máximo de personas por grupo en cada categoría. Más info aquí.
2025-04-14FeatSe han agregado las propiedades meetAndGreet y adapted en el listado de vehículos. /transfers/{cityId}/zones/{zoneFrom}/{zoneTo}/vehicles
2025-03-20FeatSe ha agregado soporte para idiomas tropicales(Ar,Br,Mx) en los endpoints de actividades por Zona, Destinos y Coordenadas. Endpoints afectados: /destinations/{id}/activities, /zones/{zoneId}/activities, /findByCoord.
2024-12-17FeatSe ha añadido un nuevo endpoint para consultar la información de una reserva de traslados. Más información aquí
2024-11-28FeatSe ha añadido soporte para paginación en el endpoint del nuevo calendario por destinos, zonas y coordenadas. Más información aquí
2024-11-26FeatSe ha implementado un nuevo filtro en los endpoints de actividades múltiples que permite filtrar por las categorías y subcategorías, que puedes consultar a través de este endpoint.
2024-10-23FeatSe ha agregado el campo opcional "numberOfPersons" en el payload del endpoint /v2/cart para establecer el número exacto de personas a participar en una actividad por grupos. Más información aquí.
2024-10-23FeatNuevo endpoint para obtener calendarios de un destino, de una zona o a partir de unas coordenadas, con una nueva estructura, más información aquí
2024-10-16FeatNuevo endpoint de actividades individuales con nueva estructura, mas información aquí
2024-10-01FeatSe ha creado el nuevo endpoint /v2/cart/{{cartId}}/check-availability para comprobar la disponibilidad de los items de un carrito, en caso de que las actividades sean integradas.
2024-10-01FeatSe ha agregado la propiedad "rawLongDescription" que muestra la descripción larga en texto plano en los endpoints de actividades, más info aquí y asociados.
2024-09-24FeatSe ha incluido la cantidad mínima y máxima de pasajeros por categoría cuando la actividad es por grupo de personas. Este nuevo atributo se encuentra dentro del esquema rates->categories->group en la respuesta de los endpoints de actividades. Más información aquí y en el detalle de mínimos y máximos.
2024-09-19FeatSe ha agregado el campo "iata" en el endpoint de destinos. Más información aquí
2024-09-18FeatSe ha añadido el campo "guideLanguages" en las respuestas de los endpoints relacionados con actividades, el cual contiene un array con los idiomas disponibles de la guía para cada actividad. También se ha implementado el filtro "guideLang", que permite filtrar actividades por el idioma de la guía. Endpoints afectados: /activities/{id}, /activities/infinite-availability, /activities/new-activities, /findByCoord/calendar, /findByCoord, /destinations/{id}/activities, /zones/{zoneId}/activities, /destinations/1/calendar.
2024-09-13FeatNuevo endpoint para obtener precios dinamicos de una actividad. Más información aquí
2024-09-10FeatMejora en el ordenamiento de coincidencias en el endpoint /search, reordenando los resultados de actividades por relevancia.
2024-08-28FeatSe ha agregado un endpoint para obtener vehículos de traslados enviando coordenadas o el ID de la zona, tanto en origen como en destino. Más información aquí
2024-08-20FeatEl endpoint /activities/{id} tiene el nuevo campo "secondaryDestinationId", en el que se consultan los destinos secundarios de la actividad.
2024-07-30FixEl endpoint /transfers/{cityId}/zones/{zoneFrom}/{zoneTo}/vehicles devuelve correctamente los vehículos disponibles para el traslado.
2024-07-23FeatSe han agregado dos nuevos campos en el objeto Activity: hasAdditionalQuestions y hasPassengersQuestions /activities/{id}.
2024-07-05FixSe corrigió que al obtener las preguntas de pasajero en el endpoint /cart/{cartId} del carrito siempre se traia el label en español, y no el idioma de la actividad.

Glosario

Políticas de cancelación

En el atributo "cancelPolicies", ubicado en el endpoint de actividades, se definen las políticas asociadas a la cancelación de reservas. Aquí se especifican las penalizaciones y reembolsos en función del tiempo restante antes de la realización de la actividad.

A continuación, presentamos algunos ejemplos para facilitar la interpretación de esta información:


"cancelPolicies": [
  {
    "hours": 48,
    "penalty": 0,
    "type": "percent"
  }
] 

Esto significa que antes de 48 horas de la realización de la actividad se puede cancelar gratis, sin penalización


  "cancelPolicies": [
    {
      "hours": 120,
      "penalty": 25,
      "type": "percent"
    },
    {
      "hours": 240,
      "penalty": 15,
      "type": "percent"
    },
    {
      "hours": 504,
      "penalty": 0,
      "type": "percent"
    }
  ],

Por lo que sí son 504 horas antes del inicio de la actividad el reembolso es del 100%, 240 horas antes, la penalización de 15% (reembolso 85%), 120 horas antes sería el 25% de penalización (75% reembolso). Si la reserva se produce en menos de 120 horas la reserva no tiene reembolso.

"cancelPolicies": [
  {
    "hours": 0,
    "penalty": 100,
    "type": "percent"
  }
],

Esto quiere decir que no es reembolsable.

Las políticas de cancelación pueden estar basadas en dos tipos de penalizaciones: amount y percent.

Las penalizaciones de tipo percent se calculan como un porcentaje del precio total de la actividad; por ejemplo, una penalización del 25% significa que se descontará ese porcentaje del precio total, al realizar la cancelación.

En los casos en que el atributo "type" sea de tipo amount, el valor del atributo "penalty" indicará el montó a penalizar, por persona. Siempre se penalizará por persona independientemente de la categoría (adulto, niño, bebé). Se aplicará la misma penalización tanto para adultos como para niños, aunque el precio varíe. Tras la cancelación, se multiplicará la cantidad reflejada en el atributo "penalty" por la cantidad de personas para las cuales se haya hecho la reserva.

"cancelPolicies": [
    {
        "hours": 168,
        "penalty": 100,
        "type": "amount"
    }
]

En este ejemplo, si cancelas con más de 7 días de antelación tendrás una penalización de 100 € por pasajero. Si cancelas con menos tiempo, llegas tarde o no te presentas, no se ofrecerá ningún reembolso.

También puede darse el caso en la que la actividad cuente con una política de cancelación mixta. Es decir, que tenga penalización de tipo amount y de tipo percent. Las políticas de cancelación mixtas combinan penalizaciones tanto de tipo porcentaje como de monto fijo (en una cantidad específica de dinero). Cómo en los casos de penalización de tipo amount y percent, la penalización varía dependiendo de la antelación con la que se realice la cancelación.

"cancelPolicies": [
   {
       "hours": 336,
       "penalty": 60,
       "type": "percent"
   },
   {
       "hours": 504,
       "penalty": 40,
       "type": "percent"
   },
   {
       "hours": 720,
       "penalty": 200,
       "type": "amount"
   }
]

En este caso se combinan los dos tipos de penalización. Si cancelas con una antelación mayor a 30 días, se penaliza con 200 € por persona. Si cancelas entre 30 días y los 21 días de anticipación, se penaliza con el 40% del valor de la reserva. Si cancelas entre los 21 días a los 14 días de anticipación, se penaliza con el 60% del valor de la actividad. Y si cancelas entre los 14 dias hasta el día del disfrute de la actividad la reserva no tiene reembolso.

Categoría

La categoría de una actividad se refiere a la clasificación principal o general a la que pertenece. Es una etiqueta amplia que agrupa actividades similares por sus características fundamentales. Puede obtener el detalle del endpoint para obtener el listado aquí

Subcategoría

La subcategoría proporciona una clasificación más específica dentro de una categoría principal. Representa una división más detallada de las actividades. Puede obtener el detalle del endpoint para obtener el listado aquí

Tipo de monto

El atributo amountType aparece en varias respuestas de peticiones, durante la creación del carrito, o en la petición de actividades. Este valor puede ser NET o PVP, indicando que los montos mostrados de las actividades serán precio neto o precio PVP. Esta configuración se establece durante la creación del usuario.

Prefijo

Al momento de crear un carrito, el atributo prefix hace referencia al código numérico de teléfono del país. Los valores aceptados para este campo pueden obtenerse consultando el endpoint correspondiente al país (click aquí), atributo prefix

Wallet

El wallet permitirá cargar saldo para así poder realizar reservas con este saldo disponible de una forma segura. Se puede obtener su key (click aquí), la cual se usará para realizar la confirmación de la reserva.

Advance

El objeto Advance, de la respuesta de GET activities/{id}, indica el tiempo de antelación para poder reservar una actividad. Las propiedades days, días de antelación, y hour, hora límite para reservar, van a par, por lo que si vienen en null, se debe extraer la información de la otra propiedad del objeto, minutes before, que indica la cantidad de minutos de antelación para reservar la actividad. (detalles aquí):

Por ejemplo:

¿Cuándo reservar? Puedes reservar hasta las 19:00 horas del día anterior siempre que haya disponibilidad.

"advance": 
  {
    "days": 1,
    "hour": 19:00,
    "minutes_before": null
  }

¿Cuándo reservar? Puedes reservar hasta cinco días antes siempre que haya disponibilidad.

"advance":
{
  "days": null,
  "hour": null,
  "minutes_before": 7200
}

Mínimo y máximo de personas por actividad

Cada actividad puede tener restricciones específicas en cuanto al número mínimo y máximo de participantes. Estos parámetros determinan cómo y cuándo se puede realizar una reserva. Puedes consultar los siguientes campos en los detalles de la actividad realizando una petición al endpoint de la actividad. Por ejemplo:

GET {{url}}/v2/activities/{activityId}

  • minimumPaxPerBooking (integer): Número mínimo de personas requerido para realizar una reserva. Este campo es bloqueante para la creación del carrito con la cantidad de participantes. Si intentas reservar con una cantidad inferior, el sistema no permitirá la creación del carrito.

  • minimumPaxPerActivity (integer): Cantidad mínima de personas necesarias para llevar a cabo la actividad. Este campo es informativo y te indica cuántas personas se requieren en total para que la actividad se realice, independientemente de tu reserva individual.

  • maximumPaxPerActivity (integer o null): Número máximo de personas permitidas para una reserva. Si es nulo, no hay límite establecido. Este campo es bloqueante para la creación del carrito con la cantidad de participantes. Si intentas reservar con una cantidad que excede este límite, la reserva será rechazada.

Ejemplo de uso:

Si una actividad tiene:

  • minimumPaxPerBooking = 2
  • minimumPaxPerActivity = 5
  • maximumPaxPerActivity = 10

Significa que:

  • No puedes hacer una reserva para menos de 2 personas.
  • Se requiere de al menos cinco participantes para desarrollar la actividad, ese mismo día y hora. De no alcanzar el mínimo, el proveedor podría cancelar la actividad y proporcionar una alternativa. Éste es un campo informativo
  • No puedes reservar para más de 10 personas en una sola reserva.

Puedes encontrar más información sobre la estructura de la respuesta de este endpoint en la documentación.

Casos de Uso Relevantes

A continuación, presentamos una serie de escenarios comunes para la integración con la API de actividades. Estos ejemplos ofrecen consejos prácticos para implementar flujos de reserva y manejo de datos de manera eficiente. Para todos los casos, recomendamos hacer una petición al endpoint de actividades con disponibilidad infinita para obtener una lista de actividades aptas para probar los casos de uso.

1. Reservar una Actividad Regular con Pago y Cancelación

  • Busca una actividad en el endpoint recomendado (disponibilidad infinita) y selecciona una que tenga los atributos "hasAdditionalQuestions": false y "hasPassengersQuestions": false.
  • Verifica la disponibilidad de la actividad antes de realizar la reserva utilizando los endpoints de calendario.
  • Asegúrate de proporcionar los detalles correctos en la creación del carrito, como la fecha, tarifa y cantidad de participantes.
  • Una vez confirmado el pago, utiliza el endpoint correspondiente para obtener el voucher.
  • En caso de que quieras probar la cancelación, cancela la reserva mediante el endpoint adecuado, revisando posibles penalizaciones aplicables.
  • Guarda o registra el identificador del carrito y de los items reservados para seguimiento interno.

2. Reservar una Actividad con Preguntas Adicionales o Preguntas de Pasajero

  • Busca una actividad en el endpoint recomendado (disponibilidad infinita) y selecciona una que tenga los atributos "hasAdditionalQuestions": true y/o "hasPassengersQuestions": true.
  • Sigue el mismo flujo que hemos recomendado en el caso anterior, hasta la creación del carrito.
  • Tras la creación del carrito, realiza una solicitud GET al endpoint de checkout para obtener las preguntas adicionales.
  • Completa el proceso de checkout enviando la información requerida mediante un PUT al endpoint de checkout.
  • Verifica que todas las respuestas requeridas sean válidas antes de enviar la solicitud.
  • Confirma el pago y guarda el identificador.
  • Puedes obtener más información sobre las preguntas adicionales en la documentación.

3. Reservar una Actividad de Grupos de Personas

  • Busca una actividad en el endpoint recomendado (disponibilidad infinita) y selecciona una que tenga el atributo "isCategoryPaxGroup": true.
  • Especifica correctamente el número de participantes dentro del rango permitido para la categoría seleccionada.
  • Sigue el flujo recomendado en el primer caso.
  • Obten más información sobre las actividades por grupos de personas en la documentación sobre las actividades por grupos de personas isCategoryPaxGroup: true.

4. Reservar una Actividad con un Mínimo y/o Máximo de Participantes Obligatorio

  • Haz una petición al endpoint de actividades por destino y selecciona una actividad que tenga valores de los atributos minimumPaxPerBooking y minimumPaxPerActivity, mayores a 0.
  • Debes cerciorarte que se respeten el número minimo y máximo de personas a participar en la actividad al crear el carrito en el endpoint /v2/cart. Estos campos son bloqueantes, y si no se cumplen, la solicitud será rechazada.
  • Es recomendable que se controlen estos errores desde el desarrollo de la integración para que se adapte al usuario del sitio integrado al API.
  • Obtén más información sobre las restricciones de mínimo y máximo de participantes en la documentación sobre restricciones de participantes.

5. Reservar una Actividad de tipo FreeTour

  • Consulta los detalles de una actividad a través de actividades por destino, por ejemplo, y selecciona alguna actividad que tenga el atributo "isFreeTour": true.
  • Sigue el flujo creando el carrito, haciendo un GET checkout para obtener las preguntas adicionales y haciendo el PUT checkout introducir los datos.
  • Ten en cuenta que, al tratarse de un freeTour, la reserva se confirmará automáticamente al completar el checkout.
  • Obtén el voucher directamente como parte de la respuesta del PUT checkout sin necesidad de realizar un paso adicional de confirmación.
  • Obten más información sobre las actividades de tipo freeTour en la documentación.

6. Reservar una Actividad con Disponibilidad por Días (en lugar de Horas)

  • Reservar una actividad cuya disponibilidad se base en días completos, en lugar de horarios específicos. Podrás encontrarlas haciendo una petición a los endpoints de Calendario V2, por ejemplo, y selecciona una actividad que tenga en algún horario (hours) el atributo time:"", con el valor de un string vacío.
  • En caso de que el campo "time" en la respuesta del calendario aparezca como un string vacío (""), asegúrate de crear el carrito utilizando este mismo valor. Esto aplica para actividades que no tienen una hora específica de inicio, como entradas a museos o actividades que pueden disfrutarse a lo largo del día.
  • Obtén más información sobre la creación del cart en la documentación

7. Reservar actividades con precios dinámicos

8. Reservar actividades con "hasOneRate": true

  • Busca una actividad en el endpoint recomendado (disponibilidad infinita) y selecciona una que tenga el atributo "hasOneRate": true
  • Consulta la disponibilidad en el calendario. Verás que la actividad tiene un solo "rate".
  • Al crear el carrito, no será necesario elegir entre múltiples tarifas, ya que la actividad cuenta con una única opción de tarifa.
  • Sigue el flujo recomendado en el primer caso.

9. Reservar actividades con "hasOneRate": false

  • Busca una actividad en el endpoint recomendado (disponibilidad infinita) que tenga el atributo hasOneRate: false. Esto indica que la actividad cuenta con múltiples "rates" disponibles para seleccionar.
  • Verifica la disponibilidad de la actividad utilizando los endpoints de calendario para consultar fechas y horarios disponibles.
  • Examina las opciones en el array "rates" proporcionado en la respuesta del endpoint. Cada tarifa tiene categorías específicas que puedes seleccionar.
  • Durante las pruebas, selecciona un "rate" diferente al primero del array para confirmar que puedes manejar múltiples opciones.
  • Sigue el flujo recomendado en el primer caso.

Workflow actividades

Busqueda de actividades

Realiza una búsqueda detallada de actividades mediante diferentes criterios como destino, zona o coordenadas geográficas. A continuación, se presentan ejemplos de URLs para esta operación:

  • Búsqueda por destino (detalles aquí):

    • {url}/v2/destinations/{destinationId}/activities
  • Detalles de una actividad específica (detalles aquí):

    • {url}/v2/activities/{activityId}
  • Búsqueda por coordenadas (detalles aquí):

    • {url}/v2/findByCoord
  • Búsqueda por zona (detalles aquí):

    • {url}/v2/zones/{zoneId}/activities
  • Búsqueda por POI (detalles aquí):

    • {url}/v2/pois/{poiId}/activities

La respuesta incluirá una lista de actividades que coincidan con los criterios de búsqueda, proporcionando detalles detallados sobre la misma.

Búsqueda de Disponibilidad

Una vez identificadas las actividades de interés, es esencial verificar su disponibilidad. El Calendario V2 es la única fuente de verdad para disponibilidad, horarios y modalidades activas.

Source of Truth (disponibilidad y modalidades)

  • GET {url}/v2/activities/{activityId} se utiliza solo para información estática (descripción, políticas y estructura de tarifas).
  • GET/POST {url}/v2/calendar/activities es la fuente de verdad para disponibilidad, horarios y modalidades activas (rates).

Endpoints de Calendario V2 (Recomendados)

  • Obtener calendario de una actividad específica:

    • GET {url}/v2/calendar/activities/{activityId}

    Este endpoint te permite obtener la disponibilidad detallada de una actividad específica mediante su activityId. Detalles aquí.

  • Obtener calendario de actividades por destino, zona o coordenadas:

    • POST {url}/v2/calendar/activities

    En este endpoint, puedes enviar en el cuerpo de la solicitud (payload) uno de los siguientes parámetros para filtrar las actividades. Detalles aquí:

    • Por destinationId:

      {
        "destinationId": 1
      }
      
    • Por zoneId:

      {
        "zoneId": 1
      }
      
    • Por coordenadas:

      {
        "coordinate": {
          "latitude": "22.2951073",
          "longitude": "114.169665",
          "distance": "17"
        }
      }
      

    Este endpoint unificado permite obtener la disponibilidad de actividades filtrando por destino, zona o coordenadas geográficas. Proporciona una respuesta más completa y eficiente, facilitando la integración y reduciendo el número de llamadas necesarias.

Actividades con Precios Dinámicos

Cuando una actividad tiene el atributo hasDynamicPrice configurado en true, significa que los precios de dicha actividad pueden variar en función de factores como la fecha, la demanda o eventos especiales. Para obtener el precio exacto de la actividad en una fecha específica, es imprescindible realizar una consulta al siguiente endpoint de precios dinámicos.

Este proceso asegura que se presente el precio más actualizado en función de la fecha seleccionada por el usuario. No realizar esta consulta podría mostrar un precio incorrecto o desactualizado, lo que puede generar discrepancias en la oferta final.

Pasos a seguir:

  • Verificar si el atributo hasDynamicPrice está establecido en true para la actividad correspondiente.
  • Realizar una solicitud GET al endpoint mencionado, enviando la fecha obtenida a través del calendario, en la que se desea obtener el precio.
  • Utilizar el precio retornado por el endpoint para presentar la información al usuario o para la gestión interna de la actividad.

Notas importantes:

  • El Calendario V2 no gestiona precios dinámicos; estos siempre deben consultarse en /activities/{id}/dynamic-prices.
  • No es posible probar precios dinámicos en QA; las pruebas deben realizarse en Producción.

Recomendación adicional:

Al momento de generar el carrito, es altamente recomendable verificar el precio en el resumen del carrito. Esto garantiza que el precio final a aplicar sea el más actualizado y evita posibles incongruencias entre el precio mostrado inicialmente y el precio final de la reserva.

Información adicional sobre la disponibilidad de actividades (Calendario V2)

En el Calendario V2, la disponibilidad final se obtiene combinando los cupos de hour.quota y rate.quota.

Interpretación de la disponibilidad (modelo actual)

1.- hour.quota > 0 1.1 rate.quota = -1 --> Dispo = hour.quota
1.2 rate.quota = 0 --> Dispo = 0
1.3 rate.quota > 0 --> Dispo = rate.quota 2.- hour.quota = 0 2.1 rate.quota = -1 --> Dispo = 0
2.2 rate.quota = 0 --> Dispo = 0
2.3 rate.quota > 0 --> Dispo = rate.quota (inconsistencia de datos) 3.- hour.quota = -1 3.1 rate.quota = -1 --> Dispo = Infinita
3.2 rate.quota = 0 --> Dispo = 0
3.3 rate.quota > 0 --> Dispo = rate.quota

Consideraciones

  • hour.quota indica el cupo total del horario.
  • rate.quota indica el cupo específico de la modalidad.
  • -1 representa disponibilidad ilimitada.
  • El caso hour.quota = 0 con rate.quota > 0 se considera una inconsistencia de datos.

Estructura real del JSON del Calendario V2

El Calendario V2 devuelve dos bloques principales:

  • schedule: indica las fechas disponibles y qué configuraciones de tarifas (baseRatesId) aplican en cada fecha.
  • baseRates: contiene la información completa de horarios, modalidades (rates) y cupos (quota).
{
  "activityId": "373",
  "currency": "COP",
  "timeZone": "Europe/Rome",
  "hasHours": true,
  "schedule": [ ... ],
  "baseRates": { ... }
}

Notas clave sobre baseRates

  • baseRates es un objeto dinámico: cada clave es un baseRateId interno (por ejemplo: property1, aBcDeF1, xyz123).
  • No existe un campo literal llamado properties.
  • Cada entrada en baseRates representa una configuración de tarifas distinta.
  • El campo baseRateId es el identificador de referencia; la disponibilidad nunca debe inferirse del nombre de la clave.

Relación entre schedule y baseRates Para una fecha concreta:

  • se consulta schedule
  • se obtiene el listado de baseRatesId
  • se navega a baseRates[baseRateId]
  • se consultan los hours
  • se valida la disponibilidad con hour.quota y rate.quota

Navegación correcta para validar disponibilidad

schedule
 → baseRatesId
   → baseRates
     → hours
       → rates
         → quota

Creación del Carrito

Una vez que el usuario ha seleccionado una actividad específica, se agrega al carrito mediante una solicitud de creación de carrito. La respuesta incluirá detalles sobre la actividad agregada al carrito, así como información sobre el estado actual del carrito y los costos asociados. Puede encontrar mayor información aquí.

Obtención de Datos de la Reserva

Obtiene información preliminar sobre la reserva actual, incluyendo detalles de datos del usuario, preguntas de la actividad o preguntas del pasajero que se necesitarán responder en el paso siguiente, costos estimados y cualquier otro dato relevante para el usuario. Para más detalles, consulta aquí.

Nota importante

En el caso de las actividades de tipo freeTour, la reserva se confirmará automáticamente después del proceso de checkout que se menciona anteriormente y devolverá la respuesta con el tipo "Root type for voucher" en el siguiente endpoint.

Si la actividad no es de tipo freeTour, se devolverá la información del carrito con la respuesta de tipo "Cart", en el referido endpoint y se deberá realizar el proceso de confirmación, como detallamos más adelante.

Puedes identificar las actividades de tipo freeTour con el atributo isFreeTour en la información de las actividades, en el siguiente endpoint

Sobre las actividades por grupos de personas isCategoryPaxGroup: true

Cuando una actividad está marcada como una actividad por grupos de personas, utilizando la propiedad isCategoryPaxGroup: true, se define un rango específico de personas que pueden participar en dicha actividad. Este rango se especifica a través de las propiedades minimum y maximum, que están incluidas dentro del objeto group para cada categoría.

  • minimum Define el número mínimo de personas que deben participar en la actividad dentro de esa categoría específica.
  • maximum Define el número máximo de personas permitidas en la actividad dentro de esa categoría.
"rates": [
    {
        "id": 0,
        "text": "Tour privado de 4 horas",
        "categories": [
            {
                "id": 0,
                "text": "Hasta 5 personas",
                "canBookAlone": true,
                "group": {
                    "minimum": 1,
                    "maximum": 5
                }
            },
            {
                "id": 1,
                "text": "Hasta 10 personas",
                "canBookAlone": true,
                "group": {
                    "minimum": 1,
                    "maximum": 10
                }
            },
            {
                "id": 2,
                "text": "Hasta 15 personas",
                "canBookAlone": true,
                "group": {
                    "minimum": 1,
                    "maximum": 15
                }
            }
        ]
    }
]

Cuando la actividad no es por grupos de personas (isCategoryPaxGroup: false), el campo group vendrá como un objeto vacío [].


"rates": [
    {
        "id": 0,
        "text": "Tour en español",
        "categories": [
            {
                "id": 0,
                "text": "Adultos",
                "canBookAlone": true,
                "group": []
            },
            {
                "id": 1,
                "text": "Menores de 11 años",
                "canBookAlone": false,
                "group": []
            }
        ]
    }
]

Si la actividad es isCategoryPaxGroup: true, el usuario podrá integrar el campo numberOfPersons en el payload del endpoint /v2/cart para establecer el número exacto de personas a participar en la actividad por grupos. El campo deberá tener un entero entre el rango de minimum y maximum de la categoría seleccionada.

Ejemplo: Para la actividad, 183221, vemos que la categoría con id 1 tiene un rango de 1 a 4 personas.

                {
                "id": 1,
                "text": "Hasta 4 personas",
                "canBookAlone": true,
                "group": {
                    "minimum": 1,
                    "maximum": 4
                }

Por lo tanto, el campo numberOfPersons, del payload del endpoint /v2/cart debe tener un valor entre 1 y 4.

      {
    "activityId": 183221,
    "date": "2024-09-13",
    "currency": "USD",
    "rate": {
      "id": "0",
      "categories": [
        {
          "id": "1",
          "quantity": 1,
          "numberOfPersons": 3
        }
      ]
    },
    "time": "09:00"
  }

Parámetro: quantity

  • En actividades regulares: quantity representa la cantidad de personas para las que se está realizando la reserva dentro de una tarifa específica (por ejemplo, adultos o niños).Es decir, se indica cuántas personas se reservan bajo cada categoría de precio.

    Ejemplo: Actividad regular.

       {
        "activityId": 123456,
        "date": "2024-06-08",
        "currency": "EUR",
        "time": "10:00",
        "rate": {
        "id": 0,
        "categories": [
        {
           "id": 1,          // Tarifa adulto
           "quantity": 2     // 2 adultos
        },
        {
           "id": 2,          // Tarifa niño
           "quantity": 1     // 1 niño
        }
       ]
      }
     }
    
  • En actividades grupales: quantity va como numero entero siendo 1 el valor predeterminado para cada grupo y aunque se puede cambiar, siempre se cobra por un solo grupo,No importa si son adultos o niños, se cobra por grupo. numberOfPersons, que indica cuántas personas participarán en ese grupo. Este valor no afecta al precio, debe estar dentro del rango permitido por la categoría group.minimum y group.maximum.

    Ejemplo 2: Actividad Grupal

    { 
     "activityId": 175180,
     "date": "2024-06-08",
     "currency": "EUR",
     "time": "",
     "rate": {
     "id": 0,
     "categories": [
     {
       "id": 0,
       "quantity": 1, 
       "numberOfPersons": 6 //Número de personas dentro del grupo
      }
    ]
    }
    }
    

    Consideraciones adicionales

    • Si el valor de numberOfPersons está fuera del rango permitido de group.minimum y group.maximum, la reserva será rechazada.
    • Aunque quantity podría aceptar valores mayores a 1 se cobrara solo por un grupo.
    • Es importante consultar los campos group.minimum y group.maximum antes de enviar una reserva.

Rellenar Datos Adicionales de la Reserva

Durante este paso, se ingresa la información adicional necesaria para confirmar la reserva. Esto incluye responder preguntas específicas sobre la actividad o proporcionar detalles adicionales sobre los pasajeros. Para obtener más detalles sobre este proceso, haz clic aquí.

En caso de rellenar datos adicionales de los pasajeros

  • Para el ID del atributo passengers, por ejemplo, "passenger-1-0-663e2.206", el valor 0 se usa para agrupar al pasajero (es incremental en el caso de tener varios pasajeros). Esto significa que los ID "passenger-1-0-663e2.206" y "passenger-2-0-663e2.206" se refieren al mismo pasajero y a su vez el id "passenger-1-1-663e2.206" y "passenger-2-1-663e2.206" al otro pasajero. Para obtener más detalles sobre este proceso, haz clic aquí.

Obtención del Wallet Key

Antes de confirmar la reserva, obtendremos información esencial del Wallet asociado a la agencia, como su identificador único. Este Wallet Key se utiliza para identificar de manera segura la transacción durante el proceso de creación de la reserva.

Para ver más detalles haz clic aquí.

Creación de la Reserva

La reserva se crea oficialmente mediante una solicitud que incluye el Wallet Key obtenido anteriormente. La respuesta confirma la creación exitosa de la reserva y proporciona detalles finales, como números de confirmación y cualquier información adicional necesaria.

Para más información sobre la creación de la reserva, haz clic aquí.

Disponibilidad en el entorno de sandbox

Para obtener un listado de actividades con disponibilidad en el entorno de sandbox, puedes utilizar el siguiente endpoint: Obtener disponibilidad infinita de actividades (disponible para sandbox).

Propiedades del endpoint de disponibilidad infinita en el entorno de sandbox

  • hasCalendarHours: Si es false quiere decir que la actividad no tiene una hora específica para reservar. Podrías reservar dejando la propiedad time del payload del método POST del endpoint /v2/cart con un string vacío.

"activityId": 175180,
"date": "2024-06-08",
"currency": "EUR",
"time": "",
"rate": {
    "id": 0,
    "categories": [
        {
            "id": 0,
            "quantity": 1
        }
  • isCategoryPaxGroup: Indica si la actividad tiene tipos de entradas por grupos de personas. Si es true, la propiedad text de los elementos del objeto categories de la respuesta de activities/{activityId}, mostrará las categorías por grupos de personas.

"rates": [
    {
        "id": 0,
        "text": "Tour privado de 4 horas",
        "categories": [
            {
                "id": 0,
                "text": "Hasta 5 personas",
                "canBookAlone": true,
                "group": {
                    "minimum": 1,
                    "maximum": 5
                }
            },
            {
                "id": 1,
                "text": "Hasta 10 personas",
                "canBookAlone": true,
                "group": {
                    "minimum": 1,
                    "maximum": 10
                }
            },
            {
                "id": 2,
                "text": "Hasta 15 personas",
                "canBookAlone": true,
                "group": {
                    "minimum": 1,
                    "maximum": 15
                }
            }
        ]
    }
]
  • hasAdditionalQuestions: Indica si una actividad tiene preguntas adicionales. Si es true, el array booking de la respuesta de activities/{activityId}/checkoutData tendrá varios elementos de pregunta.

"booking": [{...},
                {
                    "id": "preguntaTitulo_0-663cc3e9519df6.37779825",
                    "label": "Onde voc\u00ea quer come\u00e7ar o tour?",
                    "type": "select",
                    "required": true,
                    "regex": null,
                    "options": [
                        {
                            "id": 0,
                            "text": "Porta do templo Wat Phra Singh (15:45 horas)."
                        },
                        {
                            "id": 1,
                            "text": "Porta do zool\u00f3gico de Chiang Mai (16:05 horas)."
                        }
                    ],
                    "value": "",
                    "uuid": null,
                    "labelTranslated": "Onde voc\u00ea quer come\u00e7ar o tour?"
                },
                {...}
            ],
  • hasPassengersQuestions: Indica si una actividad requiere los datos de los pasajeros. Si es true, la respuesta de activities/{activityId}/checkoutData tendrá la propiedad "passengers".

"booking": [{...},{...},{...} ],
"passengers": [
                {
                    "id": "passenger-1-0-663cc3e9519df6.37779825",
                    "label": "Nombre",
                    "type": "text",
                    "required": true,
                    "regex": null,
                    "options": null,
                    "value": "",
                    "uuid": null
                },
                {
                    "id": "passenger-2-0-663cc3e9519df6.37779825",
                    "label": "Apellidos",
                    "type": "text",
                    "required": true,
                    "regex": null,
                    "options": null,
                    "value": "",
                    "uuid": null
                },
                {
                    "id": "passenger-13-0-663cc3e9519df6.37779825",
                    "label": "Fecha nacimiento",
                    "type": "date",
                    "required": true,
                    "regex": null,
                    "options": null,
                    "value": "",
                    "uuid": null
                },
      
  • hasOneRate: Indica si una actividad tiene una única tarifa. Si es true, el array rate de la respuesta activities/{id} tendrá un solo elemento y si es false, tendrá más de un elemento.

 "rates": [
    {
        "id": 0,
        "text": "Tour sin vuelo de regreso",
        "categories": [
            {
                "id": 0,
                "text": "Adultos",
                "canBookAlone": true
            },
            {
                "id": 1,
                "text": "Niños de 7 a 12 años",
                "canBookAlone": false
            },
            {
                "id": 2,
                "text": "Menores de 7 años",
                "canBookAlone": false
            }
        ]
    },
    {
        "id": 1,
        "text": "Tour con vuelo de regreso",
        "categories": [{...}, {...}, {...}]   
    }
]

Encuentra más información sobre el endpoint GET infinite-availability aquí.

Workflow traslados

La integración recomendada es Traslados v3. El flujo v2 que se describe a continuación (búsqueda → carrito → checkout) queda Legacy y se mantiene únicamente por compatibilidad con integraciones existentes. Todos los nuevos desarrollos deben usar v3.

Traslados v3 (recomendado)

v3 simplifica el flujo a Cotizar → Reservar → Pagar y elimina la complejidad geográfica (sin mapeo de zonas/destinos): cotizas directamente usando códigos IATA, Google Place IDs o coordenadas GPS, y los trayectos de ida y vuelta se cotizan en una sola llamada.

  1. Cotizar — POST {url}/v3/transfers/quotes (detalles aquí). Devuelve quotes[], cada una con un quote_id, un TTL (expires_at) y el detalle por tramo en segments[]. El array booking_requirements de cada segmento indica qué datos extra son obligatorios para reservar ese tramo.
  2. Reservar — POST {url}/v3/transfers/bookings (detalles aquí). Envía el quote_id, el holder y los outbound_details / inbound_details requeridos (y addons opcionales). Devuelve un cart_id.
  3. Pagar — POST {url}/v2/cart/{cartId}/confirm (detalles aquí). Reutilizado de v2; su respuesta no cambia. v3 devuelve un cart_id compatible.

También puedes recuperar una cotización ya generada con GET {url}/v3/transfers/quotes/{quoteId} (detalles aquí), sin repetir la búsqueda de disponibilidad.

Diferencia entre Traslados v2 (Legacy) y v3

ConceptoTraslados v2 (Legacy)Traslados v3
Identificar zonaGET /v2/destinations + mapeo de zonasEliminado — IATA / Google Place ID / coordenadas directos
DisponibilidadPOST /v2/transfers/destinations/{id}/vehiclesPOST /v3/transfers/quotes (devuelve quote_id con TTL)
Ida y vueltaDos llamadas independientesUna llamada con type: "ROUND_TRIP"
SelecciónAñadir al carrito POST /transfers/cartUsar quote_id
ReservaPUT /cart/{cartId}/checkoutPOST /v3/transfers/bookings
PagoPOST /cart/{cartId}/confirmPOST /cart/{cartId}/confirm (reutilizado)

Para garantizar un mejor rendimiento y nuevas funcionalidades, todas las futuras mejoras se implementarán exclusivamente en Traslados v3. Los endpoints v2 de abajo se mantienen únicamente por compatibilidad con integraciones existentes.

Búsqueda de Traslados (Legacy — coordenadas recomendadas)

Prioriza el uso de coordenadas para evitar ambigüedades y mejorar la precisión en la disponibilidad de traslados. El endpoint recomendado es:

  • POST {url}/v2/transfers/destinations/{destinationId}/vehicles (detalles aquí)

En este endpoint puedes enviar coordenadas de origen y destino. La información obtenida acerca del vehículo es esencial para llevar a cabo la reserva.

Legacy (compatibilidad):

  • Los endpoints basados en zonas se mantienen solo por compatibilidad con integraciones existentes: /v2/transfers/{cityId}/zones/{zoneFrom}/{zoneTo}/vehicles y /v2/transfers/{cityId}/zones.

Round trip (ida y vuelta):

  • La disponibilidad de un traslado ida y vuelta requiere dos llamadas independientes (una por cada trayecto).

Coordenadas disponibles en sandbox (ejemplo):

{
  "fromCoordinate": {
    "latitude": 41.390205,
    "longitude": 2.154007
  },
  "toCoordinate": {
    "latitude": 41.720233,
    "longitude": 2.933432
  },
  "filters": {
    "pax": 3,
    "date": "2026-02-24",
    "time": "10:00",
    "currency": "EUR"
  }
}

Creación del Carrito

Una vez que el usuario ha seleccionado un traslado específico, se añade al carrito mediante una solicitud de creación de carrito. La respuesta incluirá detalles sobre el traslado agregado, así como información acerca del estado actual del carrito y los costos asociados. Puedes encontrar más información aquí.

Hora de Recogida

Al crear el carrito, en el atributo time es importante indicar la hora del vuelo/tren cuando el destino es de tipo "Airport", "Port", "Train".

  {
      "id": 3,
      "label": "Porto per navi da crociera",
      "type": "Port",
      "iata": "",
      "minAdvance": 24
  },

Obtención de Datos de la Reserva

Obtén información preliminar sobre la reserva actual, que incluye detalles del usuario, preguntas específicas sobre el traslado o del pasajero que necesitarán respuesta en el siguiente paso, costos estimados y cualquier otro dato relevante. Para obtener detalles adicionales, consulta aquí.

Rellenar Datos Adicionales de la Reserva

Durante este paso, se introduce la información adicional necesaria para confirmar la reserva. Esto implica responder preguntas específicas sobre el traslado o proporcionar detalles adicionales sobre los pasajeros. Para más detalles sobre este proceso, haz clic aquí.

Nombre del hotel:

  • Cuando el traslado requiera nombre de hotel, debe enviarse como respuesta a la pregunta adicional correspondiente (por ejemplo, "Hotel de recogida" o "Hotel de destino") en el payload del checkout.

Obtención del Wallet Key

Antes de confirmar la reserva, se obtiene información esencial del Wallet asociado a la agencia, como su identificador único. Este Wallet Key se utiliza para identificar de manera segura la transacción durante el proceso de creación de la reserva.

Para ver más detalles haz clic aquí.

Creación de la Reserva

La reserva se crea oficialmente mediante una solicitud que incluye el Wallet Key obtenido anteriormente. La respuesta confirma la creación exitosa de la reserva y proporciona detalles finales, como números de confirmación y cualquier información adicional necesaria.

Para más información sobre la creación de la reserva, haz clic aquí.

Certificación de Traslados

Para validar la integración de traslados, sigue este checklist mínimo:

  • Búsqueda de vehículos con coordenadas (origen/destino).
  • Reserva de un trayecto ida y otro de vuelta (dos llamadas).
  • Creación del carrito, respuesta de preguntas adicionales (incluyendo hotel si aplica) y confirmación.
  • Validación de la respuesta final de la reserva y del voucher si aplica.

Preguntas Frecuentes sobre la API de Civitatis

  1. ¿Cómo manejo los errores de autenticación al consumir la API de Civitatis?

    Respuesta: Si recibes un código de respuesta 401 Unauthorized, significa que la solicitud no está autorizada. Esto puede deberse a problemas de autenticación con el token. Verifica la validez y vigencia del token utilizado en la solicitud y asegúrate de que estás enviando las credenciales correctas.

  2. ¿Qué significa el código de error 406 Not Acceptable?

    Respuesta: El código 406 Not Acceptable indica que la solicitud ha sido bloqueada por el WAF (Firewall de Aplicaciones Web) debido a su naturaleza maliciosa o sospechosa. Asegúrate de que tu solicitud cumple con los parámetros y formatos esperados por la API y que no contiene contenido malicioso.

  3. ¿Cómo puedo evitar el error 429 Too Many Requests?

    Respuesta: El error 429 Too Many Requests ocurre cuando se supera el límite máximo de peticiones por segundo, que actualmente es de 20 peticiones por segundo durante 1 minuto (1200 peticiones por minuto). Para evitar este error, implementa mecanismos de control de flujo en tu aplicación para limitar el número de solicitudes que envías a la API.

  4. ¿Cómo funcionan las políticas de cancelación en las actividades?

    Respuesta: Las políticas de cancelación se definen en el atributo cancelPolicies de la actividad. Incluyen penalizaciones y reembolsos en función del tiempo restante antes de la realización de la actividad. Las penalizaciones pueden ser de tipo percent (porcentaje) o amount (monto fijo por persona). Es importante revisar estas políticas para informar adecuadamente a los usuarios sobre las condiciones de cancelación.

  5. ¿Qué son las categorías y subcategorías en una actividad?

    Respuesta: La categoría es la clasificación principal o general a la que pertenece una actividad, agrupando actividades similares por sus características fundamentales. La subcategoría proporciona una clasificación más específica dentro de una categoría principal, representando una división más detallada de las actividades. Puedes obtener el listado de categorías y subcategorías mediante los endpoints correspondientes.

  6. ¿Qué es el "amountType" y cómo afecta a los precios?

    Respuesta: El atributo amountType indica si los montos mostrados de las actividades son precio neto (NET) o precio de venta al público (PVP). Esta configuración se establece durante la creación del usuario y afecta cómo se muestran y calculan los precios en la API.

  7. ¿Cómo se utiliza el "wallet" para realizar reservas?

    Respuesta: El wallet permite cargar saldo para realizar reservas de forma segura. Debes obtener la wallet key mediante el endpoint correspondiente y utilizarla al confirmar la reserva. Esto asegura que la transacción se realice de manera segura y autorizada.

  8. ¿Qué es el objeto "advance" y cómo afecta a las reservas?

    Respuesta: El objeto advance, de la respuesta de GET activities/{id}, indica el tiempo de antelación necesario para poder reservar una actividad. Puede especificar días y hora límite para reservar o minutos de antelación. Por ejemplo, si advance indica 1 día y hora 19:00, significa que puedes reservar hasta las 19:00 horas del día anterior a la actividad.

  9. ¿Cómo valido las preguntas de tipo fecha?

    Respuesta: Las respuestas a preguntas de tipo date deben tener alguno de los siguientes formatos: Y-m-d, Y/m/d, d-m-Y, d/m/Y. Si la fecha no cumple con alguno de estos formatos, se mostrará un mensaje de error indicando que el formato es incorrecto. En particular, cuando obtenemos los datos para reservar a través de la petición GET Checkout podríamos recibir preguntas de tipo date. Por ejemplo.

       {
           "id": "passenger-6-0-668d0622e21af0.78717589",
           "label": "Fecha caducidad pasaporte",
           "type": "date",
           "required": true,
           "regex": null,
           "options": null,
           "value": "",
           "uuid": null
      }
    

    Las respuestas de tipo date, a completarse en el siguiente endpoint, deben tener alguno de los siguientes formatos:

    ['Y-m-d', 'Y/m/d', 'd-m-Y', 'd/m/Y']
    

    En caso de que la fecha no cumpla con el formato, se mostrará un mensaje de error.

    {"error":"The parameter id 'passenger-6-0-668d0622e21af0.78717589' of type date doesn't have a correct format, current value: '18\/05\/1993 0:00:00'."}
    
  10. ¿Cuál es el flujo de trabajo para reservar actividades?

    Respuesta: El flujo general para reservar actividades es:

    • Buscar actividades mediante los endpoints de búsqueda por destino, zona o coordenadas.
    • Obtener disponibilidad de las actividades.
    • Crear un carrito y agregar las actividades seleccionadas.
    • Obtener los datos de la reserva, incluyendo preguntas adicionales si las hay.
    • Rellenar los datos adicionales de la reserva.
    • Obtener la wallet key para confirmar la reserva.
    • Confirmar la reserva utilizando la wallet key.
  11. ¿Cómo busco actividades y su disponibilidad?

    Respuesta:: Para obtener la disponibilidad, se recomienda utilizar los endpoints de calendario v2, ya que ofrecen mejoras significativas y serán mantenidos en futuras versiones:

    • Obtener calendario de una actividad específica:

      GET /v2/calendar/activities/{activityId}

    • Obtener calendario de actividades por destino, zona o coordenadas:

      POST /v2/calendar/activities

      En este endpoint, puedes enviar en el cuerpo de la solicitud uno de los siguientes parámetros:

      • Por Destino:

        {
          "destinationId": 1
        }
        
      • Por Zona:

        {
          "zoneId": 1
        }
        
      • Por Coordenadas:

        {
          "coordinate": {
            "latitude": "22.2951073",
            "longitude": "114.169665",
            "distance": "17"
          }
        }
        

    Estos endpoints unifican y mejoran las funcionalidades anteriores, permitiendo obtener la disponibilidad de actividades de manera más eficiente y con menos solicitudes.

  12. ¿Cómo manejo actividades con precios dinámicos?

    Respuesta: Si una actividad tiene el atributo hasDynamicPrice configurado en true, significa que los precios pueden variar según la fecha, demanda u otros factores. Debes consultar el endpoint de precios dinámicos para obtener el precio exacto en una fecha específica. Además, es recomendable verificar el precio en el resumen del carrito antes de confirmar la reserva.

    • El Calendario V2 no gestiona precios dinámicos.
    • No es posible probar precios dinámicos en QA; las pruebas deben realizarse en Producción.
  13. ¿Cómo creo un carrito y agrego actividades?

    Respuesta: Para crear un carrito y agregar actividades, utiliza el endpoint /v2/cart con el método POST, proporcionando la información de la actividad seleccionada, incluyendo activityId, date, currency, rate, categories y time si aplica. La respuesta incluirá detalles del carrito y la actividad agregada.

  14. ¿Cómo obtengo y envío datos adicionales necesarios para la reserva?

    Respuesta: Después de crear el carrito, obtén los datos adicionales necesarios mediante el endpoint GET /cart/{cartId}/checkout. Allí recibirás preguntas adicionales y datos de pasajeros que debes completar. Envía las respuestas mediante el endpoint PUT /cart/{cartId}/checkout, asegurándote de proporcionar los IDs y valores requeridos.

  15. ¿Cómo confirmo una reserva?

    Respuesta: Para confirmar una reserva, necesitas obtener la wallet key mediante el endpoint de obtención del wallet. Luego, envía una solicitud a POST /cart/{cartId}/confirm para crear la reserva, incluyendo la wallet key y los datos necesarios. La respuesta confirmará la creación exitosa de la reserva y proporcionará detalles finales.

  16. ¿Cómo funcionan las actividades de tipo "freeTour"?

    Respuesta: Las actividades de tipo freeTour se confirman automáticamente después del proceso de checkout. No requieren el paso adicional de confirmación de la reserva. Puedes identificar estas actividades mediante el atributo isFreeTour en la información de la actividad.

  17. ¿Cómo reservo actividades para grupos de personas?

    Respuesta: Si una actividad tiene isCategoryPaxGroup en true, significa que es para grupos de personas. En este caso, debes utilizar el campo numberOfPersons al crear el carrito en el endpoint correspondiente, indicando el número exacto de personas dentro del rango mínimo y máximo especificado en la categoría seleccionada.

  18. ¿Cuál es la diferencia entre "quota" y "numberOfPersons"?

    Respuesta: quota es la disponibilidad real obtenida del Calendario V2 (cupos por horario y modalidad). numberOfPersons es el número exacto de personas que debes enviar al crear el carrito solo si la actividad es por grupos (isCategoryPaxGroup: true). Este valor debe estar dentro del rango mínimo y máximo de la categoría seleccionada.

  19. ¿Cómo obtengo disponibilidad en el entorno sandbox?

    Respuesta: Para obtener disponibilidad en el entorno sandbox, puedes utilizar el endpoint de disponibilidad infinita: /v2/activities/infinite-availability. Este endpoint está diseñado para pruebas en el entorno sandbox y proporciona actividades con disponibilidad garantizada.

  20. ¿Cuál es el flujo de trabajo para reservar traslados?

    Respuesta: El flujo general para reservar traslados es:

    • Buscar vehículos disponibles utilizando coordenadas de origen y destino.
    • Crear un carrito y agregar el traslado seleccionado.
    • Obtener los datos de la reserva, incluyendo preguntas adicionales si las hay.
    • Rellenar los datos adicionales de la reserva.
    • Obtener la wallet key para confirmar la reserva.
    • Confirmar la reserva utilizando la wallet key.
    • Para ida y vuelta, realiza el flujo dos veces (una por cada trayecto).
  21. ¿Cómo busco vehículos disponibles para traslados?

    Respuesta: Se recomienda buscar vehículos disponibles mediante el endpoint que acepta coordenadas de origen y destino: /v2/transfers/destinations/{destinationId}/vehicles. Los endpoints basados en zonas (/v2/transfers/{cityId}/zones/...) se mantienen solo por compatibilidad con integraciones existentes.

  22. ¿Cómo indico la hora de recogida en una reserva de traslado?

    Respuesta: Al crear el carrito para un traslado, debes indicar la hora en el atributo time. Es importante especificar la hora del vuelo o tren cuando el destino es de tipo Airport, Port o Train.

  23. ¿Cómo relleno los datos adicionales para una reserva de traslado?

    Respuesta: Al obtener los datos de la reserva mediante el endpoint de checkout, recibirás preguntas adicionales específicas para el traslado. Debes completar estas preguntas y enviar las respuestas mediante el endpoint correspondiente, asegurándote de proporcionar los IDs y valores requeridos. Cuando se solicite, el nombre del hotel debe enviarse como respuesta a la pregunta adicional correspondiente.

  24. ¿Cómo obtengo y utilizo la "wallet key" para confirmar una reserva?

    Respuesta: La wallet key se obtiene mediante el endpoint de obtención del wallet para obtener información del wallet asociado a tu agencia. Una vez obtenida, utilizas la wallet key en la solicitud de creación de la reserva, lo que permite identificar de manera segura la transacción.

  25. ¿Cómo puedo evitar errores de validación al enviar datos en la API?

    Respuesta:

    • Asegúrate de utilizar los formatos correctos para fechas, horas y otros tipos de datos.
    • Verifica que los IDs y valores enviados correspondan a los proporcionados por la API.
    • Consulta los detalles de cada endpoint para conocer los campos requeridos y sus formatos.
    • Maneja adecuadamente las respuestas de error de la API para corregir cualquier problema en los datos enviados.
  26. ¿Cómo puedo conocer el número máximo y mínimo de participantes permitidos en una actividad?

    Respuesta: Cada actividad puede tener restricciones específicas en cuanto al número mínimo y máximo de participantes. Estos parámetros determinan cómo y cuándo se puede realizar una reserva. Puedes consultar los siguientes campos en los detalles de la actividad realizando una petición al endpoint de la actividad. Por ejemplo:

    GET {{url}}/v2/activities/{activityId}

    • minimumPaxPerBooking (integer): Número mínimo de personas requerido para realizar una reserva. Este campo es bloqueante para la creación del carrito con la cantidad de participantes. Si intentas reservar con una cantidad inferior, el sistema no permitirá la creación del carrito.

    • minimumPaxPerActivity (integer): Cantidad mínima de personas necesarias para llevar a cabo la actividad. Este campo es informativo y te indica cuántas personas se requieren en total para que la actividad se realice, independientemente de tu reserva individual.

    • maximumPaxPerActivity (integer o null): Número máximo de personas permitidas para una reserva. Si es nulo, no hay límite establecido. Este campo es bloqueante para la creación del carrito con la cantidad de participantes. Si intentas reservar con una cantidad que excede este límite, la reserva será rechazada.

    Ejemplo de uso:

    Si una actividad tiene:

    • minimumPaxPerBooking = 2
    • minimumPaxPerActivity = 5
    • maximumPaxPerActivity = 10

    Significa que:

    • No puedes hacer una reserva para menos de 2 personas.
    • La actividad se realizará si hay al menos 5 participantes. (Este campo es informativo)
    • No puedes reservar para más de 10 personas en una sola reserva.

    Puedes encontrar más información sobre la estructura de la respuesta de este endpoint en la documentación.

  27. ¿Cómo puedo filtrar las actividades por categorías y subcategorías?

    Respuesta: Para filtrar las actividades por categorías y subcategorías, puedes utilizar los parámetros category y subCategory en los siguientes endpoints:

  • {{url}}/v2/destinations/{id}/activities

  • {{url}}/v2/zones/{zoneId}/activities

  • {{url}}/v2/findByCoord

  • {{url}}/v2/activities/infinite-availability

    Estos parámetros te permiten obtener actividades específicas dentro de una categoría o subcategoría determinada.

  1. ¿Qué tipos de datos pueden almacenarse en caché y por cuánto tiempo?

    Respuesta: Existen ciertos datos dentro de la API que pueden beneficiarse del almacenamiento en caché, permitiendo mejorar el rendimiento sin comprometer la precisión de la información. Entre estos datos se incluyen:

    • Detalles de actividades (nombre, descripción, imágenes, ubicación, políticas generales, etc).
    • Disponibilidad de actividades (fechas en las que una actividad está disponible).
    • Configuraciones generales (políticas de cancelación, requisitos especiales, restricciones).
    • Listado de destinos (ciudades o lugares donde se ofrecen actividades).
    • Categorías de actividades (tipos de experiencias disponibles).
    • Idiomas disponibles (en qué idiomas se puede realizar una actividad).
    • Monedas aceptadas (qué divisas están disponibles para el pago).

    Se recomienda que el almacenamiento en caché de estos datos tenga una duración máxima de 4 horas, dependiendo de la naturaleza de la información, siendo los detalles de las actividades y la disponibilidad los datos que suelen variar más. Esto permite optimizar el rendimiento sin riesgo de trabajar con datos obsoletos. En caso de cambios frecuentes en un tipo de dato específico, se sugiere considerar una menor duración en el caché y aplicar mecanismos de invalidación adecuados.

Servers
Production
https://api.civitatis.com/v2
Sandbox
https://sandbox-api.civitatis.com/v2
Sandbox
https://api-qa.civitatis.com/v2