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

# Gestión de suscripciones

> Crea suscripciones de webhook y de cola en Streaming Hub, conecta una concesión delegada de AWS, rota un secreto de firma, recupera un destino auto-desactivado y vuelve a fijar un major de esquema.

Una **suscripción** le indica a Streaming Hub qué eventos van a qué destino para tu tenant. Gestionas las suscripciones a través de la API del plano de control `/v1`, autenticada con un JWT de plugin-auth. Esta página cubre el modelo y los flujos de incorporación; las formas exactas de solicitud y respuesta están en la referencia de la API (empieza por la [introducción a la referencia](/es/reference/introduction)).

## El modelo de suscripción

***

Una suscripción registra:

* **`name`** — una etiqueta legible (requerida, no vacía).
* **`sink_kind`** — uno de `webhook`, `pull`, `sqs`, `rabbitmq`, `eventbridge`.
* **`endpoint`** — a dónde van las entregas, en una forma que depende del tipo de sink (ver abajo).
* **`event_types`** — los tipos de evento a entregar. Un tipo desconocido genera una advertencia pero nunca bloquea una creación, así que un hueco en el catálogo nunca detiene la incorporación.
* **`schema_major`** — la versión major del payload que sigue la suscripción.
* **`plan_tier`** — el tier de entrega bajo el que opera la suscripción.

El formato del endpoint depende del tipo de sink:

| Tipo de sink  | Endpoint                                                                                                                |
| ------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `webhook`     | Una URL `https://`, sin userinfo incrustado.                                                                            |
| `pull`        | Se omite; el servidor sintetiza `pull://<id>`.                                                                          |
| `sqs`         | La URL `https://` de la cola SQS.                                                                                       |
| `rabbitmq`    | `<exchange>/<routingKey>` (exchange requerido, routing key opcional). El host del broker vive en la credencial cifrada. |
| `eventbridge` | El string de direccionamiento nombre-del-bus-de-eventos / detail-type. La región vive en la credencial cifrada.         |

### Dos campos de estado ortogonales

***

Cada suscripción lleva dos campos de estado independientes. Confundirlos es la fuente más común de preguntas del tipo «¿por qué se detuvo la entrega?», así que mantenlos separados:

* **`verification_state`** es la **prueba** de que el destino realmente puede recibir eventos. Recorre `pending_verification` → `active` → `degraded`, impulsado por sondeos. Solo una suscripción `active` es entregable.
* **`enabled`** es el **interruptor de entregabilidad**. Es lo que la auto-desactivación apaga, y lo que una reactivación vuelve a encender.

La coincidencia de suscripciones requiere **ambos**: una suscripción entrega solo cuando `enabled` **y** `verification_state = active`. La auto-desactivación vive por completo en `enabled` y nunca cambia `verification_state`, así que una suscripción auto-desactivada se lee como `enabled = false, verification_state = active`. Consulta [auto-desactivación de un destino roto](/es/streaming-hub/how-streaming-hub-works) para ver cómo interactúan los dos.

## Crear una suscripción de webhook

***

Una suscripción de webhook es la más simple de incorporar: nace lista para recibir:

1. **Crear** — `POST /v1/subscriptions` con `sink_kind: "webhook"` y tu endpoint `https://`. La URL de destino se valida contra rangos de direcciones privadas, de loopback y de metadatos de nube antes de escribir cualquier fila, así que un destino privado o de metadatos nunca puede almacenarse. La respuesta devuelve la nueva suscripción **ya `active`**, y el **secreto de firma exactamente una vez**.
2. **Guarda el secreto de firma** — se muestra solo en esta respuesta, se almacena solo como texto cifrado y nunca lo devuelve ninguna lectura. Guárdalo al recibirlo; si lo pierdes, solo puedes rotar a uno nuevo.
3. **Confirma la accesibilidad (opcional)** — `POST /v1/subscriptions/:id/ping` envía un sondeo sintético y firmado a través del camino de entrega real e informa el resultado clasificado.

