> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coupons.piixan.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Decisiones en línea

> POST /v1/decisiones: una decisión por cliente en menos de 100 ms, con propensión, motivo y caducidad.

```bash theme={null}
curl -X POST https://api.coupons.piixan.ai/v1/decisiones \
  -H "Authorization: Bearer $TOKEN" -H "Idempotency-Key: 7c1f…" \
  -d '{"cliente_ref": "c_9f1e2d3c4b5a6978", "contexto": {"canal": "push", "campana_id": "camp-2026-11"}}'
```

```json theme={null}
{
  "decision_id": "dec_3d5b142295cebe8fb65c_e3d905708071",
  "accion": 2, "accion_nombre": "lacteos_15", "propension": 0.8215,
  "politica_version": "mu-a1b2c3|categoria_favorita",
  "explorado": false, "en_control": false, "en_respaldo": false,
  "caduca_en": "2026-03-13T15:00:00Z",
  "motivo": "margen esperado +8.40 MXN frente a no mandar; 3 cupones caducados sin redimir"
}
```

| campo        | qué significa                                                                            |
| ------------ | ---------------------------------------------------------------------------------------- |
| `accion`     | `0` es «no mandar nada»; el resto, ids de tu catálogo (`PUT /v1/catalogo-acciones`)      |
| `propension` | probabilidad con la que el motor eligió esa acción; guárdala si registras aparte         |
| `en_control` | el cliente está en un grupo de control («nada» o «regla actual»)                         |
| `explorado`  | la acción salió de la exploración, no de la política                                     |
| `caduca_en`  | hasta cuándo se admite la confirmación de ejecución (7 días)                             |
| `motivo`     | explicación breve; con el ámbito `explicar:leer` llega además `detalle` con μ por acción |

## Contexto

* `canal`: por dónde vas a ejecutar la acción (`push`, `sms`, `email`, `app`, `caja`…).
* `campana_id`: si la decisión pertenece a una campaña definida con `PUT /v1/campanas/{id}`,
  se aplica su presupuesto.
* `acciones_permitidas`: subconjunto de ids que puedes ejecutar ahora (por ejemplo, solo
  cupones de app si el cliente está en la app). `0` siempre está.

## Ventana abierta

Si el cliente ya tiene una decisión con ventana de recompensa abierta (menos de N días,
28 por defecto), la respuesta es `accion: 0`, `propension: 1` y el `decision_id` de esa
decisión, con el motivo «ventana de recompensa abierta». No se crea otra.

## Límites

Hasta 50 peticiones por segundo por credencial (ráfaga de 100), 3 decisiones por
`cliente_ref` y día, y la cuota diaria del inquilino. Al pasarte: `429` con `Retry-After`.
Ver [límites](/guias/limites).

## Modo sombra

Durante el alta, el operador activa el **modo sombra** del inquilino. En ese modo el
motor decide y registra como siempre, pero **solo sugiere**: cada respuesta lleva
`en_sombra: true` y tu sistema debe seguir aplicando su regla de negocio actual.

Lo que tienes que hacer en sombra, por cada decisión recibida:

1. Aplicar tu regla como hasta ahora (mandar el cupón que mandarías, o ninguno).
2. Si mandas un cupón, etiquetar el `CUPON_RECIBIDO` con el `decision_id` recibido.
3. Confirmar la ejecución con `accion_real` = el id de tu catálogo del cupón que mandaste
   (`0` si no mandaste nada): `POST /v1/decisiones/{decision_id}/ejecucion`
   con `{"ejecutada": true, "accion_real": 0}`.

Así el motor comprueba, sin tocar tus envíos, que el contrato, el bucle de confirmaciones
y la atribución funcionan (≥ 95 % de confirmaciones y de cupones con `decision_id`), y
compara lo que habría hecho con lo que hiciste. Cuando el operador desactiva la sombra,
las respuestas dejan de llevar `en_sombra` y debes ejecutar la acción decidida.
