Centro de ayuda›Desarrolladores›Operaciones de cupones

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ámetroTipoNivelQué hace
qtextoopcionalBusca 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_tofechaopcionalFiltra por la fecha de creación del cupón (rango en ISO).
detailtextoopcionalcompact (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.
langtextoopcionalSolo con detail: "descriptive": cada texto vuelve en el idioma que pidas (por defecto español).
fullbooleanoopcionalDevuelve el documento completo de cada cupón tal cual está en el servidor. Pesado: solo si de verdad lo necesitas.
limitnúmeroopcionalLimita 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.

CampoSignificado
countCupones devueltos en items, después de aplicar limit.
totalCupones que cumplen el filtro, antes de recortar con limit. Si count es menor que total, hay más de los que ves.
itemsLa 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-coupon con 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ámetroTipoNivelQué hace
coupontextoobligatorioCó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_idtextoopcionalAlias 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ónRespuesta
Falta coupon200 con success: false y error: "coupon_intent_required".
Código que no coincide con ningún cupón200 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-coupon o update-coupon para confirmar cómo quedó el cupón: la prueba en seco de esas dos no escribe nada, get-coupon sí 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ámetroTipoNivelQué hace
codetextoobligatorioCódigo del cupón, único por cuenta. Por ejemplo VERANO15.
titletextoobligatorioTítulo del cupón.
discount_valuenúmeroobligatorioMagnitud del descuento: con discount_type: "percentage" es un porcentaje (se limita a 100); con "fixed" es un importe en euros.
discount_typetextorecomendado"percentage" (por defecto) o "fixed". Admite sinónimos como «porcentaje» o «importe fijo».
valid_products_modetextorecomendado"always" (por defecto, aplica a todo el catálogo) o "someProducts" (solo a los productos de valid_products).
valid_productslistaopcionalNombres o identificadores de los productos a los que aplica. Obligatorio si valid_products_mode es "someProducts". Se resuelven contra tu catálogo real.
exclude_extrasbooleanoopcionalSolo con "percentage": si es true, el descuento no toca los extras, solo la base del producto. Por defecto false.
valid_from, valid_untilfechaopcionalVentana de validez del cupón.
limit_usesnúmeroopcionalSi 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": []
}
CampoSignificado
applied_defaultsQué valores por defecto se rellenaron porque no los pasaste.
resolved_discountTipo y valor del descuento ya validados, con el motivo.
resolved_productsLos productos de valid_products ya resueltos a un identificador concreto, con el motivo del match. Vacío si el modo es always.
payload_previewLo 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ónRespuesta
Falta code, title o discount_value400 con error: "invalid_params" y el campo que falta en details.
valid_products_mode: "someProducts" sin valid_products200 con success: false y error: "valid_products_required".

Consejos

  • Si un producto de valid_products no 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ámetroTipoNivelQué hace
coupontextoobligatorioCódigo o identificador del cupón a editar.
titletextorecomendadoNuevo título. Solo cambia el español, no toca otros idiomas.
discount_valuenúmerorecomendadoNueva 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_typetextoopcionalNuevo tipo: "percentage" o "fixed".
valid_from, valid_untilfechaopcionalNueva ventana de validez.
limit_usesnúmeroopcionalUsos restantes. Ojo: es un contador que decrementa con cada canje, no un tope acumulativo; fijarlo aquí sobrescribe el conteo actual.
codetextoopcionalNuevo 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_modetextoopcional"always" o "someProducts". Si pasas valid_products, se asume "someProducts".
valid_productslistaopcionalNueva lista de productos a los que aplica. Reemplaza el conjunto entero, no lo amplía.
exclude_extrasbooleanoopcionalExcluir los extras del descuento (solo con "percentage").
can_be_addedbooleanoopcionalSi el cupón se puede acumular con otros.
enjoy_from, enjoy_untilfechaopcionalVentana 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ónRespuesta
Código o identificador que no resuelve a ningún cupón200 con success: false, error: "coupon_unresolved" y candidates con los cupones existentes que más se parecen.

Consejos

  • El manual describe valid_products a 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 un get-coupon despué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ámetroTipoNivelQué hace
coupontextoobligatorioCódigo o identificador del cupón a borrar.
confirmbooleanorecomendadoTiene 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ónRespuesta
Código o identificador que no resuelve a ningún cupón200 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 (confirm sin true) antes de confirmar de verdad.

¿Te ha resultado útil este artículo?