# Configurar un webhook

> Crea un endpoint de webhook, elige sus eventos, añade filtros de payload, envía un evento de prueba, activa o desactiva el webhook y rota su secreto.

En esta guía crearás un webhook, lo limitarás a los eventos que necesitas y comprobarás que tu endpoint recibe peticiones firmadas. Puedes hacerlo todo en el panel o con la [API de webhooks](/es/docs/api-reference/webhooks/).

## Antes de empezar

- Una URL pública que acepte peticiones `POST`. Se recomienda encarecidamente usar HTTPS. Las URL en `localhost` o en rangos de IP privadas se rechazan; para el desarrollo local, usa un túnel como ngrok o Cloudflare Tunnel.
- Un endpoint que conserve el cuerpo en bruto de la petición para poder [verificar la firma](/es/docs/webhooks/request-signature/).
- Para la API, una clave con **Full Access**.
- Margen para un webhook más. Pay as you go incluye 3 endpoints; Pro, 10, y Business y Custom, 100.

## Crear el webhook

**Panel**

  1. **Abre Webhooks.** Ve a **Email API → Webhooks** y selecciona **Add webhook**.

  2. **Introduce un nombre y una URL.** El nombre debe ser único en el espacio de trabajo, por ejemplo `Production events`. La URL es tu endpoint, por ejemplo `https://acme.com/webhooks/emailit`. Selecciona **Create**.

  3. **Copia el secreto.** El cuadro de diálogo muestra el secreto del webhook, que empieza por `whsec_`, junto con el aviso «You can see the webhook secret only once. Store it safely». Cópialo en el entorno de tu aplicación, por ejemplo como `EMAILIT_WEBHOOK_SECRET`, y selecciona **Done**.

  Un webhook creado en el panel está suscrito a todos los tipos de eventos. Se abre la pestaña **Settings** del webhook para que puedas limitarlo.

**API**

  Llama a [Crear un webhook](/es/docs/api-reference/webhooks/create/). Indica los tipos de eventos en `events` o establece `all_events` en `true`. La respuesta `201` incluye el `secret`.

```bash
curl https://api.emailit.com/v2/webhooks \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production events",
    "url": "https://acme.com/webhooks/emailit",
    "events": ["email.delivered", "email.bounced", "email.complained"]
  }'
```

  A diferencia del panel, la API usa por defecto `all_events: false` y una lista `events` vacía, así que un webhook creado sin ninguno de los dos no recibe nada. Un nombre duplicado devuelve `409`; si alcanzas el límite de endpoints de tu plan, se devuelve `422` con `usage.used` y `usage.limit`.

## Elegir los eventos

Un webhook recibe todos los tipos de eventos o solo los tipos que selecciones.

**Panel**

  En la pestaña **Settings** del webhook, desactiva **All events** y selecciona los tipos en la tarjeta **Events**. Los eventos se agrupan por recurso (**Emails**, **Domains**, **Audiences**, **Subscribers**, **Contacts**, **Templates**, **Suppressions**, **Email Verifications**, **Email Verification Lists**), y cada grupo tiene una casilla **Select all**. Selecciona **Save**.

  El selector no muestra todos los tipos que envía Emailit. `email.canceled`, `email.held`, `email.unsubscribed`, `email.resubscribed`, `subscriber.resubscribed` y los eventos `campaign.*` llegan a los webhooks que tienen **All events** activado, o puedes añadirlos a la lista con la API. El grupo **Deprecated** contiene nombres de eventos antiguos que ya no se envían. Consulta [Tipos de eventos](/es/docs/webhooks/event-types/).

**API**

  Llama a [Actualizar un webhook](/es/docs/api-reference/webhooks/update/). `events` sustituye la lista completa. Si estableces `all_events` en `true`, la lista se vacía.

```bash
curl -X POST https://api.emailit.com/v2/webhooks/wh_2xGk8Hd3RvN6qT1mWsB9cL4pZ7e \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"all_events": false, "events": ["email.received", "email.held", "email.canceled"]}'
```

## Filtrar eventos por payload

