Saltar al contenido
Webhooks · webhooks
Contrato OpenAPI 3.1: openapi.yaml
Referencia

Referencia: endpoints de webhooks

Los destinos HTTPS de tu integración. Hasta 10 por integración. El secreto de firma se enseña una sola vez.

GET/v1/webhooks
webhooks:read

Todos los webhooks de esta integración (sin paginación).

Petición

curl
curl https://wearetransfers.com/api/v1/webhooks \
  -H "Authorization: Bearer $WAT_API_KEY"

Respuesta

json
{
  "data": [
    {
      "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
      "url": "https://erp.ejemplo.com/hooks/wat",
      "events": [
        "booking.completed",
        "booking.cancelled"
      ],
      "active": true,
      "description": "ERP · servicios terminados",
      "consecutive_failures": 0,
      "disabled_at": null,
      "disabled_reason": null,
      "created_at": "2026-09-18T09:00:00.000Z",
      "updated_at": "2026-09-18T09:00:00.000Z"
    }
  ]
}
POST/v1/webhooks
webhooks:write

Crea un destino. La respuesta trae secret solo esta vez. Admite Idempotency-Key. Las reglas de la URL están en Seguridad: https, puerto 443, sin credenciales, destino público.

ParámetroDóndeTipoDescripción
url *bodystringhttps://…, ≤ 500 caracteres.
events *bodystring[]Tipos de evento, o ["*"] para todos.
descriptionbodystring≤ 200 caracteres.

Petición

curl
curl -X POST https://wearetransfers.com/api/v1/webhooks \
  -H "Authorization: Bearer $WAT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: crear-webhook-erp-1" \
  -d '{"url":"https://erp.ejemplo.com/hooks/wat","events":["booking.completed","booking.cancelled"],"description":"ERP · servicios terminados"}'

Respuesta · 201

json
{
  "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
  "url": "https://erp.ejemplo.com/hooks/wat",
  "events": [
    "booking.completed",
    "booking.cancelled"
  ],
  "active": true,
  "description": "ERP · servicios terminados",
  "consecutive_failures": 0,
  "disabled_at": null,
  "disabled_reason": null,
  "created_at": "2026-09-18T09:00:00.000Z",
  "updated_at": "2026-09-18T09:00:00.000Z",
  "secret": "whsec_2Xk9fJ3mQpL8vT1nR6wY4bH0cD7sG5aZ9eU2iO8kM3q"
}
Si reintentas la creación con la misma Idempotency-Key

La réplica llega con Idempotent-Replayed: true, secret: null y secret_shown_once: true. El secreto no se guarda para poder repetirlo: se enseña en la primera respuesta y ya. Guárdalo antes de reintentar nada; si se perdió, crea otro webhook y borra este.

GET/v1/webhooks/{id}
webhooks:read

Un webhook de esta integración.

ParámetroDóndeTipoDescripción
id *pathuuidId del webhook.

Petición

curl
curl https://wearetransfers.com/api/v1/webhooks/3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f \
  -H "Authorization: Bearer $WAT_API_KEY"

Respuesta

json
{
  "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
  "url": "https://erp.ejemplo.com/hooks/wat",
  "events": [
    "booking.completed",
    "booking.cancelled"
  ],
  "active": true,
  "description": "ERP · servicios terminados",
  "consecutive_failures": 0,
  "disabled_at": null,
  "disabled_reason": null,
  "created_at": "2026-09-18T09:00:00.000Z",
  "updated_at": "2026-09-18T09:00:00.000Z"
}
PATCH/v1/webhooks/{id}
webhooks:write

Cambia uno o más campos. active: true reactiva un webhook desactivado por fallos y pone el contador a cero. Un cuerpo vacío es 400.

ParámetroDóndeTipoDescripción
urlbodystringMisma validación que al crear.
eventsbodystring[]Sustituye la lista.
descriptionbodystring | null≤ 200.
activebodybooleanPausar (false) o reactivar (true).

Petición

curl
curl -X PATCH https://wearetransfers.com/api/v1/webhooks/3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f \
  -H "Authorization: Bearer $WAT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"active":true}'

Respuesta

json
{
  "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
  "url": "https://erp.ejemplo.com/hooks/wat",
  "events": [
    "booking.completed",
    "booking.cancelled"
  ],
  "active": true,
  "description": "ERP · servicios terminados",
  "consecutive_failures": 0,
  "disabled_at": null,
  "disabled_reason": null,
  "created_at": "2026-09-18T09:00:00.000Z",
  "updated_at": "2026-09-18T09:00:00.000Z"
}
DELETE/v1/webhooks/{id}
webhooks:write

Borra el destino y su historial de entregas.

ParámetroDóndeTipoDescripción
id *pathuuidId del webhook.