<Warning>
  El secreto de firma se devuelve solo en la respuesta de creación (y de nuevo al rotar). Nunca se registra en logs, nunca se almacena en texto plano y nunca lo devuelve un `GET`. Captúralo cuando creas la suscripción.
</Warning>

Una vez creada, la suscripción de webhook entra en la coincidencia y empieza a recibir eventos. Consulta [Consumo de eventos](/es/streaming-hub/consuming-events) para saber cómo verificar la firma en cada entrega.

## Incorporar una suscripción de cola

***

Las suscripciones de cola (`sqs`, `rabbitmq`, `eventbridge`) nacen **`pending_verification`** y **no entregan nada** hasta que su destino se verifica. Cómo lo verificas depende del tipo:

* **RabbitMQ** — suministra una credencial de broker, verificada en la escritura (abajo).
* **SQS y EventBridge** — [conecta una concesión delegada de AWS](#conectar-una-concesión-delegada-de-aws) (siguiente sección) en lugar de almacenar una credencial.

Para RabbitMQ, el flujo de credencial tiene tres pasos:

1. **Crear** — `POST /v1/subscriptions` con el `sink_kind` de la cola y su endpoint, y **sin** credencial en línea (un `sink_config` o `credential` en línea se rechaza). La suscripción se almacena como `pending_verification`; la coincidencia la excluye, así que todavía no produce trabajos de entrega.
2. **Suministra la credencial** — `PUT /v1/subscriptions/:id/credential` con la credencial de broker de solo escritura. El hub la mantiene en memoria, **la sondea de inmediato** (conecta y se autentica contra el broker) y la persiste como texto cifrado **solo si el sondeo tiene éxito**: un sondeo fallido no almacena nada. El host del broker se valida contra rangos de direcciones bloqueadas antes de almacenarse. Un sondeo exitoso cambia la suscripción de `pending_verification → active` en la misma transacción.
3. **Active** — una vez `active`, la coincidencia admite la suscripción y esta empieza a recibir eventos.

La credencial es de **solo escritura**: la suministras aquí y nunca se devuelve, ni siquiera enmascarada, en ningún camino de lectura. Para cambiarla, haz `PUT` de una nueva; se aplica el mismo sondeo en la escritura.

## Conectar una concesión delegada de AWS

***

Para los sinks de AWS (`sqs`, `eventbridge`), el hub entrega asumiendo un rol **en tu cuenta de AWS**; nunca almacena una credencial de AWS. Estableces esa confianza antes de suministrar la credencial:

1. **Obtén los artefactos de configuración** — `GET /v1/subscriptions/:id/setup-artifacts` devuelve una **política de confianza** IAM entre cuentas, un **enlace de creación rápida** de CloudFormation y un **`ExternalId`** no secreto que el hub acuña para esta suscripción.
2. **Aplícalos en tu cuenta de AWS** — crea el rol de entrega a partir de la política de confianza (el enlace de creación rápida lo genera). El rol confía en el principal del hub *solo* bajo la condición del `ExternalId` acuñado, lo que cierra la brecha del confused deputy: una política de confianza que carece de esa condición se trata como un fallo de verificación, nunca como verificada.
3. **Registra la concesión** — `PUT /v1/subscriptions/:id/delegated-grant` con el ARN del rol de entrega, la región y el destino. Esto solo registra coordenadas no secretas; no ejecuta ningún sondeo y no cambia `verification_state`.
4. **Verifica** — `POST /v1/subscriptions/:id/verify` ejecuta el sondeo endurecido de asunción de rol y, si tiene éxito, cambia la suscripción a `active`.

Ninguna credencial de AWS cruza jamás estas solicitudes ni la almacena el hub; el hub asume tu rol por cada entrega, protegido por el `ExternalId`.

## Rotar un secreto de firma

***

`POST /v1/subscriptions/:id/secret/rotate` acuña un secreto de firma de webhook **nuevo**, lo devuelve **una vez** e inicia un **solapamiento de doble firma de 24 horas**. Durante el solapamiento, el hub firma cada entrega con **ambos** secretos, el nuevo y el anterior, y envía **dos** headers de firma, así que tu consumidor puede cambiar al nuevo secreto en cualquier momento de la ventana sin perder entregas.

Rota de forma limpia así:

1. Llama a rotate y guarda el nuevo secreto de la respuesta (junto con el timestamp `overlapUntil`).
2. Despliega el nuevo secreto en tu consumidor dentro de la ventana de solapamiento. Mientras ambos estén configurados, tu verificador acepta una entrega si **cualquiera** de las firmas valida.
3. Después del solapamiento, retira el secreto antiguo.

Rotar un sink `pull` —que no tiene secreto de firma— se rechaza. Consulta [manejar dos firmas durante la rotación](/es/streaming-hub/consuming-events) para la verificación del lado del consumidor.

## Recuperar una suscripción auto-desactivada

***

Cuando un destino permanece roto el tiempo suficiente, el hub [auto-desactiva](/es/streaming-hub/how-streaming-hub-works) la suscripción cambiando `enabled = false`. Para recuperarla:

1. Arregla el destino (el endpoint, la cola o la concesión).
2. Llama a `POST /v1/subscriptions/:id/verify`. Vuelve a sondear el destino y, ante un sondeo exitoso, reactiva la suscripción y limpia la marca de auto-desactivación —en su sitio, conservando el mismo id y secreto de firma.

Un nuevo sondeo fallido no cambia nada, así que la reactivación siempre está ligada a un éxito de sondeo real y actual. `GET /v1/subscriptions/:id/health` te da el resumen de salud de entrega —resultados recientes, recuentos de dead-letter y el veredicto de auto-desactivación— para confirmar que el destino está sano antes y después.

## Volver a fijar el major de esquema

***

`PATCH /v1/subscriptions/:id` vuelve a fijar el `schema_major` de la suscripción, el **único** campo mutable:

* `{"schema_major": 2}` fija la suscripción a esa versión major.
* `{"schema_major": null}` elimina la fijación para seguir la versión base.

Cualquier otro campo, un body vacío o un valor por debajo de `1` se **rechaza** (no se ignora en silencio), así que nunca puedes creer que un cambio prohibido surtió efecto. Cambiar el endpoint, el tipo de sink o el secreto queda fuera del alcance de `PATCH` por diseño; crea una suscripción nueva para un destino distinto. Volver a fijar no es un cambio de destino: no reinicia `verification_state` y no devuelve ningún secreto.

## Idempotencia

***

Las rutas mutantes —crear, eliminar, `PATCH`, rotar el secreto y registrar la concesión delegada— requieren una clave de idempotencia:

```
X-Idempotency: <your-unique-key>
```

Una mutación enviada sin ella se rechaza **antes de cualquier escritura** con `400 missing_idempotency_key`. El almacén es **fail-closed**: si el almacén de idempotencia es inalcanzable, la solicitud falla en lugar de arriesgar una doble escritura; esto garantiza que un create o un rotate reproducido vuelva a servir el secreto original mostrado una sola vez en lugar de acuñar uno nuevo.

* Reproducir una clave confirmada devuelve la respuesta original byte a byte, con `X-Idempotency-Replayed: true`.
* Reusar una clave con un body de solicitud *diferente* devuelve `409 idempotency_conflict`; acuña una clave nueva para una solicitud corregida.

Las rutas de verificación (`ping`, `verify`, `PUT /credential`, `GET /setup-artifacts`) son naturalmente idempotentes y no requieren clave. Consulta la guía de toda la plataforma sobre [reintentos e idempotencia](/es/reference/retries-idempotency).

## Próximos pasos

***

<CardGroup cols={2}>
  <Card title="Consumo de eventos" icon="inbox" href="/es/streaming-hub/consuming-events">
    Verifica firmas de webhook, deduplica entregas y consulta eventos mediante pull.
  </Card>

  <Card title="Cómo funciona Streaming Hub" icon="diagram-project" href="/es/streaming-hub/how-streaming-hub-works">
    Coincidencia, envío, reintentos y auto-desactivación en detalle.
  </Card>
</CardGroup>
