Centro de ayuda›Desarrolladores›Operaciones de actividades

Operaciones de actividades

Lista, consulta, crea, edita y borra actividades por API v1 o MCP: tarifas, cupos, sesiones, personal y publicación.

Una actividad es el producto base de Buky: una clase, salida o experiencia reservable con fecha, hora, aforo y, opcionalmente, personal asignado. Es lo que tus clientes ven y reservan en el motor de reservas, y lo que tú organizas en sesiones desde el panel. Más sobre el concepto en Qué es una actividad en BukyApp.

Operaciones de esta página: list-activities, get-activity, create-activity, update-activity, delete-activity (solo lectura: list-activities, get-activity; escritura: create-activity, update-activity, delete-activity).

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.

list-activities: lista las actividades del centro

Devuelve el catálogo de actividades del centro. Es el paso previo natural para encontrar el identificador exacto de una actividad antes de editarla o borrarla, y admite tres niveles de detalle según lo que necesites ver. Es de solo lectura: vale con cualquier token.

Cómo llamarla

curl "https://api.bukyapp.com/v1/ops/list-activities?q=surf" \
  -H "Authorization: Bearer bk_TU_TOKEN"
curl -X POST https://api.bukyapp.com/v1/ops/list-activities \
  -H "Authorization: Bearer bk_TU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"q": "surf", "detail": "descriptive", "lang": "es"}'

Por MCP: «Enséñame las actividades que tengo» o «Busca las actividades que tengan "surf" en el nombre».

Parámetros

ParámetroTipoNivelQué hace
qtextoopcionalFiltra por título o nombre interno (contiene, sin tildes). Es la búsqueda del panel.
detailtexto (compact/descriptive)opcionalNivel de detalle de cada actividad. compact (por defecto): lo justo para identificar y enumerar. descriptive: textos en plano y categorías resueltas a su nombre, sin tarifas ni flags internos.
langtextoopcionalSolo con detail: "descriptive": cada texto vuelve en un único idioma (por ejemplo "es"; si falta, cae a español o al primero disponible). Sin lang, cada texto es un objeto {idioma: texto} con los idiomas rellenos.
fullbooleanoopcionaltrue devuelve el documento completo de cada actividad (tarifas, idiomas, personal…), más pesado. Gana a detail si mandas los dos.
privatebooleanoopcionaltrue solo actividades de sesiones privadas (no admiten más reservas tras la primera); false solo compartidas. Por defecto, todas.
disabledbooleanoopcionaltrue solo desactivadas, false solo activas. Por defecto, todas.
created_from, created_tofechaopcionalRango sobre la fecha de creación.
limitnúmeroopcionalMáximo de resultados, tras aplicar los filtros.

Qué devuelve

Vista compact (por defecto), ejemplo real recortado:

{
  "success": true,
  "detail": "compact",
  "count": 13,
  "total": 13,
  "items": [
    { "_id": "5b98cbdc749e2af7dda1da69", "title": "Actividad", "internalName": null, "categories": [], "is_disabled": false, "private": false, "pax_min": 1, "pax_max": null },
    { "_id": "69dba4e53f831f958dbdff7c", "title": "Surf Avanzado", "internalName": null, "categories": [], "is_disabled": false, "private": false, "pax_min": 1, "pax_max": null }
  ]
}

Vista descriptive con lang: "es", ejemplo real recortado:

{
  "success": true,
  "detail": "descriptive",
  "count": 13,
  "total": 13,
  "items": [
    {
      "_id": "5b98cbdc749e2af7dda1da69",
      "title": "Actividad",
      "internalName": null,
      "short_description": null,
      "description": "descripción de la actividad",
      "included": [], "not_included": [], "requirements": [],
      "alert_text": "La hora de la clase puede variar según las condiciones meteorológicas",
      "level": null,
      "meeting_point": null,
      "cancellation_policy_mode": "general",
      "cancellation_policy": null,
      "categories": [],
      "payment_mode": "none",
      "payment_advance_mode": "percent",
      "payment_advance_percent": 20,
      "payment_advance_fixed": 0,
      "need_pax_data": false,
      "is_disabled": false,
      "private": false,
      "by_request": false,
      "not_bookable_standalone": false,
      "pax_min": 1,
      "pax_max": null,
      "duration_min": 60
    }
  ]
}
CampoSignificado
detailLa vista que se aplicó: compact, descriptive o full.
countCuántas actividades se devuelven en items.
totalCuántas cumplen los filtros antes de aplicar limit. Si count es menor que total, limit recortó resultados.
items[]._idEl identificador que necesitas para get-activity, update-activity, etc.
items[].internalNameNombre interno del listado admin. Puede venir vacío: no se deriva del título.
items[].is_disabled, .privateEstado y privacidad, como los filtros del panel. Presentes en compact y descriptive.
items[].categoriesEn compact, identificadores; en descriptive, nombres ya resueltos.
items[].description, .alert_text (solo descriptive)Con lang, un texto plano en ese idioma; sin lang, un objeto {idioma: texto}.
items[].payment_mode, .need_pax_data, .by_request, .not_bookable_standalone (solo descriptive)Condiciones de pago y de reserva de la actividad.

