Έγγραφα Rivya AI

API Webhooks

Δημιουργήστε υπογεγραμμένα Rivya API webhook endpoints, επαληθεύστε delivery signatures, ελέγξτε delivery attempts και στείλτε ασφαλή test events.

Τελευταίος έλεγχος στις 2026/05/11

Χρησιμοποιήστε API webhooks όταν η ενσωμάτωσή σας χρειάζεται το Rivya να ειδοποιεί τον server σας αφού ένα Public API generation φτάσει σε terminal state.

Το polling με GET /api/v1/generations/{taskId} εξακολουθεί να υποστηρίζεται. Τα webhooks προσθέτουν υπογεγραμμένα callbacks για production συστήματα που προτιμούν event delivery.

Απαιτούμενο scope

Η διαχείριση webhooks απαιτεί API key με:

webhooks:manage

Τα νέα keys που δημιουργούνται στις Settings περιλαμβάνουν αυτό το scope από προεπιλογή.

Δημιουργία 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"]
  }'

Η απόκριση περιλαμβάνει το signing_secret μόνο μία φορά:

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

Αποθηκεύστε το πλήρες secret στον server σας. Αν το χάσετε, καλέστε το rotate endpoint και ενημερώστε τον receiver σας.

Κανόνες URL

Τα endpoint URLs πρέπει να είναι HTTPS. Το Rivya απορρίπτει URLs με credentials, fragments, ονόματα localhost, local network addresses, private IP ranges, loopback addresses και reserved addresses.

Το Rivya στέλνει πάντα:

  • POST
  • Content-Type: application/json
  • χωρίς custom request headers ελεγχόμενα από τον χρήστη
  • χωρίς αυτόματη ακολούθηση redirects
  • σύντομο delivery timeout

Συμβάντα

Τρέχοντες event types:

  • generation.succeeded
  • generation.failed

Τα webhook payloads χρησιμοποιούν τον ίδιο public generation serializer με το status endpoint.

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

Delivery headers

Κάθε delivery περιλαμβάνει:

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

Είσοδος signature:

${timestamp}.${rawBody}

Αλγόριθμος:

HMAC-SHA256 with the endpoint signing secret

Απορρίψτε requests με stale timestamps. Μια ανοχή πέντε λεπτών είναι πρακτική προεπιλογή.

Επαλήθευση 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"));
}

Επαλήθευση 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)

Διαχείριση 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-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} απενεργοποιεί το endpoint. Δεν διαγράφει το delivery history.

Εγγραφές delivery

Λίστα πρόσφατων events:

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

Λίστα delivery attempts για ένα endpoint:

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

Τα delivery records περιλαμβάνουν status, HTTP status, attempt number, request id, duration, truncated response snippet και public error fields.

Δοκιμαστικό event

Στείλτε ένα ασφαλές test payload:

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

Το test event χρησιμοποιεί webhook.test. Δεν δημιουργεί generation task, δεν καταναλώνει credits και δεν περιλαμβάνει πραγματικό result URL.

Πολιτική retry

Το Rivya θεωρεί το HTTP 2xx επιτυχία.

Οι αποτυχίες περιλαμβάνουν network errors, timeout, redirect responses και non-2xx responses. Το Rivya επαναλαμβάνει έως πέντε attempts:

  • αμέσως
  • μετά από 1 λεπτό
  • μετά από 5 λεπτά
  • μετά από 30 λεπτά
  • μετά από 2 ώρες

Μετά το τελικό attempt, το event επισημαίνεται ως failed.

Οι αποτυχίες webhook delivery δεν αλλάζουν generation status, credits, refunds ή task history.

Λίστα ελέγχου ασφαλείας

  • Επαληθεύστε το HMAC signature πριν αναλύσετε business logic.
  • Απορρίψτε stale timestamps.
  • Αντιμετωπίστε τα test events ξεχωριστά από τα generation events.
  • Μην καταγράφετε πλήρη signing secrets.
  • Επιστρέψτε 2xx μόνο αφού ο receiver σας έχει αποδεχτεί το event.
  • Κρατήστε το polling ως fallback για reconciliation.

Σχετικές σελίδες

Πίνακας περιεχομένων