Centro de ayuda›Desarrolladores›Operaciones de disponibilidad, calendario y precios

Operaciones de disponibilidad, calendario y precios

Consulta días reservables, sesiones con plazas y precios de actividades, alojamientos, packs y alquileres por API v1 o MCP, con enlace de reserva.

Antes de que un cliente pague, tu motor de reservas responde tres preguntas seguidas: qué días puede venir, qué sesión concreta tiene plazas y cuánto le va a costar. Estas tres operaciones resuelven exactamente eso, en el mismo orden y con las mismas reglas que ve tu tienda pública: get-calendar da los días, get-avail da las sesiones y sus plazas reales, y get-quote da el precio y la disponibilidad de una selección concreta. Cómo se calcula el aforo de cada sesión (personal, vehículos, exclusiones) está explicado en Gestionar disponibilidad y aforo.

Operaciones de esta página: get-calendar, get-avail, get-quote (las tres de solo lectura).

Las bases comunes (autenticación, GET frente a POST, prueba en seco, errores HTTP, límites) están en API v1 — Introducción y primeros pasos.

get-calendar: días reservables de un producto

get-calendar responde a la pregunta «¿qué días puedo venir con N personas?» para una actividad, un alojamiento, un pack o un alquiler. Calcula lo mismo que el primer paso de tu motor de reservas, con las mismas reglas, y devuelve los días con plazas, los días cerrados con su motivo y el enlace al motor de reservas con la fecha y las personas ya rellenas. Es una operación de solo lectura: vale con cualquier token.

Cómo llamarla

Por API, con GET y los parámetros en la URL, o con POST y un cuerpo JSON:

curl "https://api.bukyapp.com/v1/ops/get-calendar?activity=Surf%20Principiante&from=2026-09-16&to=2026-10-15&pax=2" \
  -H "Authorization: Bearer bk_TU_TOKEN"
curl -X POST https://api.bukyapp.com/v1/ops/get-calendar \
  -H "Authorization: Bearer bk_TU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"activity": "Surf Principiante", "from": "2026-09-16", "to": "2026-10-15", "pax": 2}'

Por MCP, el asistente la ejecuta solo cuando le preguntas por fechas. Si quieres forzarla: «Ejecuta get-calendar para Surf Principiante entre el 16 de septiembre y el 15 de octubre con 2 personas».

El manual completo, siempre actualizado, está en GET https://api.bukyapp.com/v1/ops/get-calendar/manual.

Parámetros

ParámetroTipoNivelQué hace
fromfechaobligatorioInicio del rango, en formato ISO (2026-10-01).
tofechaobligatorioFin del rango. Como máximo 199 días después de from. El motor de reservas consulta dos meses.
producttextorecomendadoNombre, nombre interno o identificador del producto. Se busca en los cuatro catálogos a la vez; si no se resuelve a uno solo, la respuesta trae los candidatos para que elijas.
activity, accommodation, pack, rentaltextoopcionalAlternativa a product cuando ya sabes de qué tipo es. Solo busca en ese catálogo.
paxnúmerorecomendadoPersonas del grupo. Cambia qué días son reservables. Si lo omites, se usa el mínimo del producto (1 si no tiene).
per_personbooleanoopcionalSolo actividades. true si cada persona puede ir a una sesión distinta: entonces basta con un hueco libre por día. Por defecto false, el grupo va junto.
admin_viewbooleanoopcionaltrue para ver el calendario como lo ve el panel: sin el plazo mínimo de antelación y con las sesiones ocultas de la tienda. Por defecto false, la vista del cliente.
entryfechaopcionalSolo alojamientos. Día de entrada: la respuesta añade exits_for_entry, las salidas válidas para esa entrada.
optiontextoopcionalSolo packs. Opción o variación del pack (título, nombre o identificador). Por defecto, la primera.
only_staynúmeroopcionalSolo packs. Acompañantes que solo se alojan, sin actividades (de 0 a 6). Por defecto 0.

Qué devuelve