Las actividades borradas no aparecen aquí.

Consejos

  • Con dos actividades con el mismo título (pasa: en la cuenta de ejemplo hay dos «surf de prueba c1»), pide full:true o cruza por internalName para no operar sobre la que no toca.
  • detail:"descriptive" es el punto intermedio entre compact y full: sirve para mostrarle el catálogo a un cliente o revisar textos, sin cargar tarifas ni flags internos.

get-activity: detalle completo de una actividad

Devuelve el documento completo y fresco de una actividad: tarifas, impuesto, capacidad, modo de reserva, personal, todo. Es la forma de comprobar cómo quedó una actividad tras crearla o editarla, y de conseguir su identificador exacto. Es de solo lectura: vale con cualquier token.

Cómo llamarla

curl "https://api.bukyapp.com/v1/ops/get-activity?activity=Surf%20Principiante%20en%20piscina" \
  -H "Authorization: Bearer bk_TU_TOKEN"
curl -X POST https://api.bukyapp.com/v1/ops/get-activity \
  -H "Authorization: Bearer bk_TU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"activity": "Surf Principiante en piscina"}'

Por MCP: «Enséñame el detalle de la actividad Surf Principiante en piscina».

Parámetros

ParámetroTipoNivelQué hace
activity (alias id, activity_id)textorecomendadoNombre, nombre interno o identificador de la actividad. Si el nombre no resuelve a una sola, la respuesta trae los candidatos.

Qué devuelve

Ejemplo real, recortado (esta actividad concreta hereda sus sesiones de otra, ver más abajo):

{
  "success": true,
  "_id": "6aa3db20f4b405ea4e3dfc20",
  "resolved": { "id": "6aa3db20f4b405ea4e3dfc20", "reason": "match exacto por nombre 'Surf Principiante en piscina'" },
  "item": {
    "_id": "6aa3db20f4b405ea4e3dfc20",
    "title": { "es": "Surf Principiante en piscina" },
    "activities_capacity": 6,
    "activities_duration": 60,
    "activities_bookingMode": "scheduled_in_other_activity",
    "activities_useSessionsFrom": "69dba4d4b227f96a4e3b21a8",
    "activities_private": false,
    "notBookableStandalone": false,
    "haveRatesByPersonRange": false,
    "priceFrom": 6000,
    "taxes": ["69a181ce5d6272575493bcfd"],
    "rates": [
      { "description": { "name": "Adulto" }, "price": 6000, "season": null, "_id": "6aa3dc3601ec3b760f91c62d" },
      { "description": { "name": "Temporada 2027" }, "price": 7500, "season": { "start": "2027-01-01", "end": "2027-06-21", "active": true }, "_id": "6aa3dc3697a76a5a4a6279a2" }
    ]
  }
}
CampoSignificado
_idIdentificador de la actividad resuelta.
resolvedQué actividad se eligió a partir de tu texto y por qué. Compruébalo cuando el nombre sea ambiguo.
item.activities_capacityPlazas por sesión.
item.activities_durationDuración por defecto, en minutos, de las sesiones nuevas.
item.activities_bookingModeCómo gestiona sus sesiones: scheduled (normal, tiene sesiones propias), scheduled_in_other_activity (no tiene sesiones propias: hereda las de la actividad de activities_useSessionsFrom, útil para vender el mismo horario con otro precio o nombre), TimePeriod, date_enquiry, no_date.
item.priceFromPrecio «desde» en céntimos, el que se muestra en el catálogo público.
item.rates[]Tarifas activas: nombre, precio en céntimos y, si aplica, temporada.
item.taxes[]Impuesto aplicado (identificador).

