API Webhooks
Tạo endpoint webhook có chữ ký cho Rivya API, xác minh chữ ký delivery, kiểm tra các lần delivery và gửi sự kiện kiểm thử an toàn.
Đánh giá lần cuối vào 2026/05/11
Dùng API webhooks khi tích hợp của bạn cần Rivya thông báo cho server sau khi một generation của Public API đi đến trạng thái cuối.
Việc polling GET /api/v1/generations/{taskId} vẫn được hỗ trợ. Webhooks bổ sung callback có chữ ký cho các hệ thống production muốn nhận kết quả qua event delivery.
Scope bắt buộc
Quản lý webhook yêu cầu API key có scope:
webhooks:manageCác key mới tạo trong Settings mặc định đã bao gồm scope này.
Tạo 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"]
}'Phản hồi chỉ bao gồm signing_secret một lần:
{
"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
}Hãy lưu toàn bộ secret trên server của bạn. Nếu làm mất, hãy gọi endpoint rotate và cập nhật receiver.
Quy tắc URL
Endpoint URL phải dùng HTTPS. Rivya từ chối URL có thông tin xác thực, fragment, tên localhost, địa chỉ mạng cục bộ, dải IP riêng, địa chỉ loopback và địa chỉ dành riêng.
Rivya luôn gửi:
POSTContent-Type: application/json- không có request header tùy chỉnh do người dùng kiểm soát
- không tự động đi theo redirect
- timeout delivery ngắn
Event
Các event type hiện tại:
generation.succeededgeneration.failed
Webhook payload dùng cùng public generation serializer như endpoint trạng thái.
{
"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
}
}
}Header delivery
Mỗi delivery bao gồm:
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_...Input để ký:
${timestamp}.${rawBody}Thuật toán:
HMAC-SHA256 with the endpoint signing secretTừ chối request có timestamp quá cũ. Mức dung sai 5 phút là mặc định thực tế.
Xác minh bằng 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"));
}Xác minh bằng 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)Quản lý 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} sẽ vô hiệu hóa endpoint. Lệnh này không xóa lịch sử delivery.
Bản ghi delivery
Liệt kê các event gần đây:
GET /api/v1/webhook-eventscurl https://rivya.ai/api/v1/webhook-events \
-H "Authorization: Bearer rvya_sk_..."Liệt kê các lần delivery cho một endpoint:
GET /api/v1/webhooks/{endpointId}/deliveriescurl https://rivya.ai/api/v1/webhooks/whend_.../deliveries \
-H "Authorization: Bearer rvya_sk_..."Bản ghi delivery bao gồm status, HTTP status, số lần thử, request id, duration, đoạn response đã cắt ngắn và các trường lỗi công khai.
Event kiểm thử
Gửi payload kiểm thử an toàn:
POST /api/v1/webhooks/{endpointId}/testcurl -X POST https://rivya.ai/api/v1/webhooks/whend_.../test \
-H "Authorization: Bearer rvya_sk_..."Event kiểm thử dùng webhook.test. Nó không tạo generation task, không tiêu thụ credits và không bao gồm URL kết quả thật.
Chính sách retry
Rivya xem HTTP 2xx là thành công.
Thất bại bao gồm lỗi mạng, timeout, phản hồi redirect và phản hồi không phải 2xx. Rivya retry tối đa 5 lần:
- ngay lập tức
- sau 1 phút
- sau 5 phút
- sau 30 phút
- sau 2 giờ
Sau lần thử cuối cùng, event được đánh dấu là failed.
Lỗi webhook delivery không thay đổi trạng thái generation, credits, refund hoặc lịch sử task.
Checklist bảo mật
- Xác minh chữ ký HMAC trước khi phân tích business logic.
- Từ chối timestamp quá cũ.
- Xử lý event kiểm thử tách biệt với event generation.
- Không ghi log toàn bộ signing secret.
- Chỉ trả về
2xxsau khi receiver của bạn đã chấp nhận event. - Giữ polling làm fallback để đối soát.
Trang liên quan
Rivya TypeScript SDK
Dùng Rivya TypeScript SDK beta để gọi Public API v1 cho models, generations, files, credits, webhooks và Chat bao gồm SSE streaming.
Tổng quan Rivya API
Dùng Rivya API v1 để gọi các mô hình generation và chat của Rivya từ sản phẩm của bạn với API key, credits trong tài khoản và SSE streaming tùy chọn.