Ejemplo real, recortado, para una actividad con dos personas:

{
  "success": true,
  "operation": "get-calendar",
  "kind": "activity",
  "resolved_activity": {
    "id": "6aa3db20f4b405ea4e3dfc20",
    "title": "Surf Principiante en piscina",
    "reason": "match exacto por nombre 'Surf Principiante en piscina'"
  },
  "range": { "from": "2026-09-16", "to": "2026-10-15" },
  "timezone": "Europe/Madrid",
  "pax": { "requested": 2, "min": 1, "max_effective": 10, "mode": "group" },
  "count_entry_days": 10,
  "entry_days": ["2026-09-17", "2026-09-18", "2026-09-21", "2026-09-22", "..."],
  "days": [
    { "day": "2026-09-16", "sessions": 1, "plazas": 0, "unlimited": false, "fits_group": false },
    { "day": "2026-09-17", "sessions": 2, "plazas": 8, "unlimited": false, "fits_group": true }
  ],
  "closed_days": [
    { "day": "2026-09-16", "reason": "no_quota" },
    { "day": "2026-09-19", "reason": "no_session" }
  ],
  "booker_url": "https://app.bukyapp.com/front/<cuenta>/product/6aa3db20f4b405ea4e3dfc20",
  "booker_prefill_url": "https://app.bukyapp.com/front/<cuenta>/product/6aa3db20f4b405ea4e3dfc20?default=...",
  "warnings": []
}
CampoSignificado
resolved_activity (o resolved_accommodation, etc.)Qué producto se eligió a partir del nombre que diste y por qué. Compruébalo cuando el nombre sea ambiguo.
paxPersonas pedidas, mínimo del producto, máximo efectivo en ese rango y modo (group o per_person).
entry_daysLos días en los que el grupo puede venir, en la zona horaria del centro. Es la respuesta corta.
daysTodos los días con alguna sesión visible: cuántas sesiones hay, cuántas plazas quedan y si cabe el grupo. Sirve para explicar «hay sesión pero no cabéis».
closed_daysDías sin opción y el motivo: no_session (no hay sesión), no_quota (hay sesión pero sin plazas para el grupo) y, en alojamientos, past, occupied o day_enter.
booker_urlEnlace a la ficha del producto en tu motor de reservas.
booker_prefill_urlEl mismo enlace con la primera fecha disponible y el número de personas ya rellenos. Es el que conviene dar al cliente.
no_date_requiredSolo packs sin fecha (de tipo voucher o regalo): true. No hay días que consultar y la respuesta no trae booker_prefill_url; el pack se compra desde booker_url.
exits_for_entrySolo alojamientos con entry: salidas válidas para esa entrada, respetando estancia mínima y máxima y días de salida permitidos.
activity_candidates (o accommodation_candidates, etc.)Solo si el nombre no se resolvió a un único producto: lista de coincidencias con identificador, tipo y título. La operación no ejecuta hasta que concretes.

Cómo se calcula

  • Actividades. Un día es reservable si tiene al menos una sesión visible cuyo cupo real admite al grupo entero. En modo por persona basta con un hueco. El máximo de personas es el menor entre el máximo de la actividad y el mayor cupo del rango.
  • Alojamientos. Un día es entrada válida si no es pasado, si esa noche quedan unidades libres suficientes (en alojamientos compartidos, una cama por persona) y si el alojamiento admite entradas ese día de la semana. Con entry obtienes además las salidas válidas.
  • Packs y alquileres. Mismo principio aplicado a la opción del pack o al material, con las restricciones propias de cada uno.
  • Packs sin fecha (voucher o regalo). No tienen días que elegir: la respuesta llega con no_date_required: true, sin días que consultar y sin booker_prefill_url. El cliente lo compra directamente desde booker_url.

Los datos vienen de la misma consulta que usa tu motor de reservas, con una caché de un minuto: lo que devuelve esta operación es lo que vería un cliente en ese momento.

Ejemplos

¿Qué días puede venir un grupo de 4 en octubre?