Errores propios

SituaciónRespuesta
Nombre que no coincide con ninguna actividad, o coincide con variassuccess: false, error: "activity_unresolved" y activity_candidates con las opciones. Repite con el nombre exacto o el _id.

create-activity: crea una actividad nueva

Crea una actividad con su modo de precio, personal y calendario. Es una operación de escritura: consulta siempre primero list-activities para no duplicar por error, y prueba en seco antes de confirmar.

Cómo llamarla

curl -X POST https://api.bukyapp.com/v1/ops/create-activity \
  -H "Authorization: Bearer bk_TU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Prueba documentación",
    "internal_name": "prueba-documentacion",
    "price_eur": 30,
    "color": "#1273de",
    "capacity": 6,
    "dry_run": true
  }'

Por MCP: «Crea una actividad llamada Prueba documentación a 30€, con 6 plazas y color azul».

Parámetros

Modo de precio: elige uno de estos tres (mandar más de uno da error):

ParámetroTipoNivelQué hace
price_eurnúmerorecomendadoModo plano: una sola tarifa base, en euros.
rate_rangesarrayrecomendadoModo por tamaño de grupo: [{from, to, price, name?}], una tarifa distinta según cuántas personas reserven. Es el patrón habitual en clases de surf.
ratesarrayrecomendadoModo tarifas avanzado: [{name, price_eur, season?, quantity?, pax?, color?}], para combinar temporadas, cantidades y rangos de personas en una sola tabla.
variationsarrayopcionalModo por tipo de persona (adulto/niño…): [{name, price}].
no_pricebooleanoopcionalActividad sin tarifa (bloqueo administrativo). Incompatible con cualquier otro parámetro de precio.
pricing_modetextoopcionalFuerza el modo (flat/group_range/person_type) si prefieres no dejarlo a la inferencia.

Datos básicos y sesiones:

