Документация Rivya AI

Rivya TypeScript SDK

Используйте закрытую бета-версию Rivya TypeScript SDK для вызова моделей, генераций, файлов, кредитов, вебхуков и Chat через Public API v1, включая SSE.

Последняя проверка: 2026/08/29

Rivya предоставляет закрытую бета-версию TypeScript SDK для серверных интеграций с Public API.

SDK — тонкий клиент для Rivya Public API v1. Низкоуровневым контрактом остается схема OpenAPI, и методы SDK должны соответствовать этой схеме.

SDK описывает реализованное поведение клиента. Для запросов по-прежнему нужны включенный Public API, действительный ключ аккаунта и модель, чей актуальный API-статус разрешает требуемую операцию.

Статус

Сейчас пакет поддерживается в этом репозитории как закрытая бета-версия. Он не публикуется в npm, пока не будут утверждены название, метаданные, журнал изменений и процесс выпуска.

SDK поддерживает:

  • получение списка моделей

  • создание и получение асинхронных генераций

  • загрузку и получение через Files API

  • получение баланса кредитов

  • управление конечными точками вебхуков, тестовые доставки, список событий и доставок, а также смену секрета

  • проверку подписи вебхука

  • завершения Chat без стриминга и со стримингом, а также сессии чата, созданные через API

Потоковая передача Chat доступна в этой закрытой бета-версии через серверный разбор SSE. Храните секретные ключи API только на своем сервере.

Установка в этом репозитории

Пока SDK находится в beta, используйте локальный исходник пакета:

pnpm --dir packages/rivya-sdk typecheck

Код приложения должен хранить секретный API-ключ на сервере:

import { RivyaClient } from "@rivya/sdk";

const rivya = new RivyaClient({
  apiKey: process.env.RIVYA_API_KEY
});

Не помещайте секретные ключи API в браузерные сборки, localStorage, аналитические события, снимки экрана или общие заявки поддержки.

Список моделей

models.list публичен и не требует API-ключа:

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: "Чистое редакционное изображение продукта на мягком студийном фоне",
    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-lite",
  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-lite",
  prompt: "Измените стиль фотографии продукта для чистой редакционной страницы каталога",
  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
      }
    ]
  }
});

Для каждого справочного изображения Image5 или Grok Imagine Image 2.0 нужны width, height, size_bytes и image_dimensions_token из исходного ответа на загрузку, привязанную к модели. Позднее вызов files.retrieve может вернуть токен как null; вместо того чтобы угадывать MIME-тип, размеры или число байтов, повторно загрузите исходное изображение. Для Layer Decomposition также применяются его геометрические ограничения для одного изображения; Grok Image 2 принимает от одного до пяти подписанных справочных изображений в форматах JPEG, PNG или WebP для стандартного редактирования.

Для справочного видео Video8 используйте video_width, video_height, frames_per_second, video_bitrate_mbps, video_file_size_bytes и video_metadata_token из исходного ответа на загрузку, привязанную к модели, как width, height, framesPerSecond, videoBitrateMbps, sizeBytes и videoMetadataToken. Сохраняйте durationSeconds и durationToken как отдельное подписанное подтверждение длительности. Если при последующем вызове files.retrieve отсутствует любой из токенов, повторно загрузите исходное видео.

Wan 3.0 использует одинаковое сопоставление полей SDK во взаимоисключающих сценах text, frames и reference. Загружайте каждый референс с model: "wan-3-0-video"; для изображений нужны подписанные поля изображения, для видео — подписанные длительность и видеометаданные, а для аудио — исходные значения mime_type, size_bytes, duration_seconds и duration_token. Задайте seedance_scene, variant, resolution, aspect_ratio, duration, audio и необязательный seed внутри params. Интеллектуальная длительность задается как -1, резервирует 30 секунд и не может использоваться со справочным видео; быстрые пути преобразования файла в видео и ссылки в видео остаются недоступны.

Проверка кредитов

const credits = await rivya.credits.retrieve();
console.log(credits.current_credits);

Управление вебхуками

Когда доступ к вебхукам включен для развертывания и аккаунта, создайте конечную точку вебхука:

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 возвращается только после вызовов создания или ротации. Храните его на своем сервере.

Другие помощники вебхуков:

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 });

Проверяйте подписи доставок, прежде чем доверять полезной нагрузке вебхука:

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 использует тот же контракт HMAC-SHA256, который описан в API-вебхуках.

Chat

Используйте chat.completions.create для одного хода Chat API без стриминга:

const completion = await rivya.chat.completions.create(
  {
    model: "claude-sonnet-5-chat",
    message: "Составьте краткий план запуска новой кампании с изображениями продукта",
    client_request_id: "chat-001"
  },
  {
    idempotencyKey: "chat-001"
  }
);

console.log(completion.session_id, completion.message.content);

Продолжайте с возвращенным session_id:

await rivya.chat.completions.create({
  model: "claude-sonnet-5-chat",
  session_id: completion.session_id,
  message: "Теперь превратите его в список из пяти шагов."
});

Читайте сессии, созданные через API:

await rivya.chat.sessions.list({ limit: 20 });
await rivya.chat.sessions.retrieve(completion.session_id);

Используйте chat.completions.stream, чтобы читать события SSE как асинхронный итератор:

const stream = await rivya.chat.completions.stream(
  {
    model: "claude-sonnet-5-chat",
    message: "Составьте краткий план запуска новой кампании с изображениями продукта",
    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.

Ошибки

SDK выбрасывает RivyaAPIError, если код ответа Public API не входит в диапазон 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 включает HTTP-статус, публичный код ошибки, сообщение, ID запроса при наличии и безопасное подмножество заголовков ответа.

Валидация

Запустите проверки SDK, прежде чем считать изменение завершенным:

pnpm sdk:check
pnpm --dir packages/rivya-sdk typecheck
pnpm content:api-docs

pnpm sdk:check включает статическую проверку контракта и автономную проверку выполнения: разбор ошибок, безопасные заголовки ошибок, заголовки идемпотентности, аутентификацию Bearer, публичный список моделей, разбор потоковых ответов Chat по SSE, события ошибок потока Chat и проверку подписи вебхука.

Связанные страницы