Rivya TypeScript SDK
使用 Rivya TypeScript SDK beta 调用 Public API v1,包括模型、生成、文件、积分、webhook,以及包含 SSE streaming 的 Chat。
最近审阅于 2026/05/11
Rivya 提供 TypeScript SDK beta,用于服务端 Public API 集成。
SDK 是 Rivya Public API v1 的薄客户端。底层合同仍以 OpenAPI 与 Schema 合同 为准,SDK 方法必须和 schema 保持一致。
状态
当前 package 只作为仓库内 private beta 维护。只有在包名、metadata、changelog 和发布流程被明确批准后,才允许发布到 npm。
SDK 支持:
- 查询模型列表
- 创建和查询异步生成任务
- Files API 上传和查询
- 查询积分余额
- webhook endpoint 管理、测试投递、事件列表、投递列表和 secret 轮换
- webhook 签名校验
- 非 streaming 与 streaming Chat completions,以及 API 创建的 chat sessions
Chat streaming 已在当前 private beta 中通过服务端 SSE parser 开放。secret API key 仍然只能放在服务端。
在当前仓库中使用
SDK 处于 beta 时,先使用本地 package source:
pnpm --dir packages/rivya-sdk typecheck业务代码应把 secret API key 保存在服务端:
import { RivyaClient } from "@rivya/sdk";
const rivya = new RivyaClient({
apiKey: process.env.RIVYA_API_KEY
});不要把 secret API key 放进浏览器 bundle、localStorage、分析事件、截图或共享工单。
查询模型
models.list 是公开只读接口,不需要 API key:
const models = await rivya.models.list();
for (const model of models.data) {
console.log(model.id, model.api_status, model.supported_api_inputs);
}创建生成任务
使用 generations.create 创建异步图片、视频或音频生成任务:
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);再用 generations.retrieve 轮询:
const current = await rivya.generations.retrieve(generation.id);
console.log(current.status, current.result?.primary_url);生产写请求建议使用 Idempotency-Key。SDK 中对应参数是 idempotencyKey。
上传文件
使用 files.upload 上传参考图片、视频或音频:
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",
client_request_id: "asset-123"
});
console.log(uploaded.id, uploaded.url);使用 files.retrieve 重新读取已上传文件的元数据:
const sameFile = await rivya.files.retrieve(uploaded.id);
console.log(sameFile.mime_type, sameFile.duration_token);在生成任务中使用文件时,把返回的公开字段放进 params.referenceMediaItems:
await rivya.generations.create({
model: "nano-banana-2",
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
}
]
}
});查询积分
const credits = await rivya.credits.retrieve();
console.log(credits.current_credits);管理 Webhooks
创建 webhook endpoint:
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 只会在创建或轮换时返回一次。请把它保存在服务端。
其他 webhook helper:
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 });信任 webhook payload 前,先校验签名:
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");
}这个 SDK helper 使用的就是 API Webhooks 中记录的 HMAC-SHA256 合同。
Chat
使用 chat.completions.create 发送一轮非 streaming Chat API 请求:
const completion = await rivya.chat.completions.create(
{
model: "gpt-5-2-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);用返回的 session_id 继续对话:
await rivya.chat.completions.create({
model: "gpt-5-2-chat",
session_id: completion.session_id,
message: "Now turn that into a 5-step execution checklist."
});读取 API 创建的 sessions:
await rivya.chat.sessions.list({ limit: 20 });
await rivya.chat.sessions.retrieve(completion.session_id);使用 chat.completions.stream 以 async iterator 读取 Server-Sent Events:
const stream = await rivya.chat.completions.stream(
{
model: "gpt-5-2-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 只适合用于展示增量。最终提交结果以 message.completed 为准,之后也可以用 chat.sessions.retrieve 读取。
错误处理
Public API 返回非 2xx 时,SDK 会抛出 RivyaAPIError:
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 包含 HTTP status、公共错误码、message、可用时的 request id,以及安全的响应 header 子集。
验证
把 SDK 变更视为完成前,先运行:
pnpm sdk:check
pnpm --dir packages/rivya-sdk typecheck
pnpm content:api-docspnpm sdk:check 包含静态合同检查,也包含无网络 runtime 检查,覆盖错误解析、安全错误 header、幂等 header、Bearer 鉴权、公开模型列表、Chat streaming SSE parsing、Chat streaming error event 和 webhook 签名校验。