POSThttps://api.veriko.mx/v1/webhooks

Crear un endpoint webhook para recibir eventos

Audiencia
public
Autenticación
API key
Permiso
webhooks:create
Guía de uso →

Registra un endpoint HTTPS que recibirá los eventos suscritos. La URL debe resolver a una dirección pública: localhost y los rangos privados se rechazan.

Cada endpoint puede suscribirse a diferentes eventos, entre ellos:

  • Eventos validation.*: Avisan de cada veredicto de una validación y de cada paso de sus reintentos automáticos (p. ej: validation.completed, validation.error, etc).
  • Evento validation.returned: avisa cuando una validación que ya había salido valid pasa después a returned porque Banxico reportó la devolución; no se emite al crear la validación, donde el evento es validation.completed. Para recibirlo hay que suscribirse a él además de a validation.completed.
  • Eventos billing.*: No producen entregas hasta que haya algún movimiento en la suscripción del usuario (p. ej: billing.subscription_canceled, billing.payment_succeeded, cuotas de uso, etc).

Si se alcanza el tope de endpoints registrados, la creación responde con un estado HTTP 422 (con webhook_limit_reached en el cuerpo) y con el valor del límite en el campo meta.limit.

Parámetros
ParámetroTipoObligatorioDescripción
urlstring (uri) (?–2048)obligatorio

URL receptora del webhook. Se rechaza si resuelve a una dirección privada o si pasa de 2048 caracteres y, en producción, también si no usa HTTPS.

p. ej. https://example.com/webhooks/entregas
eventsarray<string> (elementos: 1–10)obligatorio

Eventos a los que se suscribe el endpoint webhook. Entre 1 y 10.

descriptionstring | nullanulable (?–255)opcional

Etiqueta libre para distinguir el endpoint webhook de los demás. null la omite; más de 255 caracteres responde 422 webhook_description_too_long.

p. ej. Alta de pagos en el ERP
Petición
curl -X POST 'https://api.veriko.mx/v1/webhooks' \
  -H 'Authorization: Bearer veriko_••••' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://webhook.example.com/platform",
    "events": [
      "validation.completed",
      "validation.failed",
      "validation.error",
      "billing.payment_succeeded",
      "billing.payment_failed"
    ]
  }'

Ejemplo en Python — próximamente.

Ejemplo en JavaScript — próximamente.

Ejemplo en PHP — próximamente.

Respuesta 201WebhookEndpoint — Endpoint webhook creado. El campo `secret` aparece **solo en esta respuesta** y no puede volver a consultarse: es el que verifica la firma `X-Platform-Signature: sha256=<hex>` que acompaña a cada entrega.
CampoTipoDescripción
type*string

Tipo de recurso JSON:API. Siempre webhook_endpoint.

p. ej. webhook_endpoint
id*string (uuid)

Identificador único del endpoint webhook (UUID v4).

p. ej. a1b2c3d4-e5f6-7890-abcd-ef0123456789
attributes*object

Datos del endpoint webhook (URL receptora, eventos suscritos, estado y secreto).

url*string (uri)

URL receptora del webhook. En producción se rechaza si no usa HTTPS, si resuelve a una dirección privada o si pasa de 2048 caracteres.

p. ej. https://example.com/webhooks/entregas
events*array (elementos: 1–10, elementos únicos)

Eventos a los que se suscribe el endpoint webhook. Entre 1 y 10.

description*string | nullanulable

Etiqueta libre para distinguir el endpoint webhook de los demás.

p. ej. Alta de pagos en el ERP
status*string

Estado actual del webhook — active: Recibe entregas; disabled: Se desactivó manualmente; auto_disabled: Se desactivó automáticamente tras superar el umbral de fallos consecutivos.

p. ej. active
consecutive_failures*integer

Cantidad de fallos consecutivos. Se reinicia al primer éxito.

p. ej. 0
last_delivery_at*TimestampUTC | null

Fecha y hora de la última entrega exitosa, en ISO 8601 UTC. null cuando el endpoint aún no completó ninguna entrega.

secretstring

Clave compartida para verificar firmas. Solo presente en la respuesta de creación y de rotación del endpoint; se omite en cualquier otra respuesta. Se usa para validar las cabeceras X-Webhook-Signature y X-Webhook-Signature-Timestamped de cada entrega.

p. ej. a0b1c2d3e4f5061728394a5b6c7d8e9f00112233445566778899aabbccddeeff
secret_hintstring

Últimos 4 caracteres del secret, con el prefijo .... Presente en cualquier respuesta donde el secret completo está oculto.

p. ej. ...4f2a
created_at*string (date-time)

Timestamp ISO 8601 en UTC con sufijo Z explícito; por ejemplo, "2026-05-01T05:14:38Z". Los campos *_at, *_end, *_start y *_date adoptan esta forma. meta.datetime describe el mismo contrato en la respuesta.

p. ej. 2026-05-01T05:14:38Z
updated_at*string (date-time)

Timestamp ISO 8601 en UTC con sufijo Z explícito; por ejemplo, "2026-05-01T05:14:38Z". Los campos *_at, *_end, *_start y *_date adoptan esta forma. meta.datetime describe el mismo contrato en la respuesta.

