Firmar y verificar webhooks
Cualquiera puede enviar una solicitud POST a su endpoint fingiendo ser un socio confiable, y cualquiera del otro lado puede alegar que su webhook nunca llegó. Este endpoint coloca una firma criptográfica en los payloads que usted envía y verifica los que recibe, para que ambas partes puedan demostrar qué se envió realmente y que nada se alteró en el trayecto.
Ejecutar — gratis
Corre en su navegador. Gratis y sin límite: sus datos no salen de esta página.
El problema de un webhook sin firma
Un endpoint que acepta cualquier cuerpo POST como verdadero es un endpoint que cualquiera puede suplantar: un falso evento de pago exitoso, una actualización de pedido falsificada, una solicitud reproducida a partir de un payload capturado. Y del lado de quien envía, sin una firma que mostrar, un socio puede negar que usted haya enviado un evento, dejando un ticket de soporte sin forma de resolverse. dev.webhook_sign existe porque 'confiar en el payload' dejó de ser un modelo de seguridad viable en el momento en que los webhooks se volvieron infraestructura crítica.
Dos direcciones, un solo endpoint
Envíe POST a /dev/webhook-sign con un payload y la intención de firmarlo, y la tarea devuelve una firma que usted adjunta a los encabezados de la solicitud saliente antes de entregarla. Envíe al mismo endpoint un payload entrante junto con la firma recibida y la intención de verificarlo, y este revisa la firma contra el payload e informa si es válida, si fue alterada o si expiró. En ambos casos recibe un task_id de inmediato, y el resultado —una firma o un veredicto de verificación— llega por webhook firmado o mediante un enlace firmado válido por 24 horas.
Por qué firmar no es lo mismo que cifrar
Una firma no oculta el payload; demuestra quién lo envió y que no cambió después de firmarse, usando un secreto compartido o un par de claves junto con un hash del contenido del mensaje. Es el mismo principio detrás de los webhooks firmados con HMAC que las plataformas más grandes han usado durante más de una década: quien recibe recalcula la firma a partir del payload crudo y la compara con la que llegó, y cualquier discrepancia significa que algo se alteró, que se excedió una ventana de tiempo, o que en realidad nunca lo envió quien dice haberlo hecho.
Cómo encaja la verificación en un flujo real
Un receptor de webhooks que verifica antes de procesar cierra toda una categoría de intentos de suplantación sin agregar una latencia relevante, ya que la verificación misma es rápida y se cobra a una tarifa plana de $0.002 por solicitud sin costo alguno cuando falla. Los equipos que manejan muchas integraciones de webhooks suelen dirigir cada payload entrante a través de la verificación como primer paso automatizado, rechazando lo que no pasa la revisión antes de que llegue a la lógica de negocio; aplicar esa misma disciplina del lado saliente significa que cada socio que recibe sus webhooks puede confirmar por sí mismo que realmente vienen de usted.
Qué puede hacer con ella
Autenticidad de webhooks salientes
Una plataforma SaaS firma cada webhook que envía a sus clientes para que ellos puedan verificar que el evento realmente se originó en la plataforma antes de actuar sobre él.
Verificación de webhooks de pago entrantes
Una tienda en línea verifica la firma de cada webhook de estado de pago entrante antes de actualizar un pedido, rechazando cualquiera que no pase la revisión.
Confianza mutua entre socios de API
Dos empresas que intercambian webhooks en ambas direcciones firman lo que envían y verifican lo que reciben, cerrando la puerta a disputas sobre eventos faltantes o alterados.
Prevención de ataques de reproducción
Una integración fintech verifica tanto la firma como una ventana de tiempo en los webhooks entrantes, rechazando payloads que parecen válidos pero llegan mucho después de haberse firmado.
Preguntas frecuentes
¿Cómo firmo o verifico un webhook con esta API?
Envíe por POST el payload y la intención de firmar o verificar a /dev/webhook-sign, guarde el task_id devuelto y reciba la firma o el resultado de la verificación por webhook o mediante un enlace firmado válido por 24 horas.
¿Es gratis la API para firmar webhooks?
No, no hay plan gratuito ni prueba; cuesta una tarifa plana de $0.002 por solicitud, y una tarea fallida nunca se cobra.
¿Cuál es la diferencia entre firmar y cifrar un webhook?
Firmar demuestra quién envió el payload y que no fue alterado, dejando el contenido legible; no lo oculta como sí haría el cifrado.
¿Puede verificar webhooks de cualquier proveedor?
Verifica según el esquema de firma y el secreto o clave que usted proporcione con la solicitud, así que funciona con cualquier proveedor cuyo método de firma pueda indicar.
¿Protege contra webhooks reproducidos o repetidos?
La verificación puede incluir una revisión de marca de tiempo junto con la firma, así que un payload reproducido mucho después de su ventana de firma queda marcado aunque la firma en sí sea técnicamente válida.
¿Puedo firmar o verificar webhooks en lote?
Sí, envíe una tarea asíncrona por payload y reciba cada resultado por webhook a medida que termine, lo cual encaja bien con tráfico entrante o saliente de alto volumen.
¿Qué pasa si una firma no coincide?
El resultado de la verificación informa la discrepancia con claridad en vez de dejarla pasar en silencio, para que su flujo pueda rechazar el payload antes de que llegue a la lógica de negocio.
¿Ya está disponible este endpoint?
Sí, /dev/webhook-sign está disponible y aceptando solicitudes ahora mismo.
Para desarrolladores — acceso por API
Todo lo de esta página está disponible por programación. Esta sección es para equipos que quieren integrarlo en sus sistemas; el resto puede usar la herramienta de arriba sin más.
Endpoint de API
¿Prefiere automatizarlo? Un POST autenticado crea la tarea; el resultado llega por webhook o enlace firmado. La misma capacidad también se ejecuta aquí en la web, y pronto desde nuestra app, el email y Telegram.
Llámela desde su stack
curl -X POST https://api.kit.forhosting.com/dev/webhook-sign \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/dev/webhook-sign", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"input": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/webhook-sign",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"input": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/webhook-sign", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"input":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"input":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/webhook-sign", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Ejemplo de solicitud
{
"input": "…"
}Ejemplo de respuesta
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.webhook_sign",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}La API es asíncrona: la llamada devuelve un task_id al instante y el resultado llega por webhook. El polling está limitado a 1 req/s por tarea.
Precio
Precio publicado — sin tokens ni créditos inventados. Una tarea fallida no se cobra.
Errores
| HTTP | Código | Significado |
|---|---|---|
401 | unauthorized | API key ausente o inválida. |
402 | insufficient_balance | El saldo no cubre el precio de la tarea. |
404 | unknown_type | El tipo de tarea no existe. |
429 | rate_limited | Demasiadas peticiones. Use el webhook en vez de sondear. |