---
title: "Probar un webhook (ping)"
method: POST
path: "/webhooks/{id}/test"
tags: ["webhooks"]
---

# Probar un webhook (ping)

`POST /webhooks/{id}/test`

## Request

- Base URL: `https://api.enviadores.com.mx/api/v1`
- URL: `https://api.enviadores.com.mx/api/v1/webhooks/{id}/test`
- Auth: HTTP bearer

Entrega un `{"event":"ping"}` firmado **de forma síncrona** (mismos headers y misma firma que un evento real; `data` = `{webhook_id}`) y reporta el resultado. Un ping fallido NO cuenta para la desactivación automática — repítelo con libertad mientras ajustas el endpoint. Sin cuerpo. Requiere scope `webhooks:write`.

## Path parameters

- `id` string, required

## Response `200`

Resultado del ping (200 aunque el endpoint haya fallado — mira `delivered`).

- object
  - `success` unknown, required
  - `data` object, required
    - `delivered` boolean, required: `true` si el endpoint respondió 2xx dentro de 10 s.
    - `response_status` integer, nullable, required: Status HTTP recibido; `null` si no hubo respuesta (timeout, TLS, DNS).
    - `error` 'timeout' | 'connection failed' | 'non-2xx status' | 'endpoint rejected' | 'null', nullable, required: Clase del fallo, deliberadamente gruesa (el detalle de red no se expone para que el ping no sirva como sonda de puertos): `timeout`, `connection failed` (rechazo/reset/TLS/DNS), `non-2xx status` (ver `response_status`), `endpoint rejected` (la URL ya no pasa la política); `null` si se entregó.
    - `event_id` string, required: `evt_` + 24 hex — el `id` del cuerpo enviado y el header `X-Enviadores-Delivery`.
  - `requestId` string, required: Correlación de logs; también en el header `X-Request-Id`.

## Other responses

- `401`: `UNAUTHORIZED` — credencial Bearer ausente/mal formada o llave desconocida/revocada (respuesta idéntica en ambos casos).
- `403`: `INSUFFICIENT_SCOPE` — a la llave le falta el scope requerido · `PDV_NOT_ALLOWED` — violación del carril X-PDV-ID. Nota de orden: el limitador por llave corre ANTES del gate de scope, así que una petición con scope incorrecto y el bucket agotado responde `429 RATE_LIMITED` (el 429 tiene precedencia sobre este 403).
- `404`: `NOT_FOUND` — no existe, es de otra cuenta o de otro modo (respuesta idéntica).
- `409`: `WEBHOOK_DISABLED` — el webhook fue desactivado automáticamente (`details.disabled_reason`); elimínalo y regístralo de nuevo.
- `429`: `RATE_LIMITED` — bucket de la llave agotado. Espera `Retry-After` s (`details.retry_after_ms` para el hint fino). El limitador corre antes del gate de scope, por lo que un 429 tiene precedencia sobre un 403 `INSUFFICIENT_SCOPE`.
- `500`: `SERVER_ERROR` — falla interna (p. ej. lectura de base de datos). Es transitoria; reintenta con backoff.

---

[API](https://skmtc.dev/enviadores/apis/enviadores-public-api.md) · [All operations](https://skmtc.dev/enviadores/apis/enviadores-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/enviadores/apis/enviadores-public-api/revisions/3633f08c889c?raw)