p. ej. 2026-05-01T05:14:38Z
Códigos de respuestaPOST /v1/webhooks
CódigoClaseDescripciónCuerpo
2012xxEndpoint webhook creado. El campo secret aparece solo en esta respuesta y no puede volver a consultarse: es el que verifica la firma X-Webhook-Signature: sha256=<hex> que acompaña a cada entrega.WebhookEndpoint
4004xxEl cuerpo de la petición está vacío o no es JSON válido, o la URL apunta a una dirección no pública.ErrorResponse
4014xxSe requiere autenticación o las credenciales son inválidasErrorResponse
4034xxPermisos insuficientesErrorResponse
4134xxEl cuerpo de la petición supera el tamaño máximo admitido (body_too_large).ErrorResponse
4224xxLa URL, la lista de eventos o description no superan la validación, o la cuenta de usuario alcanzó su tope de endpoints. webhook_url_invalid_type y webhook_description_invalid_type aparecen cuando el campo llega con un tipo distinto de cadena de texto; webhook_description_too_long cuando description excede 255 caracteres. Todo error de campo trae source.pointer.ErrorResponse
4294xxLímite de tasa excedidoErrorResponse
Errores de POST /v1/webhooks
CódigoClaveEjemplo
400body_empty

El cuerpo de la petición está vacío.

Envelope
meta.request_id
e6f7a2b3c4d55d4c3b2a7f6e
400invalid_json

El cuerpo no es JSON válido.

Envelope
meta.request_id
f7a2b3c4d5e66e5d4c3b2a7f
400url_dns_failed

No se pudo resolver el nombre de la dirección.

Envelope
meta.request_id
d4e5f6a1b2c44c2b1a6f5e4d
400url_ssrf_blocked

La URL indicada resuelve a una dirección no pública.

Envelope
meta.request_id
d4e5f6a1b2c55c2b1a6f5e4d
401unauthorized

Credenciales de autenticación ausentes o inválidas.

Envelope
meta.request_id
c4d5e6f7a8b99b8a7f6e5d4c
403permission_denied

No tienes permiso para acceder a este recurso.

Envelope
meta.request_id
d5e6f7a8b9c00c9b8a7f6e5d
413body_too_large

El cuerpo de la petición es demasiado grande.

Envelope
meta.request_id
1a2b3c4d5e6ff6e5d4c3b2a1
422validation_error

El campo url es obligatorio.

Envelope
source.pointer
/data/attributes/url
meta.request_id
b4c5d6e7f8a99a8f7e6d5c4b
422webhook_description_too_long

El campo description no debe exceder 255 caracteres.

Envelope
source.pointer
/data/attributes/description
meta.request_id
e6f7a2b3c4d55d4c3b2a7f6e
422webhook_event_invalid

El evento indicado no existe. El evento rechazado viene en meta.event.

Envelope
source.pointer
/data/attributes/events
meta.request_id
c4d5e6f7a2b33b2a7f6e5d4c
422webhook_events_required

El endpoint debe suscribirse a al menos un evento.

Envelope
source.pointer
/data/attributes/events
meta.request_id
a2b3c4d5e6f77f6e5d4c3b2a
422webhook_events_too_many

Un endpoint admite como máximo 10 eventos.

Envelope
source.pointer
/data/attributes/events
meta.request_id
b3c4d5e6f7a22a7f6e5d4c3b
422webhook_limit_reached

Se alcanzó el número máximo de endpoints permitidos. El tope aplicado viene en meta.limit.

Envelope
meta.request_id
d5e6f7a2b3c44c3b2a7f6e5d
422webhook_url_invalid_format

La URL no tiene un formato válido.

Envelope
source.pointer
/data/attributes/url
meta.request_id
c3d4e5f6a1b22b1a6f5e4d3c
422webhook_url_not_https

La URL debe usar HTTPS.

Envelope
source.pointer
/data/attributes/url
meta.request_id
d4e5f6a1b2c33c2b1a6f5e4d
422webhook_url_required

El campo url es obligatorio.

Envelope
source.pointer
/data/attributes/url
meta.request_id
a1b2c3d4e5f66f5e4d3c2b1a
422webhook_url_too_long

La URL no puede exceder 2 048 caracteres.

Envelope
source.pointer
/data/attributes/url
meta.request_id
b2c3d4e5f6a11a6f5e4d3c2b
429rate_limit_exceeded

Límite de peticiones excedido. Inténtalo de nuevo en 45 segundos.

Envelope
meta.request_id
f7a8b9c0d1e22e1d0c9b8a7f
Cabeceras de respuesta
  • Retry-After: integer — Segundos a esperar antes de reintentar. Coincide con la ventana de rate-limit del endpoint (típicamente 60s para listas, 1-5s para operaciones idempotentes en vuelo).
  • X-RateLimit-Limit: integer — Límite de solicitudes configurado para este bucket. Se emite en cada 429 y, en la API autenticada, también en las respuestas correctas, donde es el tope por clave del plan de la cuenta.
  • X-RateLimit-Remaining: integer — Solicitudes restantes en la ventana actual. Siempre 0 en el momento del 429; en una respuesta correcta de la API autenticada es lo que queda del tope por clave.
  • X-RateLimit-Reset: integer — Unix epoch absoluto (segundos) en que se reinicia la ventana. Se emite en cada 429, junto con Retry-After, y en las respuestas correctas de la API autenticada. Puede existir sobreescritura por endpoint (p. ej. `rate_limited_login`).