Webhooks de API
Crea endpoints de webhook firmados para la API de Rivya, verifica firmas de entrega, revisa intentos de entrega y envía eventos de prueba seguros.
Última revisión el 11 de mayo de 2026
Usa webhooks de API cuando tu integración necesite que Rivya notifique a tu servidor después de que una generación de Public API llegue a un estado terminal.
La consulta periódica mediante GET /api/v1/generations/{taskId} sigue disponible. Los webhooks añaden avisos firmados para sistemas de producción que prefieren recibir eventos.
Permiso requerido
La gestión de webhooks requiere una clave de API con:
webhooks:manageLas claves nuevas creadas en Ajustes incluyen este permiso de forma predeterminada.
Crear un destino
POST /api/v1/webhookscurl https://rivya.ai/api/v1/webhooks \
-H "Authorization: Bearer rvya_sk_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Production webhook",
"url": "https://example.com/rivya/webhook",
"event_types": ["generation.succeeded", "generation.failed"]
}'La respuesta incluye signing_secret solo una vez:
{
"id": "whend_...",
"object": "webhook_endpoint",
"name": "Production webhook",
"url": "https://example.com/rivya/webhook",
"event_types": ["generation.succeeded", "generation.failed"],
"status": "active",
"secret_preview": "whsec_12...abc123",
"signing_secret": "whsec_...",
"last_success_at": null,
"last_failure_at": null,
"failure_count": 0,
"created_at": "2026-05-11T00:00:00.000Z",
"updated_at": "2026-05-11T00:00:00.000Z",
"disabled_at": null,
"revoked_at": null
}Guarda el secreto completo en tu servidor. Si lo pierdes, llama a la ruta de rotación y actualiza el receptor.
Reglas de URL
Las URL de destino deben usar HTTPS. Rivya rechaza direcciones con credenciales, fragmentos, nombres localhost, redes locales, rangos de IP privadas, direcciones de bucle invertido y direcciones reservadas.
Rivya siempre envía:
POSTContent-Type: application/jsonsin headers de solicitud personalizados controlados por el usuario
sin seguimiento automático de redirecciones
un timeout de entrega corto
Eventos
Tipos de evento actuales:
generation.succeededgeneration.failed
Las cargas de los webhooks usan el mismo serializador público de generación que la ruta de estado.
{
"id": "evt_...",
"type": "generation.succeeded",
"api_version": "2026-05-11",
"created_at": "2026-05-11T00:00:00.000Z",
"data": {
"generation": {
"id": "task_public_id",
"status": "succeeded",
"model": "z-image",
"reserved_credits": 1,
"final_credits": 1,
"created_at": "2026-05-11T00:00:00.000Z",
"updated_at": "2026-05-11T00:01:00.000Z",
"result": {
"primary_url": "https://...",
"urls": ["https://..."]
},
"error": null
}
}
}Headers de entrega
Cada entrega incluye:
Rivya-Webhook-Id: evt_...
Rivya-Webhook-Timestamp: 1778467200
Rivya-Webhook-Signature: v1=<hex-hmac-sha256>
Rivya-Webhook-Attempt: 1
Rivya-Webhook-Endpoint-Id: whend_...
Rivya-Request-Id: req_...Entrada de firma:
${timestamp}.${rawBody}Algoritmo:
HMAC-SHA256 con el secreto de firma del destinoRechaza solicitudes con timestamps obsoletos. Una tolerancia de cinco minutos es un valor práctico por defecto.
Verificación en JavaScript
import crypto from "node:crypto";
function verifyRivyaWebhook({ rawBody, headers, signingSecret }) {
const timestamp = headers["rivya-webhook-timestamp"];
const signature = headers["rivya-webhook-signature"] || "";
const actual = signature.split(",").find((part) => part.startsWith("v1="))?.slice(3);
const expected = crypto
.createHmac("sha256", signingSecret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
if (!actual) return false;
return crypto.timingSafeEqual(Buffer.from(actual, "hex"), Buffer.from(expected, "hex"));
}Verificación en Python
import hmac
import hashlib
def verify_rivya_webhook(raw_body: str, headers: dict, signing_secret: str) -> bool:
timestamp = headers.get("rivya-webhook-timestamp", "")
signature = headers.get("rivya-webhook-signature", "")
actual = next((part[3:] for part in signature.split(",") if part.startswith("v1=")), "")
expected = hmac.new(
signing_secret.encode(),
f"{timestamp}.{raw_body}".encode(),
hashlib.sha256,
).hexdigest()
return bool(actual) and hmac.compare_digest(actual, expected)Gestionar endpoints
GET /api/v1/webhooks
GET /api/v1/webhooks/{endpointId}
PATCH /api/v1/webhooks/{endpointId}
DELETE /api/v1/webhooks/{endpointId}
POST /api/v1/webhooks/{endpointId}/rotate-secretcurl https://rivya.ai/api/v1/webhooks \
-H "Authorization: Bearer rvya_sk_..."
curl https://rivya.ai/api/v1/webhooks/whend_... \
-H "Authorization: Bearer rvya_sk_..."
curl -X PATCH https://rivya.ai/api/v1/webhooks/whend_... \
-H "Authorization: Bearer rvya_sk_..." \
-H "Content-Type: application/json" \
-d '{"status":"disabled"}'
curl -X POST https://rivya.ai/api/v1/webhooks/whend_.../rotate-secret \
-H "Authorization: Bearer rvya_sk_..."DELETE /api/v1/webhooks/{endpointId} desactiva el destino. No elimina el historial de entregas.
Registros de entrega
Lista eventos recientes:
GET /api/v1/webhook-eventscurl https://rivya.ai/api/v1/webhook-events \
-H "Authorization: Bearer rvya_sk_..."Muestra los intentos de entrega de un destino:
GET /api/v1/webhooks/{endpointId}/deliveriescurl https://rivya.ai/api/v1/webhooks/whend_.../deliveries \
-H "Authorization: Bearer rvya_sk_..."Los registros de entrega incluyen estado, estado HTTP, número de intento, request id, duración, fragmento truncado de la respuesta y campos de error públicos.
Evento de prueba
Envía un payload de prueba seguro:
POST /api/v1/webhooks/{endpointId}/testcurl -X POST https://rivya.ai/api/v1/webhooks/whend_.../test \
-H "Authorization: Bearer rvya_sk_..."El evento de prueba usa webhook.test. No crea una tarea de generación, no consume créditos y no incluye una URL de resultado real.
Política de reintentos
Rivya trata HTTP 2xx como éxito.
Los fallos incluyen errores de red, timeout, respuestas de redirección y respuestas que no son 2xx. Rivya reintenta hasta cinco veces:
inmediatamente
después de 1 minuto
después de 5 minutos
después de 30 minutos
después de 2 horas
Después del intento final, el evento se marca como failed.
Los fallos de entrega de webhook no cambian el estado de la generación, los créditos, los reembolsos ni el historial de la tarea.
Checklist de seguridad
Verifica la firma HMAC antes de procesar la lógica de negocio.
Rechaza timestamps obsoletos.
Trata los eventos de prueba por separado de los eventos de generación.
No registres secretos de firma completos en logs.
Devuelve
2xxsolo después de que tu receptor haya aceptado el evento.Mantén la consulta periódica como respaldo para la conciliación.
