Saltar al contenido principal

Crear un webhook

POST/v1/webhooks

Para desarrolladores

Descripción​

Registra un endpoint que recibe los eventos de los correos de la instancia. La respuesta incluye el secreto de firma (whsec_…) con el que se firman las entregas, y es la única vez que se entrega.

El formato de las entregas, la verificación de la firma y los reintentos están en Webhooks.

Autenticación​

Authorizationbearer tokenheaderobligatorio
API key con scope webhooks:write. Formato: Bearer <API_KEY>.
X-Instance-Slugstringheaderobligatorio
Identificador de su instancia. Ver Autenticación.

Request​

Body:

{
"name": "CRM de ventas",
"url": "https://hooks.example.com/fidelizador",
"events": ["mail.sent", "mail.bounced"],
"is_active": true
}
namestringobligatorio
1–255 caracteres.
urlstringobligatorio
Endpoint que recibe las entregas, hasta 1024 caracteres. Debe ser https://, sin usuario ni contraseña, y su host debe resolver a direcciones públicas. Ver Requisitos del endpoint.
eventsstring[], enum: `mail.sent | mail.bounced | mail.dropped | mail.opened | mail.clicked | mail.unsubscribed | mail.resubscribed | mail.complained` | null
Tipos de evento que recibe; al menos uno si se envía la lista, y los repetidos se ignoran. Si se omite o es null, recibe todos.
is_activeboolean
false crea el webhook pausado. Default: true.

Response​

201 CreatedDevuelve el objeto creado. El header Location trae su URL (ver Headers).
idintegersiempre presente
Identificador del webhook creado.
namestringsiempre presente
—
urlstringsiempre presente
—
eventsstring[] | nullsiempre presente
Los tipos de evento, sin repetidos. null recibe todos.
is_activebooleansiempre presente
—
last_success_atstring (date-time) | nullsiempre presente
null hasta la primera entrega exitosa.
last_failure_atstring (date-time) | nullsiempre presente
null hasta la primera entrega fallida.
last_status_codeinteger | nullsiempre presente
null hasta la primera entrega.
consecutive_failuresintegersiempre presente
0 al crear.
failing_sincestring|nullsiempre presente
Momento del primer fallo de la racha en curso, o null si la última entrega fue exitosa.
auto_paused_atstring (date-time) | nullsiempre presente
null al crear.
previous_secret_expires_atstring (date-time) | nullsiempre presente
null al crear: todavía no hubo una rotación.
created_atstring (date-time)siempre presente
—
updated_atstring (date-time)siempre presente
—
secretstringsiempre presente
Secreto de firma. Solo se entrega en esta respuesta.

Errores​

CódigoCuándo
402Crear el webhook supera la cantidad de webhooks que permite el plan (plan_webhooks_limit_exceeded).
422El body no es válido, o la URL no cumple los requisitos: errors[].code es webhook_url_insecure si no usa https, o webhook_url_not_allowed si no resuelve a una dirección pública.

Detalle completo en Errores de negocio y Errores genéricos.

Notas
  • Guarde el secreto de inmediato: no se puede recuperar después. Si lo pierde, rótelo con POST /v1/webhooks/{id}/rotate-secret.
  • El secreto lo genera la plataforma. Un campo secret en el body se ignora, igual que cualquier otro campo no documentado.
  • El cupo del plan cuenta todos los webhooks de la instancia, activos o pausados.
  • Para comprobar que el endpoint recibe y verifica la firma sin esperar un evento real, envíe un evento de prueba con POST /v1/webhooks/{id}/test.
Request
curl -X POST "https://$API_HOST/v1/webhooks" \
-H "Authorization: Bearer $API_KEY" \
-H "X-Instance-Slug: $SLUG" \
-H "Content-Type: application/json" \
-d '{
"name": "CRM de ventas",
"url": "https://hooks.example.com/fidelizador",
"events": [
"mail.sent",
"mail.bounced"
]
}'
Response
{
"id": 3,
"name": "CRM de ventas",
"url": "https://hooks.example.com/fidelizador",
"events": [
"mail.sent",
"mail.bounced"
],
"is_active": true,
"last_success_at": null,
"last_failure_at": null,
"last_status_code": null,
"consecutive_failures": 0,
"failing_since": null,
"auto_paused_at": null,
"previous_secret_expires_at": null,
"created_at": "2026-09-14T10:00:00Z",
"updated_at": "2026-09-14T10:00:00Z",
"secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
}