ParámetroTipoNivelQué hace
titletextoobligatorioTítulo público.
internal_nametextorecomendadoNombre interno del listado admin. Si lo omites, queda vacío: no se deriva del título.
capacitynúmerorecomendadoPlazas por sesión. Por defecto, 6.
durationnúmerorecomendadoDuración por defecto de las sesiones, en minutos. Por defecto, 60.
colortextorecomendadoColor del calendario, en hex (#1273de). Si lo omites, se hereda el color por defecto de la paleta. Solo se aplica en modos con calendario propio.
taxtextorecomendadoImpuesto: "default", "21%", "IVA" o un identificador. Por defecto, el impuesto por defecto del centro.
descriptiontextoopcionalDescripción pública.
booking_modetextoopcionalPor defecto scheduled (la actividad gestiona sus propias sesiones). Con scheduled_in_other_activity la actividad no tiene sesiones propias y hereda las de otra (exige useSessionsFrom).
useSessionsFromtextoopcionalSolo con booking_mode: "scheduled_in_other_activity": la actividad de la que se heredan las sesiones.
price_from_eurnúmeroopcionalPrecio «desde» que se muestra en el catálogo. Si lo omites, se calcula solo a partir de las tarifas.
rate_nametextoopcionalNombre de la tarifa base en modo plano. Por defecto, «Adulto».

Personal y publicación (opcionales; se resumen porque son muchos):

ParámetroTipoNivelQué hace
staffarrayopcionalPersonal que puede servir la actividad (nombres o identificadores). Su sola presencia activa el control de personal.
staff_mode, staff_control_avail, staff_random_assign, staff_mintexto/booleano/númeroopcionalCómo se usa ese personal: solo listarlo (available, por defecto), exigir disponibilidad (strict, con staff_min de mínimo libre) o asignarlo al azar (random, exige strict activado).
privatebooleanoopcionalActividad privada. Por defecto, false.
not_bookable_standalonebooleanoopcionaltrue: la actividad solo se vende dentro de un pack, desaparece de las búsquedas y de la ficha pública.
categories, extrasarrayopcionalCategorías y extras asociados (nombres o identificadores).
ships, ships_excludedarrayopcionalSolo actividades de buceo/travesías: barcos admitidos o excluidos.
thumbtextoopcionalFoto destacada: identificador de un archivo ya subido (el que te da el chat al adjuntar una imagen) o una URL pública. Se aplica tras crear la actividad. Ver Operaciones de imágenes.
galleryarrayopcionalGalería: lista de imágenes, cada una identificador de un archivo ya subido o una URL pública.

Qué devuelve

Prueba en seco real:

{
  "success": true,
  "dry_run": true,
  "applied_defaults": { "activities_capacity": 6, "activities_bookingMode": "scheduled", "activities_color": "#1273de" },
  "resolved_tax": { "id": "69a181ce5d6272575493bcfd", "reason": "default (primer tax del customer)" },
  "resolved_pricing": { "mode": "flat", "base": { "name": "Adulto", "price_cents": 3000, "via": "priceFrom (sin rates, como el front)" } },
  "payload_preview": { "title": { "es": "Prueba documentación" }, "activities_capacity": 6, "internalName": "prueba-documentacion", "priceFrom": 3000, "activities_color": "#1273de" },
  "warnings": [
    "ACTIVIDAD AÚN NO VENDIBLE: se creó con priceFrom pero SIN tarifas. PASO 2 OBLIGATORIO: update-activity con rates:[{name,price_eur,quantity:1}]."
  ]
}
CampoSignificado
applied_defaultsLos valores que se aplicaron porque no los diste (capacidad, modo de reserva, color).
resolved_taxEl impuesto que se aplicó y por qué.
resolved_pricingEl modo de precio detectado y la tarifa resultante.
payload_previewLo que se enviaría al servidor si no fuera una prueba en seco.
warningsAvisos a leer siempre.

Consejos

  • En modo plano (`price_eur`), la actividad se crea sin tarifa todavía vendible: solo queda el precio «desde» (priceFrom), y la respuesta lo avisa con warnings. Para que sea reservable de verdad, sigue con update-activity mandando rates: [{"name": "Adulto", "price_eur": 30, "quantity": 1}]. Esto no lo dice el manual de forma explícita: se ha comprobado en la ejecución.
  • capacity, duration y color son la base de las sesiones que se generen para esta actividad; si trabajas con sesiones sueltas, revisa también Operaciones de sesiones.
  • Antes de crear, ejecuta list-activities con el nombre que vas a usar para comprobar que no exista ya.
  • Con thumb o gallery, una URL pública queda a la espera de subida: la prueba en seco lo muestra en images_pending (verificado en ejecución). Una ruta de archivo local ya no funciona: la operación no la reconoce ni como identificador ni como URL.

update-activity: edita una actividad existente

Cambia solo los campos que le pases: el resto de la actividad queda intacto. Es una operación de escritura.

Cómo llamarla

curl -X POST https://api.bukyapp.com/v1/ops/update-activity \
  -H "Authorization: Bearer bk_TU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "activity": "Prueba documentación",
    "title": "Prueba documentación editada",
    "price_eur": 32,
    "capacity": 8,
    "dry_run": true
  }'

Por MCP: «Cambia el título de Prueba documentación a "Prueba documentación editada" y súbele el precio a 32€».

Parámetros

ParámetroTipoNivelQué hace
activitytextoobligatorioActividad a editar: nombre, nombre interno o identificador.
titletextorecomendadoNuevo título público. No afecta a otros idiomas.
price_eurnúmerorecomendadoNuevo precio de la tarifa base (la primera). Conserva su identificador; reenvía el resto de tarifas tal cual.
capacitynúmerorecomendadoNuevas plazas por sesión.

El resto son opcionales (se agrupan por bloque porque son muchos; cada uno reemplaza el valor anterior salvo que se indique lo contrario):

BloqueParámetrosQué hacen
Datos básicosdescription, internal_name, duration, color, alert_text, tags, thumb, galleryDescripción, nombre interno, duración por defecto de sesión, color del calendario, aviso público y etiquetas. thumb (foto destacada) y gallery (galería) aceptan identificador de archivo ya subido o URL pública, igual que en create-activity; gallery sustituye la galería entera.
Tarifas e impuestosrate_name, rates, have_rates_by_person_range, tax, rates_by_full_grouprates reemplaza la tabla de tarifas entera (no se puede combinar con price_eur/rate_name); tax cambia el impuesto.
Cupos y condiciones de reservapax_min, pax_max, min_sessions, max_sessions, min_per_day, max_per_day, min_time_to_book, complete_sessions, need_pax_data, checkin_modePersonas y sesiones mínimas/máximas por reserva, antelación mínima y modo de check-in online.
Personalstaff, staff_mode, staff_control_avail, staff_random_assign, staff_minIgual que en create-activity; pasa staff: [] para vaciar el pool.
Visibilidad y publicaciónnot_bookable_standalone, hide_public_avail, show_location, show_origin_count, group_by_customer, staff_per_person, let_advanced_frontCómo se muestra la actividad y sus sesiones en el booker y en el panel.
Catálogocategories, extrasReemplazan el conjunto entero de categorías o extras asociados.