Pro, Business, Custom

Un filtro de payload entrega un evento solo cuando sus datos cumplen tus reglas. Los filtros se aplican además de la selección de eventos: un evento tiene que estar suscrito *y* cumplir el filtro.

Úsalo para repartir el tráfico entre endpoints, por ejemplo un webhook por línea de producto, o para descartar eventos que, de lo contrario, ignorarías en el código.

- **Modo de coincidencia:** **All rules match** (`all`) o **Any rule matches** (`any`).
- **Reglas:** hasta 25. Cada regla tiene un campo, un operador y un valor.
- **Campo:** una ruta con puntos dentro del `data.object` del evento, por ejemplo `to`, `status`, `meta.plan` o, en los eventos de clic, `link.url`. El prefijo `payload.` es opcional, así que `payload.from` y `from` son equivalentes.
- **Las comparaciones distinguen entre mayúsculas y minúsculas** y comparan los valores como texto, salvo `greater_than` y `less_than`, que comparan números.

| Operador | Coincide cuando el campo |
| --- | --- |
| `equals` / `not_equals` | Es / no es exactamente el valor. |
| `contains` / `not_contains` | Contiene / no contiene el valor. |
| `starts_with` / `ends_with` | Empieza / termina por el valor. |
| `greater_than` / `less_than` | Es un número mayor / menor que el valor. |
| `is_set` / `is_not_set` | Tiene un valor no vacío / falta o está vacío. No necesita valor. |
| `in` / `not_in` | Es igual / no es igual a uno de los valores de un array. Envía el array con la API, como en el ejemplo de abajo. |

**Panel**

  En la pestaña **Settings** del webhook, busca la tarjeta **Filter**. Elige el modo de coincidencia, añade reglas con un campo, un operador y un valor, y selecciona **Save**. Deja las reglas vacías para entregar todos los eventos suscritos. En Pay as you go, la tarjeta está bloqueada y muestra **Upgrade**.

**API**

  Envía `filter` con [Crear un webhook](/es/docs/api-reference/webhooks/create/) o [Actualizar un webhook](/es/docs/api-reference/webhooks/update/). Establécelo en `null` para quitarlo. En Pay as you go, un filtro devuelve `403` con `"error": "plan_required"`.

```bash
curl -X POST https://api.emailit.com/v2/webhooks/wh_2xGk8Hd3RvN6qT1mWsB9cL4pZ7e \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {
      "match": "all",
      "rules": [
        { "field": "to", "operator": "ends_with", "value": "@acme.com" },
        { "field": "meta.plan", "operator": "in", "value": ["pro", "business"] }
      ]
    }
  }'
```

Más ejemplos:

| Objetivo | Regla |
| --- | --- |
| Solo el correo recibido en una dirección | `to` `equals` `support@inbound.acme.com` |
| Solo un dominio remitente | `from` `ends_with` `@billing.acme.com` |
| Solo los emails que etiquetaste con metadatos | `meta.source` `equals` `checkout` |
| Solo los clics en tu página de precios | `link.url` `starts_with` `https://acme.com/pricing` |
| Solo los emails que llevan un ID de cliente | `meta.customer_id` `is_set` |

> **Los campos varían según el tipo de evento:** Una regla sobre un campo que el evento no tiene nunca coincide. Los eventos de estado de email tienen `to` y `from` en el nivel superior, pero los eventos de clic y de carga los anidan como `email.rcpt_to` y `email.mail_from`, y los eventos de contacto tienen `email`. Con **All rules match**, un webhook filtrado por `to` descarta sin avisar todos los clics. Usa webhooks distintos para cada clase de evento, o **Any rule matches** con una regla por cada forma. Comprueba los nombres de los campos en la [referencia de eventos](/es/docs/webhooks/event-types/).

Si un espacio de trabajo pasa a Pay as you go, los filtros existentes se conservan, pero se ignoran, y se entregan todos los eventos suscritos.

## Enviar un evento de prueba

