API Webhooks
Twórz podpisane endpointy webhooków Rivya API, weryfikuj podpisy dostaw, przeglądaj próby dostaw i wysyłaj bezpieczne zdarzenia testowe.
Ostatni przegląd: 2026/05/11
Używaj API webhooks, gdy Twoja integracja potrzebuje, aby Rivya powiadamiała Twój serwer po osiągnięciu stanu końcowego przez generowanie Public API.
Polling GET /api/v1/generations/{taskId} nadal jest obsługiwany. Webhooki dodają podpisane callbacki dla systemów produkcyjnych, które wolą dostarczanie zdarzeń.
Wymagany Zakres
Zarządzanie webhookami wymaga klucza API z:
webhooks:manageNowe klucze utworzone w Ustawieniach domyślnie zawierają ten zakres.
Utwórz Endpoint
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"]
}'Odpowiedź zawiera signing_secret tylko raz:
{
"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
}Przechowuj pełny sekret na swoim serwerze. Jeśli go utracisz, wywołaj endpoint rotacji i zaktualizuj odbiornik.
Reguły URL
URL-e endpointów muszą używać HTTPS. Rivya odrzuca URL-e z poświadczeniami, fragmentami, nazwami localhost, adresami sieci lokalnej, prywatnymi zakresami IP, adresami loopback i adresami zarezerwowanymi.
Rivya zawsze wysyła:
POSTContent-Type: application/jsonbez niestandardowych headerów żądania kontrolowanych przez użytkownika
bez automatycznego podążania za przekierowaniami
krótki timeout dostawy
Zdarzenia
Bieżące typy zdarzeń:
generation.succeededgeneration.failed
Payloady webhooków używają tego samego publicznego serializera generowania co endpoint statusu.
{
"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
}
}
}Headery Dostawy
Każda dostawa zawiera:
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_...Wejście podpisu:
${timestamp}.${rawBody}Algorytm:
HMAC-SHA256 with the endpoint signing secretOdrzucaj żądania ze zbyt starymi timestampami. Pięciominutowa tolerancja jest praktycznym domyślnym ustawieniem.
Weryfikacja 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"));
}Weryfikacja 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)Zarządzaj Endpointami
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} wyłącza endpoint. Nie usuwa historii dostaw.
Rekordy Dostaw
Wyświetl ostatnie zdarzenia:
GET /api/v1/webhook-eventscurl https://rivya.ai/api/v1/webhook-events \
-H "Authorization: Bearer rvya_sk_..."Wyświetl próby dostawy dla endpointu:
GET /api/v1/webhooks/{endpointId}/deliveriescurl https://rivya.ai/api/v1/webhooks/whend_.../deliveries \
-H "Authorization: Bearer rvya_sk_..."Rekordy dostaw zawierają status, status HTTP, numer próby, request id, czas trwania, skrócony fragment odpowiedzi i publiczne pola błędu.
Zdarzenie Testowe
Wyślij bezpieczny payload testowy:
POST /api/v1/webhooks/{endpointId}/testcurl -X POST https://rivya.ai/api/v1/webhooks/whend_.../test \
-H "Authorization: Bearer rvya_sk_..."Zdarzenie testowe używa webhook.test. Nie tworzy zadania generowania, nie zużywa kredytów i nie zawiera prawdziwego URL wyniku.
Polityka Ponowień
Rivya traktuje HTTP 2xx jako sukces.
Niepowodzenia obejmują błędy sieci, timeout, odpowiedzi przekierowania i odpowiedzi inne niż 2xx. Rivya ponawia maksymalnie pięć prób:
natychmiast
po 1 minucie
po 5 minutach
po 30 minutach
po 2 godzinach
Po ostatniej próbie zdarzenie jest oznaczane jako failed.
Niepowodzenia dostawy webhooka nie zmieniają statusu generowania, kredytów, zwrotów ani historii zadania.
Checklista Bezpieczeństwa
Zweryfikuj podpis HMAC przed parsowaniem logiki biznesowej.
Odrzucaj zbyt stare timestampy.
Traktuj zdarzenia testowe oddzielnie od zdarzeń generowania.
Nie loguj pełnych signing secrets.
Zwracaj
2xxdopiero po tym, jak odbiornik zaakceptuje zdarzenie.Zachowaj polling jako fallback do uzgadniania stanu.