Qué devuelve

Prueba en seco real:

{
  "success": true,
  "dry_run": true,
  "_id": "6aa3db20f4b405ea4e3dfc20",
  "changes": {
    "title": { "es": "Prueba documentación editada" },
    "activities_capacity": 8,
    "rates": [
      { "description": { "name": "Adulto" }, "price": 3200, "season": null, "_id": "6aa3dc3601ec3b760f91c62d" },
      { "description": { "name": "Temporada 2027" }, "price": 7500, "season": { "start": "2027-01-01", "end": "2027-06-21" }, "_id": "6aa3dc3697a76a5a4a6279a2" }
    ]
  },
  "note": "PUT parcial: solo estos campos cambian."
}
CampoSignificado
changesExactamente lo que va a cambiar, ya resuelto (por ejemplo, price_eur se traduce a la tarifa base dentro de rates, conservando el resto de tarifas que ya tuviera).
noteRecuerda que es un cambio parcial: los campos que no mandaste no se tocan.

Consejos

  • Al cambiar price_eur, la respuesta reenvía la tabla de tarifas completa (rates) aunque solo hayas tocado la primera: es la actividad real, no un cálculo aparte. Compruébala si la actividad tiene tarifas por temporada.
  • Cambiar el title se propaga a las sesiones futuras de esa actividad.
  • Con thumb o gallery, la prueba en seco confirma la URL en images_check antes de aplicarla (verificado en ejecución); si mandas una ruta local en vez de un identificador o una URL, no la reconoce.

delete-activity: borra una actividad

La actividad deja de verse en el panel y en la tienda. No puedes deshacerlo desde la API ni desde el asistente, pero el soporte de Buky puede recuperarla si lo necesitas. Antes de borrar, avisa de las sesiones futuras y de si tienen reservas. Es una operación de escritura.

Cómo llamarla

curl -X POST https://api.bukyapp.com/v1/ops/delete-activity \
  -H "Authorization: Bearer bk_TU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"activity": "Prueba documentación", "confirm": true, "dry_run": true}'

Por MCP: «Borra la actividad Prueba documentación» (el asistente te pedirá confirmación antes de marcar confirm: true).

Parámetros

ParámetroTipoNivelQué hace
activitytextoobligatorioActividad a borrar: nombre, nombre interno o identificador.
confirmbooleanorecomendadoTiene que ser true para que la operación se ejecute de verdad; sin él, se queda en prueba en seco. Es una salvaguarda propia de esta operación, además de la del script de esta página.

Qué devuelve

Prueba en seco real, con confirm: true:

{
  "success": true,
  "dry_run": true,
  "would_delete": { "_id": "6a35694ba0cc4a3ec76347cd", "name": "surf de test 4" },
  "soft_deleted": false,
  "reversible": true,
  "dependencies": {
    "future_sessions": 0,
    "future_sessions_with_bookings": 0,
    "note": "El server NO borra estas sesiones ni bloquea: quedarán apuntando a la actividad borrada. Las reservas existentes siguen vivas (libéralas vía Order)."
  },
  "warnings": []
}
CampoSignificado
dependencies.future_sessionsCuántas sesiones futuras tiene la actividad.
dependencies.future_sessions_with_bookingsCuántas de esas sesiones tienen reservas. Si hay alguna, revísalo antes de confirmar: las reservas existentes no se cancelan ni se avisa al cliente, y las sesiones quedan apuntando a una actividad borrada.
reversibletrue: el soporte de Buky puede recuperarla si lo pides.

Errores propios

SituaciónRespuesta
Nombre que coincide con varias actividades (pasa con títulos duplicados, como «surf de prueba c1» en la cuenta de ejemplo)success: false, error: "activity_unresolved" y activity_candidates con las opciones para desambiguar por identificador.

Consejos

  • Si dependencies.future_sessions_with_bookings es mayor que 0, gestiona esas reservas antes de borrar: el borrado no las toca ni las libera.

¿Te ha resultado útil este artículo?