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

# Suscripciones

> Crear un webhook, guardar el secreto de un solo uso, elegir eventos, activar, desactivar y rotar.

Un **webhook** es un suscriptor: una URL de callback, un secreto de firma y
un alcance (global o una cuenta). Un **webhook event** vincula ese suscriptor
con un evento del catálogo. Las entregas se registran por suscriptor en
`webhook_dispatch`.

<Note>
  Todas las llamadas siguientes requieren un bearer token cuyo usuario tenga
  el permiso `webhook:*` / `webhook-event:*` correspondiente. En el primer
  release esos permisos se conceden únicamente al rol `administrator`.
</Note>

## 1. Crear el webhook

```bash theme={null}
curl -X POST https://api.bbrands.io/api/v3/webhook/webhook \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "account": "8f3b1c2e-0d4a-4f2b-9c1e-6a7b8c9d0e1f",
    "description": "ERP sync for Maihue Chile",
    "is_global": false,
    "name": "erp-maihue-cl",
    "url": "https://erp.example.com/hooks/bbrands"
  }'
```

| Campo         | Reglas                                                                                                                                                                              |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`         | Obligatorio. HTTPS, host público, máx. 2048 caracteres. Se rechazan hosts loopback, privados, link-local, de metadatos y `*.internal` (`http://` solo se permite en `development`). |
| `is_global`   | Opcional, por defecto `false`. Con `true` recibe todos los eventos suscritos sin importar el propietario.                                                                           |
| `account`     | Obligatorio cuando `is_global` es `false`; se ignora cuando es `true`. Debe ser una cuenta existente.                                                                               |
| `name`        | Opcional, máx. 100 caracteres.                                                                                                                                                      |
| `description` | Opcional, máx. 500 caracteres.                                                                                                                                                      |

La respuesta es la fila pública del webhook **más `secret`**, devuelto una
sola vez:

```json theme={null}
{
  "data": {
    "account": "8f3b1c2e-0d4a-4f2b-9c1e-6a7b8c9d0e1f",
    "consecutive_failures": 0,
    "description": "ERP sync for Maihue Chile",
    "disabled_at": null,
    "disabled_reason": null,
    "document_id": "2f9a7c41-5d3e-4b8a-9f01-c2d3e4f5a6b7",
    "is_actived": true,
    "is_global": false,
    "name": "erp-maihue-cl",
    "secret": "whsec_Qm4sZ3JhbmRzTGFiX3NlY3JldF9leGFtcGxlXzMyYnl0ZXM",
    "url": "https://erp.example.com/hooks/bbrands"
  },
  "message": "Webhook record created successfully"
}
```

<Warning>
  `secret` **no vuelve a devolverse**: `GET`, listado, actualización y
  exportación lo omiten. Guárdalo de inmediato en tu gestor de secretos. Si
  se pierde, usa [rotate-secret](#4-rotar-el-secreto).
</Warning>

## 2. Elegir eventos

Busca los ids del catálogo que necesitas y reemplaza el conjunto de
suscripciones en una sola llamada. El cuerpo es la lista **completa**
deseada — los eventos que no aparezcan se dan de baja (borrado lógico), los
ya presentes se conservan y los nuevos se insertan.

```bash theme={null}
# Buscar los ids
curl "https://api.bbrands.io/api/v3/webhook/event?filters=internal|in|payment-debt.created,payment-debt.updated&page_size=50" \
  -H "Authorization: Bearer $TOKEN"

# Reemplazar el conjunto de suscripciones
curl -X PUT https://api.bbrands.io/api/v3/webhook/webhook/2f9a7c41-5d3e-4b8a-9f01-c2d3e4f5a6b7/events \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "events": ["<event id 1>", "<event id 2>"] }'
```

`events` debe contener al menos un id. `webhook.test` se mantiene siempre
en el conjunto (create y el replace-set lo anteponen) para que la acción
**Probar** tenga una suscripción contra la que registrar.

<Tip>
  Los webhooks por cuenta solo reciben eventos con `account_scope` igual a
  `account` **y** cuyo propietario resuelto coincide. Suscribir un webhook
  por cuenta a un evento `none` (p. ej. `general.address.updated`) está
  permitido pero nunca se disparará — usa un webhook global para esos casos.
</Tip>

## 3. Activar y desactivar

Los webhooks se crean activos. Cambia el estado con:

```bash theme={null}
curl -X PATCH https://api.bbrands.io/api/v3/webhook/webhook/2f9a7c41-5d3e-4b8a-9f01-c2d3e4f5a6b7/active \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "is_actived": false }'
```

Los webhooks inactivos se omiten al enrutar (no se escriben filas de
dispatch para ellos). Activar un webhook también **limpia**
`consecutive_failures`, `disabled_at` y `disabled_reason`, que es la forma de
recuperar un suscriptor desactivado automáticamente — ver
[Reintentos y fallos](/es/webhooks/retries-and-failures#desactivación-automática).

## 4. Rotar el secreto

```bash theme={null}
curl -X POST https://api.bbrands.io/api/v3/webhook/webhook/2f9a7c41-5d3e-4b8a-9f01-c2d3e4f5a6b7/rotate-secret \
  -H "Authorization: Bearer $TOKEN"
```

Devuelve la fila pública más el **nuevo** `secret`, de nuevo una sola vez.
No hay ventana de solape: toda entrega firmada tras la llamada usa el nuevo
valor. Despliega antes el secreto en tu lado, o espera una breve ráfaga de
respuestas `401` que la plataforma reintentará según el backoff.

## 5. Actualizar o eliminar

* `PATCH /api/v3/webhook/webhook/{id}` — actualización parcial de `url`,
  `name`, `description`, `is_global`, `account`. Se aplican de nuevo las
  reglas de URL.
* `DELETE /api/v3/webhook/webhook/{id}` — borrado lógico; el libro mayor se
  conserva.
* `DELETE /api/v3/webhook/webhook/{id}/purge` — borrado físico.

## Desde Horizon Enterprise

Los mismos flujos están disponibles en **Webhooks** dentro de Horizon
Enterprise (rol `administrator`): el formulario muestra el secreto en un
aviso de un solo uso tras crear y rotar, el selector de eventos agrupa el
catálogo por dominio y la pantalla de detalle lista las entregas con
filtros, `last_error` y una acción **Reenviar**.
