Documentație Rivya AI

API Webhooks

Creează endpointuri webhook Rivya API semnate, verifică semnaturile livrarilor, inspectează incercarile de livrare și trimite evenimente de test sigure.

Ultima revizuire la 2026/05/11

Folosește webhookuri API când integrarea ta are nevoie ca Rivya să notifice serverul tău după ce o generare Public API ajunge într-o stare terminala.

Pollingul GET /api/v1/generations/{taskId} rămâne acceptat. Webhookurile adaugă callbackuri semnate pentru sisteme de producție care prefera livrarea de evenimente.

Permisiunea necesară

Gestionarea webhookurilor necesită o cheie API cu:

webhooks:manage

Cheile noi create în Setări includ implicit această permisiune.

Creează endpoint

POST /api/v1/webhooks
curl 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"]
  }'

Răspunsul include signing_secret o singură data:

{
  "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
}

Stocheaza secretul complet pe serverul tău. Dacă îl pierzi, apelează endpointul de rotatie și actualizeaza serverul receptor.

Reguli URL

URL-urile endpointurilor trebuie să fie HTTPS. Rivya respinge URL-uri cu credentiale, fragmente, nume localhost, adrese de retea locală, intervale IP private, adrese loopback și adrese rezervate.

Rivya trimite întotdeauna:

  • POST

  • Content-Type: application/json

  • fără headere de cerere personalizate controlate de utilizator

  • fără urmarire automata a redirecturilor

  • un timeout scurt de livrare

Evenimente

Tipuri curente de evenimente:

  • generation.succeeded

  • generation.failed

Payloadurile webhook folosesc același serializer public de generare ca endpointul de status.

{
  "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
    }
  }
}

Headere de livrare

Fiecare livrare include:

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_...

Date pentru semnătură:

${timestamp}.${rawBody}

Algoritm:

HMAC-SHA256 cu secretul de semnare al endpointului

Respinge cererile cu timestampuri vechi. O toleranță de cinci minute este o valoare practică implicită.

Verificare 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"));
}

Verificare 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)

Gestionează endpointuri

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-secret
curl 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} dezactiveaza endpointul. Nu sterge istoricul livrarilor.

Înregistrări de livrare

Listeaza evenimente recente:

GET /api/v1/webhook-events
curl https://rivya.ai/api/v1/webhook-events \
  -H "Authorization: Bearer rvya_sk_..."

Listeaza incercarile de livrare pentru un endpoint:

GET /api/v1/webhooks/{endpointId}/deliveries
curl https://rivya.ai/api/v1/webhooks/whend_.../deliveries \
  -H "Authorization: Bearer rvya_sk_..."

Inregistrarile de livrare includ status, status HTTP, numarul incercarii, ID-ul cererii, durata, fragment trunchiat de răspuns și campuri publice de eroare.

Eveniment de test

Trimite un payload de test sigur:

POST /api/v1/webhooks/{endpointId}/test
curl -X POST https://rivya.ai/api/v1/webhooks/whend_.../test \
  -H "Authorization: Bearer rvya_sk_..."

Evenimentul de test folosește webhook.test. Nu creează o sarcină de generare, nu consumă credite și nu include un URL real de rezultat.

Politica de reincercare

Rivya tratează HTTP 2xx ca succes.

Eșecurile includ erori de retea, timeout, răspunsuri redirect și răspunsuri non-2xx. Rivya reîncearcă până la cinci încercări:

  • imediat

  • după 1 minut

  • după 5 minute

  • după 30 de minute

  • după 2 ore

După încercarea finală, evenimentul este marcat failed.

Eșecurile de livrare webhook nu schimbă statusul generarii, creditele, rambursările sau istoricul sarcinii.

Checklist de securitate

  • Verifică semnatura HMAC înainte să parsezi logică de business.

  • Respinge timestampurile vechi.

  • Tratează evenimentele de test separat de evenimentele de generare.

  • Nu loga secretele complete de semnare.

  • Returneaza 2xx doar după ce serverul receptor a acceptat evenimentul.

  • Păstrează pollingul ca opțiune de rezerva pentru reconciliere.

Pagini asociate