Rivya TypeScript SDK
Use the Rivya TypeScript SDK beta to call Public API v1 for models, generations, files, credits, webhooks, and Chat including SSE streaming.
Last reviewed on 2026/05/11
Rivya provides a TypeScript SDK beta for server-side Public API integrations.
The SDK is a thin client over Rivya Public API v1. The lower-level contract remains OpenAPI and Schema Contract, and SDK methods must stay aligned with that schema.
Status
The package is currently maintained inside this repository as a private beta. It is not published to npm until the package name, metadata, changelog, and release process are explicitly approved.
The SDK supports:
model listing
asynchronous generation create and retrieve
Files API upload and retrieve
credit balance retrieval
webhook endpoint management, test deliveries, event listing, delivery listing, and secret rotation
webhook signature verification
non-streaming and streaming Chat completions, plus API-created chat sessions
Chat streaming is available in this private beta through server-side SSE parsing. Keep secret API keys on your server.
Install In This Repo
Use the local package source while the SDK is in beta:
pnpm --dir packages/rivya-sdk typecheckApplication code should keep the secret API key on the server:
import { RivyaClient } from "@rivya/sdk";
const rivya = new RivyaClient({
apiKey: process.env.RIVYA_API_KEY
});Do not place secret API keys in browser bundles, localStorage, analytics events, screenshots, or shared tickets.
List Models
models.list is public and does not require an 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);
}Create A Generation
Use generations.create for asynchronous image, video, or audio generation:
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);Then poll with generations.retrieve:
const current = await rivya.generations.retrieve(generation.id);
console.log(current.status, current.result?.primary_url);Use Idempotency-Key for production write requests. The SDK exposes this as idempotencyKey.
Upload Files
Use files.upload for reference images, videos, or audio:
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);Use files.retrieve to read uploaded metadata again:
const sameFile = await rivya.files.retrieve(uploaded.id);
console.log(sameFile.mime_type, sameFile.duration_token);When using a file in a generation, pass the returned public fields through 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
}
]
}
});Check Credits
const credits = await rivya.credits.retrieve();
console.log(credits.current_credits);Manage Webhooks
Create a 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);The signing_secret is returned only after create or rotate calls. Store it on your server.
Other webhook helpers:
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 });Verify delivery signatures before trusting webhook payloads:
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");
}The SDK helper uses the same HMAC-SHA256 contract documented in API Webhooks.
Chat
Use chat.completions.create for one non-streaming Chat API turn:
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);Continue with the returned 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."
});Read API-created sessions:
await rivya.chat.sessions.list({ limit: 20 });
await rivya.chat.sessions.retrieve(completion.session_id);Use chat.completions.stream to consume Server-Sent Events as an async iterator:
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 is for display only. The committed result is available after message.completed, and can be read later with chat.sessions.retrieve.
Errors
The SDK throws RivyaAPIError for non-2xx Public API responses:
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 includes the HTTP status, public error code, message, request id when available, and a safe response-header subset.
Validation
Run the SDK checks before treating a change as complete:
pnpm sdk:check
pnpm --dir packages/rivya-sdk typecheck
pnpm content:api-docspnpm sdk:check includes a static contract check and a no-network runtime check for error parsing, safe error headers, idempotency headers, Bearer auth, public model listing, Chat streaming SSE parsing, Chat streaming error events, and webhook signature verification.