{ "activity": "Clase Surf", "from": "2026-10-01", "to": "2026-11-01", "pax": 4 }

Vista del panel, sin plazo de antelación

{ "activity": "Clase Surf", "from": "2026-09-04", "to": "2026-09-11", "pax": 2, "admin_view": true }

Alojamiento: salidas válidas entrando el día 10

{ "accommodation": "Habitación doble", "from": "2026-10-01", "to": "2026-11-01", "pax": 2, "entry": "2026-10-10" }

Pack: ¿qué días puede empezar un grupo de 3 con la opción de 5 noches?

{ "pack": "Surf Camp", "option": "5 noches", "from": "2026-10-01", "to": "2026-11-01", "pax": 3 }

Errores propios de esta operación

SituaciónRespuesta
Falta from o to400 con error: "invalid_params" y el campo que falta en details.
Rango de más de 199 días200 con success: false y error: "range_too_wide". Acota el rango o trocéalo.
Nombre que no coincide con ningún producto200 con success: false, error: "activity_unresolved" (o product_unresolved, accommodation_unresolved, etc.) y la lista activity_candidates con los productos disponibles de ese tipo.
Nombre que coincide con variosMisma respuesta, con los candidatos en activity_candidates. Repite la llamada con el nombre exacto o el identificador.

Consejos

  • Pasa siempre pax: sin él se usa el mínimo del producto y los días reservables pueden ser más de los que caben a tu grupo.
  • Para el cliente final, entrega booker_prefill_url: llega al motor de reservas con fecha y personas puestas. En un pack sin fecha no existe: entrega booker_url.
  • Cuando expliques un «no», mira closed_days: la diferencia entre «no hay sesión» y «no quedan plazas» cambia la respuesta que darás.

get-avail: plazas reales por sesión de una actividad

get-avail responde a «¿hay plazas, y para cuántos?» sesión por sesión, no día por día: es el mismo cálculo que hace tu motor de reservas al pintar el calendario, con el cupo real de cada sesión (personal necesario, vehículos o embarcaciones asociadas, plazo mínimo de antelación...). Es una operación de solo lectura: vale con cualquier token.

Cómo llamarla

curl "https://api.bukyapp.com/v1/ops/get-avail?activity=Surf%20Principiante%20en%20piscina&from=2026-09-16&to=2026-10-15&pax=2" \
  -H "Authorization: Bearer bk_TU_TOKEN"
curl -X POST https://api.bukyapp.com/v1/ops/get-avail \
  -H "Authorization: Bearer bk_TU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"activity": "Surf Principiante en piscina", "from": "2026-09-16", "to": "2026-10-15", "pax": 2}'

Por MCP: «¿Qué sesiones de Surf Principiante en piscina tienen hueco para 2 entre el 16 de septiembre y el 15 de octubre?».

Parámetros

ParámetroTipoNivelQué hace
activitytextoobligatorioNombre, nombre interno o identificador de la actividad. Si no se resuelve a una sola, la respuesta trae los candidatos.
fromfechaobligatorioInicio del rango. Se devuelven las sesiones que solapan [from, to).
tofechaobligatorioFin del rango. Como máximo 199 días después de from.
paxnúmeroopcionalTamaño del grupo. No cambia el cálculo: solo marca fits_group en cada sesión.
strictbooleanoopcionalPor defecto true, la vista del cliente (con el plazo de antelación aplicado). false es la vista del panel, sin ese plazo.

Qué devuelve

Ejemplo real, recortado, para el mismo rango de un mes:

{
  "success": true,
  "operation": "get-avail",
  "activity_id": "6aa3db20f4b405ea4e3dfc20",
  "resolved_activity": {
    "id": "6aa3db20f4b405ea4e3dfc20",
    "reason": "match exacto por nombre 'Surf Principiante en piscina'"
  },
  "range": { "from": "2026-09-16T00:00:00.000Z", "to": "2026-10-15T00:00:00.000Z" },
  "timezone": "Europe/Madrid",
  "strict": true,
  "pax": 2,
  "count": 11,
  "available_sessions": 10,
  "sessions_fitting_group": 10,
  "sessions": [
    { "session_id": "69dbaf7eb227f96a4e3ba8c6", "start": "2026-09-16T07:00:00.000Z", "end": "2026-09-16T09:00:00.000Z", "capacity": 10, "quota": { "total": 0, "active": 0 }, "unlimited": false, "available": false, "fits_group": false },
    { "session_id": "69dbaf7eb227f96a4e3ba8c7", "start": "2026-09-17T07:00:00.000Z", "end": "2026-09-17T09:00:00.000Z", "capacity": 10, "quota": { "total": 10, "active": 0 }, "unlimited": false, "available": true, "fits_group": true },
    "..."
  ],
  "booker_url": "https://app.bukyapp.com/front/<cuenta>/product/6aa3db20f4b405ea4e3dfc20",
  "booker_prefill_url": "https://app.bukyapp.com/front/<cuenta>/product/6aa3db20f4b405ea4e3dfc20?default=...",
  "warnings": []
}
CampoSignificado
resolved_activityQué actividad se eligió a partir del nombre que diste y por qué.
range, timezoneEl rango consultado y la zona horaria del centro.
stricttrue si es la vista del cliente (con plazo de antelación), false si es la vista del panel.
countSesiones devueltas en el rango.
available_sessionsCuántas de esas sesiones tienen al menos una plaza libre.
sessions_fitting_groupCuántas caben para el pax que pediste.
sessionsUna entrada por sesión: horario, capacity, quota (cupo total y activo), unlimited (sin control de aforo) y fits_group.
booker_url / booker_prefill_urlFicha del producto y la misma con fecha y personas ya puestas.

Errores propios de esta operación

SituaciónRespuesta
Nombre de actividad que no coincide con ningunasuccess: false, error: "activity_unresolved" y activity_candidates con las actividades del catálogo.
Rango de más de 199 díassuccess: false, error: "range_too_wide" con el número de días pedidos. Acorta el rango o trocéalo.

Consejos

  • Es la fuente real de plazas por sesión: úsala para «¿hay hueco?». Para «¿qué días puedo venir?» agregado por día, usa get-calendar; la agenda de list-sessions (capacidad − reservas) es solo una aproximación.
  • Pasa pax para saber cuántas sesiones caben al grupo entero, no solo cuáles tienen alguna plaza.
  • Usa strict:false cuando necesites ver el calendario como lo ve el panel, sin el plazo de antelación.

get-quote: precio y disponibilidad de una selección concreta

get-quote da el precio real y la disponibilidad de una selección ya concreta: fechas y personas en un alojamiento, o fechas, opción y unidades en un alquiler. Es el mismo cálculo que el paso 2 de tu motor de reservas. Para actividades y packs, por ahora solo da el precio «desde» del catálogo. Es una operación de solo lectura: vale con cualquier token.

Cómo llamarla

curl "https://api.bukyapp.com/v1/ops/get-quote?accommodation=bungalow%201&start=2026-10-10&end=2026-10-13&pax=2" \
  -H "Authorization: Bearer bk_TU_TOKEN"
curl -X POST https://api.bukyapp.com/v1/ops/get-quote \
  -H "Authorization: Bearer bk_TU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"accommodation": "bungalow 1", "start": "2026-10-10", "end": "2026-10-13", "pax": 2}'

Por MCP: «¿Cuánto cuesta el bungalow 1 del 10 al 13 de octubre para 2 personas?».

Parámetros

