Rivya TypeScript SDK
Dùng Rivya TypeScript SDK thử nghiệm để gọi Public API v1 cho mô hình, tác vụ tạo nội dung, tệp, điểm tín dụng, webhook và Chat, bao gồm truyền phát SSE.
Đánh giá lần cuối vào 2026/08/29
Rivya cung cấp TypeScript SDK thử nghiệm cho các tích hợp Public API phía máy chủ.
SDK là một ứng dụng khách mỏng trên Rivya Public API v1. Hợp đồng cấp thấp hơn vẫn là OpenAPI và hợp đồng lược đồ, và các phương thức SDK phải luôn khớp với lược đồ đó.
SDK mô tả hành vi ứng dụng khách đã triển khai. Yêu cầu vẫn cần Public API được bật cho bản triển khai, khóa tài khoản hợp lệ và mô hình có trạng thái API trực tiếp cho phép thao tác đó.
Trạng thái
Gói hiện được duy trì trong kho mã này dưới dạng thử nghiệm riêng tư. Gói sẽ chưa được phát hành lên npm cho đến khi tên gói, siêu dữ liệu, nhật ký thay đổi và quy trình phát hành được phê duyệt rõ ràng.
SDK hỗ trợ:
liệt kê mô hình
tạo và truy xuất tác vụ tạo nội dung bất đồng bộ
tải lên và truy xuất tệp qua Files API
truy xuất số dư điểm tín dụng
quản lý điểm cuối webhook, gửi bản kiểm thử, liệt kê sự kiện, liệt kê lượt gửi và xoay vòng secret
xác minh chữ ký webhook
hoàn thành Chat không truyền phát và có truyền phát, cùng các phiên trò chuyện do API tạo
Chức năng truyền phát Chat có trong bản thử nghiệm riêng tư này thông qua quá trình phân tích SSE phía máy chủ. Hãy giữ các khóa API bí mật trên máy chủ của bạn.
Cài đặt trong kho mã này
Dùng nguồn gói cục bộ khi SDK còn ở giai đoạn thử nghiệm:
pnpm --dir packages/rivya-sdk typecheckMã ứng dụng phải giữ khóa API bí mật trên máy chủ:
import { RivyaClient } from "@rivya/sdk";
const rivya = new RivyaClient({
apiKey: process.env.RIVYA_API_KEY
});Không đặt khóa API bí mật trong gói mã trình duyệt, localStorage, sự kiện phân tích, ảnh chụp màn hình hoặc phiếu hỗ trợ được chia sẻ.
Liệt kê mô hình
models.list là phương thức công khai và không cần khóa API:
const models = await rivya.models.list();
for (const model of models.data) {
console.log(model.id, model.api_status, model.supported_api_inputs);
}Tạo nội dung
Dùng generations.create để tạo hình ảnh, video hoặc âm thanh bất đồng bộ:
const generation = await rivya.generations.create(
{
model: "z-image",
prompt: "A clean editorial product image on a soft studio background",
client_request_id: "order-123-preview"
},
{
idempotencyKey: "order-123-preview"
}
);
console.log(generation.id, generation.status);Sau đó thăm dò bằng generations.retrieve:
const current = await rivya.generations.retrieve(generation.id);
console.log(current.status, current.result?.primary_url);Dùng Idempotency-Key cho các yêu cầu ghi trong môi trường môi trường vận hành. SDK cung cấp trường này dưới dạng idempotencyKey.
Tải tệp lên
Dùng files.upload cho ảnh, video hoặc âm thanh tham chiếu:
import { readFile } from "node:fs/promises";
const file = new Blob([await readFile("./reference.png")], {
type: "image/png"
});
const uploaded = await rivya.files.upload({
file,
filename: "reference.png",
kind: "image",
model: "nano-banana-2-lite",
client_request_id: "asset-123"
});
console.log(uploaded.id, uploaded.url);Dùng files.retrieve để đọc lại siêu dữ liệu đã tải lên:
const sameFile = await rivya.files.retrieve(uploaded.id);
console.log(sameFile.mime_type, sameFile.duration_token);Khi dùng một tệp trong yêu cầu tạo nội dung, hãy truyền các trường công khai được trả về qua params.referenceMediaItems:
await rivya.generations.create({
model: "nano-banana-2-lite",
prompt: "Restyle this product photo for a clean editorial catalog page",
params: {
referenceMediaItems: [
{
url: uploaded.url,
kind: uploaded.kind,
name: uploaded.file_name,
mimeType: uploaded.mime_type,
durationSeconds: uploaded.duration_seconds ?? undefined,
durationToken: uploaded.duration_token ?? undefined,
width: uploaded.video_width ?? uploaded.width ?? undefined,
height: uploaded.video_height ?? uploaded.height ?? undefined,
sizeBytes: uploaded.video_file_size_bytes ?? uploaded.size_bytes,
imageDimensionsToken: uploaded.image_dimensions_token ?? undefined,
framesPerSecond: uploaded.frames_per_second ?? undefined,
videoBitrateMbps: uploaded.video_bitrate_mbps ?? undefined,
videoMetadataToken: uploaded.video_metadata_token ?? undefined
}
]
}
});Mỗi ảnh tham chiếu Image5 hoặc Grok Imagine Image 2.0 đều cần width, height, size_bytes và image_dimensions_token từ phản hồi tải lên ban đầu được gắn với mô hình. Lần gọi files.retrieve sau đó có thể trả về token là null; hãy tải lại ảnh nguồn thay vì đoán kiểu MIME, kích thước hoặc số byte. Layer Decomposition còn áp dụng các giới hạn hình học cho đúng một ảnh; Grok Image 2 chấp nhận từ một đến năm ảnh tham chiếu JPEG, PNG hoặc WebP có chữ ký cho chế độ chỉnh sửa ảnh tiêu chuẩn.
Với video tham chiếu Video8, hãy dùng video_width, video_height, frames_per_second, video_bitrate_mbps, video_file_size_bytes và video_metadata_token từ phản hồi tải lên ban đầu được gắn với mô hình dưới dạng width, height, framesPerSecond, videoBitrateMbps, sizeBytes và videoMetadataToken. Giữ durationSeconds và durationToken làm bằng chứng thời lượng có chữ ký riêng biệt. Nếu một trong hai token bị thiếu trong lần gọi files.retrieve sau đó, hãy tải lại video nguồn.
Wan 3.0 dùng cùng cách ánh xạ trường SDK cho ba chế độ text, frames và reference loại trừ lẫn nhau. Hãy tải mọi tệp tham chiếu lên với model: "wan-3-0-video"; ảnh cần các trường ảnh có chữ ký, video cần cả thời lượng lẫn siêu dữ liệu video có chữ ký, còn âm thanh cần mime_type, size_bytes, duration_seconds và duration_token ban đầu. Đặt seedance_scene, variant, resolution, aspect_ratio, duration, audio và seed tùy chọn trong params. Thời lượng thông minh là -1, giữ trước 30 giây và không thể kết hợp với video tham chiếu; các lối tắt tệp-to-video và link-to-video vẫn chưa khả dụng.
Kiểm tra điểm tín dụng
const credits = await rivya.credits.retrieve();
console.log(credits.current_credits);Quản lý Webhooks
Khi quyền truy cập webhook được bật cho bản triển khai và tài khoản, hãy tạo điểm cuối webhook:
const endpoint = await rivya.webhooks.create({
name: "Production webhook",
url: "https://example.com/rivya/webhook",
event_types: ["generation.succeeded", "generation.failed"]
});
console.log(endpoint.id, endpoint.signing_secret);signing_secret chỉ được trả về sau lệnh tạo hoặc xoay vòng. Hãy lưu giá trị này trên máy chủ của bạn.
Các hàm hỗ trợ webhook khác:
await rivya.webhooks.list();
await rivya.webhooks.retrieve(endpoint.id);
await rivya.webhooks.update(endpoint.id, { status: "disabled" });
await rivya.webhooks.test(endpoint.id);
await rivya.webhooks.rotateSecret(endpoint.id);
await rivya.webhooks.deliveries.list(endpoint.id, { limit: 20 });
await rivya.webhookEvents.list({ limit: 20 });Xác minh chữ ký lượt gửi trước khi tin cậy dữ liệu webhook:
import { verifyRivyaWebhookSignature } from "@rivya/sdk";
const ok = await verifyRivyaWebhookSignature({
rawBody,
timestamp: request.headers.get("rivya-webhook-timestamp") || "",
signatureHeader: request.headers.get("rivya-webhook-signature") || "",
signingSecret: process.env.RIVYA_WEBHOOK_SIGNING_SECRET || ""
});
if (!ok) {
throw new Error("Invalid Rivya webhook signature");
}Hàm hỗ trợ của SDK dùng cùng hợp đồng HMAC-SHA256 được ghi trong API Webhooks.
Chat
Dùng chat.completions.create cho một lượt Chat API không truyền phát:
const completion = await rivya.chat.completions.create(
{
model: "claude-sonnet-5-chat",
message: "Write a concise launch plan for a new product image campaign",
client_request_id: "chat-001"
},
{
idempotencyKey: "chat-001"
}
);
console.log(completion.session_id, completion.message.content);Tiếp tục bằng session_id được trả về:
await rivya.chat.completions.create({
model: "claude-sonnet-5-chat",
session_id: completion.session_id,
message: "Now turn that into a 5-step execution checklist."
});Đọc các phiên do API tạo:
await rivya.chat.sessions.list({ limit: 20 });
await rivya.chat.sessions.retrieve(completion.session_id);Dùng chat.completions.stream để xử lý Server-Sent Events như một bộ lặp bất đồng bộ:
const stream = await rivya.chat.completions.stream(
{
model: "claude-sonnet-5-chat",
message: "Write a concise launch plan for a new product image campaign",
client_request_id: "chat-stream-001"
},
{
idempotencyKey: "chat-stream-001"
}
);
for await (const event of stream) {
if (event.event === "message.delta") {
process.stdout.write(event.data.delta);
}
if (event.event === "message.completed") {
console.log(event.data.message.id);
}
}message.delta chỉ dùng để hiển thị. Kết quả đã được ghi nhận sẽ có sau message.completed và có thể được đọc lại bằng chat.sessions.retrieve.
Lỗi
SDK ném RivyaAPIError khi Public API trả về phản hồi không thuộc nhóm 2xx:
import { RivyaAPIError } from "@rivya/sdk";
try {
await rivya.generations.retrieve("task_missing");
} catch (error) {
if (error instanceof RivyaAPIError) {
console.log(error.status, error.code, error.requestId);
}
}RivyaAPIError bao gồm trạng thái HTTP, mã lỗi công khai, thông báo, ID yêu cầu khi có và một tập con an toàn của các header phản hồi.
Kiểm tra
Chạy các kiểm tra SDK trước khi xem một thay đổi là hoàn tất:
pnpm sdk:check
pnpm --dir packages/rivya-sdk typecheck
pnpm content:api-docspnpm sdk:check bao gồm kiểm tra hợp đồng tĩnh và kiểm tra runtime không dùng mạng cho quá trình phân tích lỗi, header lỗi an toàn, header idempotency, xác thực Bearer, liệt kê mô hình công khai, phân tích SSE truyền phát Chat, sự kiện lỗi truyền phát Chat và xác minh chữ ký webhook.