Una prueba envía de inmediato un evento de ejemplo a tu URL, firmado con el secreto actual del webhook. Se ignoran los eventos suscritos y los filtros, la petición no se reintenta y no aparece en la pestaña **Requests**. Cada webhook permite 5 pruebas por minuto.

**Panel**

  En la página del webhook, abre el menú de acciones (**…**) y selecciona **Send test**. Elige un tipo de evento y selecciona **Send test**. El cuadro de diálogo muestra «Your endpoint returned 200» (o el estado que haya devuelto tu endpoint) y el cuerpo de la respuesta. «Could not reach the endpoint» significa que la petición no obtuvo una respuesta HTTP, por ejemplo por un error de DNS, un tiempo de espera agotado o una redirección.

**API**

  Llama a [Enviar un evento de prueba](/es/docs/api-reference/webhooks/test/) con cualquier tipo de evento.

```bash
curl https://api.emailit.com/v2/webhooks/wh_2xGk8Hd3RvN6qT1mWsB9cL4pZ7e/test \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "email.delivered"}'
```

  La respuesta contiene `ok`, `status_code`, `body` (la respuesta de tu endpoint, hasta 2000 caracteres), `type` y el `payload` que se envió.

Los eventos de prueba usan datos de ejemplo, con un `event_id` que empieza por `evt_test_`, y su forma puede diferir ligeramente de la de los eventos reales. Desarrolla tu controlador a partir de la [referencia de eventos](/es/docs/webhooks/event-types/) y confírmalo con un envío real.

## Activar o desactivar un webhook

Desactiva un webhook para detener las entregas sin perder su configuración, por ejemplo durante un mantenimiento.

- **Panel:** abre el menú de acciones y selecciona **Disable webhook** o **Enable webhook**. La página del webhook muestra el estado **Enabled** o **Disabled**.
- **API:** llama a [Actualizar un webhook](/es/docs/api-reference/webhooks/update/) con `{"enabled": false}` o `{"enabled": true}`.

Mientras un webhook está desactivado, no se ponen en cola eventos nuevos para él y las peticiones que ya esperaban un reintento quedan en pausa. Los eventos que ocurren mientras está desactivado no se entregan más tarde; si los necesitas, léelos con la [API de eventos](/es/docs/logs/events/#reconcile-missed-webhook-events). Emailit también desactiva los webhooks automáticamente tras 3 días de fallos; consulta [Reintentos y fallos](/es/docs/webhooks/retries-and-failures/).

Al eliminar un webhook se descartan todos sus eventos pendientes.

## Rotar el secreto

Rota el secreto si puede haberse filtrado, o como medida de seguridad habitual.

- **Panel:** abre el menú de acciones, selecciona **Webhook secret** y después **Reset**. El nuevo secreto se muestra una sola vez.
- **API:** llama a [Rotar el secreto de firma](/es/docs/api-reference/webhooks/reset-secret/). La respuesta contiene el nuevo `secret`. [Obtener un webhook](/es/docs/api-reference/webhooks/get/) también devuelve el secreto actual.

El secreto anterior deja de funcionar de inmediato, y todas las peticiones a partir de ese momento, incluidos los reintentos de eventos anteriores, se firman con el nuevo. Para rotarlo sin rechazar peticiones, haz que tu endpoint acepte cualquiera de los dos secretos durante unos minutos, restablece el secreto, despliega el nuevo valor y después elimina el anterior.

## Comprobar que funciona

1. Envía un evento de prueba y confirma que tu endpoint devuelve `2xx`.
2. Envía un email real o dispara el evento al que te suscribiste.
3. En la pestaña **Requests** del webhook, la petición muestra **Delivered**. La hora de **Last used** del webhook se actualiza.

## Ver también

  - [Verificar las firmas](/es/docs/webhooks/request-signature/)
  - [Peticiones de webhook](/es/docs/webhooks/webhook-requests/)
  - [Tipos de eventos](/es/docs/webhooks/event-types/)
  - [Reintentos y fallos](/es/docs/webhooks/retries-and-failures/)

---
Fuente: https://emailit.com/es/docs/webhooks/set-up/