ParámetroTipoNivelQué hace
producttextorecomendadoAlojamiento, alquiler, actividad o pack: nombre, nombre interno o identificador. Se busca en los catálogos; si casa en varios, trae candidatos con su tipo.
accommodation, rental, activity, packtextoopcionalAlternativa a product cuando ya sabes de qué tipo es. En actividades y packs, hoy solo da price_from_cents.
startfecharecomendadoAlojamiento: día de entrada (YYYY-MM-DD). Alquiler: recogida (YYYY-MM-DDTHH:mm).
endfecharecomendadoAlojamiento: día de salida. Alquiler: devolución.
paxnúmerorecomendadoAlojamiento: huéspedes. Alquiler: personas por unidad.
optiontextoopcionalSolo alquileres: variación u opción (nombre o identificador). Por defecto, la primera.
quantitynúmeroopcionalSolo alquileres: unidades de la opción. Por defecto 1.
sizetextoopcionalSolo alquileres: talla, si la opción tiene material por tallas.
langtextoopcionalIdioma de los mensajes de conditions. Por defecto español.

Qué devuelve

Ejemplo real, recortado, para un alojamiento con 1 persona 3 noches:

{
  "success": true,
  "operation": "get-quote",
  "kind": "accommodation",
  "product_id": "6a37ee3830e0c1f575f79611",
  "resolved": {
    "id": "6a37ee3830e0c1f575f79611",
    "reason": "match exacto por nombre 'bungalow 1'",
    "title": "bungalow 1",
    "type": "BasicAccommodation"
  },
  "price_from_cents": 5000,
  "taxes": [ { "name": "IVA", "percent": 21, "inclusive": true, "compound": false } ],
  "selection": { "start": "2026-10-10", "end": "2026-10-13", "nights": 3, "pax": 1 },
  "conditions": { "ok": true, "errors": [] },
  "available": true,
  "price_cents": 15000,
  "price_with_taxes_cents": 15000,
  "booker_url": "https://app.bukyapp.com/front/<cuenta>/product/6a37ee3830e0c1f575f79611",
  "booker_prefill_url": "https://app.bukyapp.com/front/<cuenta>/product/6a37ee3830e0c1f575f79611?default=...",
  "warnings": []
}

Para una actividad, la respuesta se reduce a lo que hay en el catálogo:

{ "success": true, "kind": "activity", "price_from_cents": 6000, "taxes": [ { "name": "IVA", "percent": 21, "inclusive": true } ], "quote": null }
CampoSignificado
kindTipo de producto resuelto: accommodation, rental, activity o pack.
resolvedQué producto se eligió a partir del nombre que diste y por qué.
price_from_centsEl «desde» del catálogo, en céntimos: el mínimo de tarifas vigentes, sin clases extra ni extra-pax.
taxesImpuestos del producto: nombre, porcentaje y si van incluidos en el precio o se suman aparte.
selectionLa selección concreta pedida: fechas, noches (alojamiento) y personas.
conditionsSi la selección cumple las reglas del producto (capacidad, mínimo o máximo de noches o de personas por unidad...). ok:false trae los mensajes en errors.
availableSi quedan unidades libres para todas las noches (alojamiento) o para el rango pedido (alquiler).
price_cents / price_with_taxes_centsPrecio de la selección: el que calcula el servidor y el que se pinta en el total de la tienda con impuestos aplicados.
booker_url / booker_prefill_urlFicha del producto y la misma con fecha, personas y opción ya puestas.

Errores propios de esta operación

SituaciónRespuesta
Nombre que no coincide con ningún alojamiento o alquilersuccess: false, error: "accommodation_unresolved" (o rental_unresolved) con candidates, la lista de productos de ese tipo.
La cuenta no tiene ningún alquiler configuradosuccess: false, error: "rental_unresolved" con candidates: [] y el detalle «el customer no tiene ninguna entidad de este tipo configurada».

Consejos

  • conditions y available van por separado: en una prueba real, un bungalow con capacidad para 1 devolvió available: true y un precio calculado incluso pidiendo 2 personas, pero conditions.ok: false con el mensaje «Capacidad máxima: 1». Revisa siempre conditions.errors antes de dar un precio por bueno a tu cliente.
  • Para actividades y packs no compares precios exactos: price_from_cents es el «desde» del catálogo, no el de una selección concreta.
  • Entrega booker_prefill_url al cliente: llega al motor de reservas con la selección ya puesta.

¿Te ha resultado útil este artículo?