Operaciones de cupones
Consulta, crea, edita y borra cupones de descuento por API v1 o MCP.
Un cupón es un código promocional que tus clientes canjean en el motor de reservas para conseguir un descuento, en porcentaje o en importe fijo, sobre uno o varios productos. Puedes crearlos, consultarlos, editarlos o borrarlos desde el panel o pidiéndoselo a tu asistente de IA. Más sobre cómo configurarlos desde el panel en Configurar cupones y descuentos.
Operaciones de esta página: list-coupons, get-coupon, create-coupon, update-coupon, delete-coupon (solo lectura: list-coupons, get-coupon; escritura: create-coupon, update-coupon, delete-coupon).
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-coupons: lista los cupones de la cuenta
Devuelve los cupones de tu cuenta con su código, descuento, vigencia y usos, sin tener que adivinar un código para consultarlo uno a uno. Es una operación de solo lectura: vale con cualquier token.
Cómo llamarla
curl "https://api.bukyapp.com/v1/ops/list-coupons?detail=descriptive&lang=es" \
-H "Authorization: Bearer bk_TU_TOKEN"Por MCP: «¿Qué cupones tengo configurados?» o «Enséñame los cupones con código VERANO».
Parámetros
| Parámetro | Tipo | Nivel | Qué hace |
|---|---|---|---|
q | texto | opcional | Busca por texto en el código o el título (sin tildes, sin distinguir mayúsculas). Es el mismo filtro que el buscador del panel. |
created_from, created_to | fecha | opcional | Filtra por la fecha de creación del cupón (rango en ISO). |
detail | texto | opcional | compact (por defecto): lo justo para identificar cada cupón. descriptive: añade a qué productos aplica, si es acumulable, si excluye los extras y la ventana de disfrute. |
lang | texto | opcional | Solo con detail: "descriptive": cada texto vuelve en el idioma que pidas (por defecto español). |
full | booleano | opcional | Devuelve el documento completo de cada cupón tal cual está en el servidor. Pesado: solo si de verdad lo necesitas. |
limit | número | opcional | Limita cuántos cupones te devuelve, tras aplicar los filtros. |
Qué devuelve
La cuenta demo usada para esta página no tiene ningún cupón creado, así que esta es la respuesta real con la lista vacía:
{
"success": true,
"detail": "compact",
"count": 0,
"total": 0,
"items": []
}Con cupones creados, cada elemento de items trae en vista compacta: _id, code, title, discount_type (percentage o fixed), discount_value, valid_from, valid_until, uses y limit. Con detail: "descriptive" se añade a qué productos aplica, si es acumulable (can_be_added), si excluye los extras y la ventana de disfrute.
| Campo | Significado |
|---|---|
count | Cupones devueltos en items, después de aplicar limit. |
total | Cupones que cumplen el filtro, antes de recortar con limit. Si count es menor que total, hay más de los que ves. |
items | La lista de cupones, en el nivel de detalle que hayas pedido. |
Consejos
- Es la forma correcta de ver qué cupones existen: no hace falta provocar un error en
get-couponcon un código inventado para descubrirlo. - Los cupones borrados nunca aparecen aquí, aunque tengas el código a mano.
get-coupon: consulta un cupón por código
Busca un cupón por su código o su identificador y devuelve el documento completo y actualizado, tal y como está en ese momento en el servidor. Es una operación de solo lectura: vale con cualquier token.
Cómo llamarla
curl "https://api.bukyapp.com/v1/ops/get-coupon?coupon=VERANO15" \
-H "Authorization: Bearer bk_TU_TOKEN"curl -X POST https://api.bukyapp.com/v1/ops/get-coupon \
-H "Authorization: Bearer bk_TU_TOKEN" \
-H "Content-Type: application/json" \
-d '{"coupon": "VERANO15"}'Por MCP: «Enséñame el cupón VERANO15» o «¿Qué descuento tiene configurado el código VERANO15?».
Parámetros
| Parámetro | Tipo | Nivel | Qué hace |
|---|---|---|---|
coupon | texto | obligatorio | Código o identificador del cupón. El manual lo marca como recomendado, pero sin él la operación falla siempre: es obligatorio en la práctica. |
id, coupon_id | texto | opcional | Alias de coupon. |
Qué devuelve
La cuenta demo usada para esta página no tiene ningún cupón creado, así que no hay un código real con el que mostrar una respuesta de éxito. Esta es la respuesta real al pedir un código inventado:
{
"success": false,
"error": "coupon_unresolved",
"details": "el customer no tiene ninguna entidad de este tipo configurada",
"candidates": [],
"hint": "El customer no tiene ningún cupón configurado todavía."
}Cuando el código sí existe, la respuesta trae _id (el identificador del cupón), resolved (qué código diste y por qué se resolvió a ese cupón, con id y reason) e item, el documento completo: código, título, tipo de descuento y su valor, ventana de validez, límite y usos restantes, productos a los que aplica, si es acumulable con otros cupones y su ventana de disfrute, si la tiene.
Errores propios de esta operación
| Situación | Respuesta |
|---|---|
Falta coupon | 200 con success: false y error: "coupon_intent_required". |
| Código que no coincide con ningún cupón | 200 con success: false, error: "coupon_unresolved" y la lista candidates con los cupones existentes más parecidos (vacía si la cuenta no tiene ninguno). |
Consejos
- Úsala después de
create-couponoupdate-couponpara confirmar cómo quedó el cupón: la prueba en seco de esas dos no escribe nada,get-couponsí te da el estado real cuando lo hayas creado desde el panel.
create-coupon: crea un cupón de descuento
Crea un cupón nuevo replicando el formulario del panel: código, título, tipo y valor del descuento, y a qué productos aplica. Es una operación de escritura; por esta vía siempre se ejecuta en modo prueba, dry_run: true, así que nunca llega a crear el cupón de verdad.
Cómo llamarla
curl -X POST https://api.bukyapp.com/v1/ops/create-coupon \
-H "Authorization: Bearer bk_TU_TOKEN" \
-H "Content-Type: application/json" \
-d '{"code": "DOCU10", "title": "Cupón de prueba docu", "discount_value": 10, "dry_run": true}'Por MCP: «Crea un cupón DOCU10 del 10% para todo el catálogo».
Parámetros
| Parámetro | Tipo | Nivel | Qué hace |
|---|---|---|---|
code | texto | obligatorio | Código del cupón, único por cuenta. Por ejemplo VERANO15. |
title | texto | obligatorio | Título del cupón. |
discount_value | número | obligatorio | Magnitud del descuento: con discount_type: "percentage" es un porcentaje (se limita a 100); con "fixed" es un importe en euros. |
discount_type | texto | recomendado | "percentage" (por defecto) o "fixed". Admite sinónimos como «porcentaje» o «importe fijo». |
valid_products_mode | texto | recomendado | "always" (por defecto, aplica a todo el catálogo) o "someProducts" (solo a los productos de valid_products). |
valid_products | lista | opcional | Nombres o identificadores de los productos a los que aplica. Obligatorio si valid_products_mode es "someProducts". Se resuelven contra tu catálogo real. |
exclude_extras | booleano | opcional | Solo con "percentage": si es true, el descuento no toca los extras, solo la base del producto. Por defecto false. |
valid_from, valid_until | fecha | opcional | Ventana de validez del cupón. |
limit_uses | número | opcional | Si lo indicas, limita los usos totales del cupón a ese número. |
Qué devuelve
Prueba en seco con los datos mínimos (código, título y un 10%):
{
"dry_run": true,
"success": true,
"applied_defaults": {
"discount_type": "percentage",
"valid_products_mode": "always",
"limited": false,
"exclude_extras": false
},
"resolved_discount": { "type": "percentage", "value": 10, "reason": "default (percentage)" },
"resolved_products": [],
"payload_preview": {
"code": "DOCU10",
"title": { "es": "Cupón de prueba docu" },
"discountType": "percentage",
"discountPercentage": 10,
"valid_products_mode": "always",
"customer": "5a55fff67e9fe0036a541d15"
},
"warnings": []
}| Campo | Significado |
|---|---|
applied_defaults | Qué valores por defecto se rellenaron porque no los pasaste. |
resolved_discount | Tipo y valor del descuento ya validados, con el motivo. |
resolved_products | Los productos de valid_products ya resueltos a un identificador concreto, con el motivo del match. Vacío si el modo es always. |
payload_preview | Lo que se enviaría a crear el cupón: código, título, tipo y valor del descuento en los campos internos, y las fechas o el límite de usos si los diste. |
La prueba en seco no crea nada, así que no incluye el identificador. En la creación real, la respuesta también trae _id, el identificador del cupón creado.
Ejemplos
Importe fijo con límite de usos y fechas
{ "code": "DOCU10FIJO", "title": "10€ de descuento docu", "discount_type": "fixed", "discount_value": 10, "limit_uses": 50, "valid_from": "2026-09-15", "valid_until": "2026-10-15" }Porcentaje solo para un producto
{ "code": "DOCUSURF", "title": "Surf -20% docu", "discount_value": 20, "valid_products_mode": "someProducts", "valid_products": ["Surf Principiante en piscina"] }En este caso resolved_products devolvió [{ "id": "6aa3db20f4b405ea4e3dfc20", "reason": "match por nombre 'Surf Principiante en piscina' (activity)" }].
Errores propios de esta operación
| Situación | Respuesta |
|---|---|
Falta code, title o discount_value | 400 con error: "invalid_params" y el campo que falta en details. |
valid_products_mode: "someProducts" sin valid_products | 200 con success: false y error: "valid_products_required". |
Consejos
- Si un producto de
valid_productsno encuentra coincidencia, la operación no inventa un identificador: falla y te devuelve candidatos para que elijas el correcto.
update-coupon: edita un cupón existente
Edita un cupón con un PUT parcial: solo cambia los campos que le pasas, el resto queda igual. Es una operación de escritura; por esta vía siempre se ejecuta en modo prueba, así que nunca llega a modificar el cupón de verdad.
Cómo llamarla
curl -X POST https://api.bukyapp.com/v1/ops/update-coupon \
-H "Authorization: Bearer bk_TU_TOKEN" \
-H "Content-Type: application/json" \
-d '{"coupon": "VERANO15", "discount_value": 20, "dry_run": true}'Por MCP: «Sube el descuento del cupón VERANO15 al 20%».
Parámetros
| Parámetro | Tipo | Nivel | Qué hace |
|---|---|---|---|
coupon | texto | obligatorio | Código o identificador del cupón a editar. |
title | texto | recomendado | Nuevo título. Solo cambia el español, no toca otros idiomas. |
discount_value | número | recomendado | Nueva magnitud del descuento. Se interpreta como porcentaje o euros según el discount_type que pases, o el que ya tenga el cupón si no lo pasas. |
discount_type | texto | opcional | Nuevo tipo: "percentage" o "fixed". |
valid_from, valid_until | fecha | opcional | Nueva ventana de validez. |
limit_uses | número | opcional | Usos restantes. Ojo: es un contador que decrementa con cada canje, no un tope acumulativo; fijarlo aquí sobrescribe el conteo actual. |
code | texto | opcional | Nuevo código público. Se normaliza a mayúsculas sin acentos ni símbolos, igual que el panel. Cambia el código que usan tus clientes. |
valid_products_mode | texto | opcional | "always" o "someProducts". Si pasas valid_products, se asume "someProducts". |
valid_products | lista | opcional | Nueva lista de productos a los que aplica. Reemplaza el conjunto entero, no lo amplía. |
exclude_extras | booleano | opcional | Excluir los extras del descuento (solo con "percentage"). |
can_be_added | booleano | opcional | Si el cupón se puede acumular con otros. |
enjoy_from, enjoy_until | fecha | opcional | Ventana en la que se puede canjear el cupón, distinta de la ventana de validez. |
Qué devuelve
La cuenta demo no tiene cupones creados, así que no hay un código real con el que probar una edición. Esta es la respuesta real de la prueba en seco al pedir un código que no existe:
{
"dry_run": true,
"success": false,
"error": "coupon_unresolved",
"details": "el customer no tiene cupones creados",
"candidates": [],
"hint": "Especifica el cupon (code o _id) entre candidates."
}Cuando el cupón sí existe, la prueba en seco devuelve _id (el identificador del cupón editado) y changes: un resumen de qué campos cambiarían y con qué valor, sin llegar a guardarlos.
Errores propios de esta operación
| Situación | Respuesta |
|---|---|
| Código o identificador que no resuelve a ningún cupón | 200 con success: false, error: "coupon_unresolved" y candidates con los cupones existentes que más se parecen. |
Consejos
- El manual describe
valid_productsa la vez como un campo editable que reemplaza la lista entera y, en otro punto, como «no editable aquí»; esta página documenta el comportamiento del parámetro tal y como lo describe su ficha, pero conviene confirmarlo con unget-coupondespués de editar en el panel si tienes dudas.
delete-coupon: borra un cupón de forma irreversible
Borra un cupón físicamente de la base de datos: se borra definitivamente y no se puede recuperar. Es una operación de escritura; por esta vía siempre se ejecuta en modo prueba, así que nunca llega a borrar nada de verdad.
Cómo llamarla
curl -X POST https://api.bukyapp.com/v1/ops/delete-coupon \
-H "Authorization: Bearer bk_TU_TOKEN" \
-H "Content-Type: application/json" \
-d '{"coupon": "VERANO20", "confirm": true, "dry_run": true}'Por MCP: «Borra el cupón VERANO20» (el asistente te pedirá confirmar antes de tocar nada).
Parámetros
| Parámetro | Tipo | Nivel | Qué hace |
|---|---|---|---|
coupon | texto | obligatorio | Código o identificador del cupón a borrar. |
confirm | booleano | recomendado | Tiene que ser true para borrar de verdad. Sin él, la operación se queda en modo prueba aunque no estés usando este script. |
Qué devuelve
La cuenta demo no tiene cupones creados, así que no hay un código real con el que probar el borrado. Esta es la respuesta real al pedir un código que no existe:
{
"dry_run": true,
"success": false,
"error": "coupon_unresolved",
"details": "el customer no tiene cupones creados",
"candidates": [],
"hint": "Especifica el cupón (code o _id) entre candidates."
}Cuando el cupón sí existe, la prueba en seco confirma _id (el identificador del cupón que se borraría) y que es irreversible (reversible: false), sin llegar a borrarlo.
Errores propios de esta operación
| Situación | Respuesta |
|---|---|
| Código o identificador que no resuelve a ningún cupón | 200 con success: false, error: "coupon_unresolved" y candidates con los cupones existentes que más se parecen. |
Consejos
- El borrado es físico y no se puede deshacer: el código queda libre para reutilizarse y no hay forma de recuperar la configuración del cupón. Haz siempre una prueba en seco (
confirmsintrue) antes de confirmar de verdad.