Petición

curl
curl -X DELETE https://wearetransfers.com/api/v1/webhooks/3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f \
  -H "Authorization: Bearer $WAT_API_KEY"

Respuesta

json
{
  "deleted": true
}
POST/v1/webhooks/{id}/test
webhooks:write

Encola un evento webhook.test que entrega el mismo worker que los reales, firmado igual. Responde 202; la entrega se sigue en /deliveries. Ver Pruebas.

ParámetroDóndeTipoDescripción
id *pathuuidId del webhook.

Petición

curl
curl -X POST https://wearetransfers.com/api/v1/webhooks/3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f/test \
  -H "Authorization: Bearer $WAT_API_KEY"

Respuesta · 202

json
{
  "delivery_id": "6d2e1f0a-9b8c-4d7e-a6f5-4c3b2a1d0e9f",
  "event_id": "8b7a6c5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
  "status": "pending"
}
POST/v1/webhooks/{id}/rotate-secret
webhooks:write

Secreto de firma nuevo, devuelto una sola vez. Durante overlap_minutes las entregas llevan las dos firmas separadas por coma, así que puedes desplegar sin corte. Ver Firmas.

ParámetroDóndeTipoDescripción
id *pathuuidId del webhook.
overlap_minutes *bodyintegerObligatorio. 0–1440 minutos de solape; 0 = el anterior deja de valer ya.

Petición

curl
curl -X POST https://wearetransfers.com/api/v1/webhooks/3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f/rotate-secret \
  -H "Authorization: Bearer $WAT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"overlap_minutes": 60}'

Respuesta

json
{
  "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
  "secret": "whsec_…",
  "previous_secret_valid_until": "2026-09-21T11:00:00.000Z"
}
GET/v1/webhooks/{id}/deliveries
webhooks:read

Las últimas entregas del destino, de la más reciente a la más antigua. Sin cursor.

ParámetroDóndeTipoDescripción
id *pathuuidId del webhook.
limitqueryinteger1–100, por defecto 25. Más de 100 se recorta a 100; menos de 1 o no entero es 400.

Petición

curl
curl "https://wearetransfers.com/api/v1/webhooks/3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f/deliveries?limit=2" \
  -H "Authorization: Bearer $WAT_API_KEY"

Respuesta

json
{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5e",
      "event_id": "8b7a6c5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
      "event_type": "booking.completed",
      "status": "failed",
      "attempt": 2,
      "max_attempts": 8,
      "next_retry_at": "2026-09-18T10:44:10.000Z",
      "last_status": 503,
      "last_error": "HTTP 503",
      "last_duration_ms": 1804,
      "delivered_at": null,
      "created_at": "2026-09-18T10:42:08.000Z"
    },
    {
      "id": "6d2e1f0a-9b8c-4d7e-a6f5-4c3b2a1d0e9f",
      "event_id": "8b7a6c5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
      "event_type": "booking.completed",
      "status": "succeeded",
      "attempt": 1,
      "max_attempts": 8,
      "next_retry_at": "2026-09-18T10:42:10.000Z",
      "last_status": 200,
      "last_error": null,
      "last_duration_ms": 212,
      "delivered_at": "2026-09-18T10:42:10.000Z",
      "created_at": "2026-09-18T10:42:08.000Z"
    }
  ]
}

El objeto Webhook

CampoTipoQué es
iduuidIdentificador.
urlstringDestino https.
eventsstring[]Tipos suscritos o ["*"].
activebooleanSi recibe entregas.
descriptionstring | nullTexto libre.
consecutive_failuresintegerFallos seguidos. A 100 se desactiva solo.
disabled_at · disabled_reasondate-time | null · string | nullCuándo y por qué se desactivó.
secretstringSolo en la respuesta de creación. whsec_….

El objeto WebhookDelivery

CampoTipoQué es
iduuidId de la entrega (X-WAT-Delivery).
event_id · event_typeuuid · EventTypeEl evento entregado.
statuspending | delivering | succeeded | failed | deadfailed se reintentará; dead ya no.
attempt · max_attemptsintegerIntentos hechos y tope (8; 3 para 4xx permanentes).
next_retry_atdate-time | nullCuándo se reintentará.
last_status · last_error · last_duration_ms…Resultado del último intento. last_status es null en timeout o error de red.
delivered_atdate-time | nullCuándo se entregó (2xx).
Errores propios

Una URL no permitida, un evento desconocido o el undécimo webhook responden 400 validation_error con details.field:

json
{
  "error": {
    "code": "validation_error",
    "message": "Ese destino no está permitido",
    "request_id": "req_9f8e7d6c5b4a39281706",
    "details": {
      "field": "url"
    }
  }
}
Referencia: endpoints de webhooks · API de WAT