Documentação da Rivya AI

Rivya TypeScript SDK

Use o beta do Rivya TypeScript SDK para chamar a Public API v1 em modelos, gerações, arquivos, créditos, webhooks e Chat, incluindo streaming SSE.

Última revisão em 2026/08/26

A Rivya fornece um beta do TypeScript SDK para integrações da Public API no lado do servidor.

O SDK é um cliente fino sobre a Rivya Public API v1. O contrato de nível mais baixo continua sendo Contrato de OpenAPI e Schema, e os métodos do SDK devem permanecer alinhados com esse schema.

Status

O pacote atualmente é mantido dentro deste repositório como beta privado. Ele não será publicado no npm até que o nome do pacote, os metadados, o registro de alterações e o processo de lançamento sejam aprovados explicitamente.

O SDK oferece suporte a:

  • listagem de modelos

  • criação e recuperação de gerações assíncronas

  • upload e recuperação pela Files API

  • recuperação de saldo de créditos

  • gerenciamento de endpoints de webhook, entregas de teste, listagem de eventos, listagem de entregas e rotação de segredo

  • verificação de assinatura de webhook

  • conclusões de Chat sem streaming e com streaming, além de sessões de chat criadas pela API

O streaming de Chat está disponível neste beta privado por meio da análise de SSE no lado do servidor. Mantenha chaves secretas de API no seu servidor.

Instalar Neste Repo

Use o código-fonte do pacote local enquanto o SDK está em beta:

pnpm --dir packages/rivya-sdk typecheck

O código da aplicação deve manter a chave secreta de API no servidor:

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

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

Não coloque chaves secretas de API em pacotes de navegador, localStorage, eventos de análise, capturas de tela ou chamados compartilhados.

Listar Modelos

models.list é público e não exige chave de API:

const models = await rivya.models.list();

for (const model of models.data) {
  console.log(model.id, model.api_status, model.supported_api_inputs);
}

Criar uma Geração

Use generations.create para geração assíncrona de imagem, vídeo ou áudio:

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

Depois consulte com generations.retrieve:

const current = await rivya.generations.retrieve(generation.id);
console.log(current.status, current.result?.primary_url);

Use Idempotency-Key para solicitações de escrita em produção. O SDK expõe isso como idempotencyKey.

Fazer Upload de Arquivos

Use files.upload para imagens, vídeos ou áudio de referência:

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

Use files.retrieve para ler novamente os metadados enviados:

const sameFile = await rivya.files.retrieve(uploaded.id);
console.log(sameFile.mime_type, sameFile.duration_token);

Ao usar um arquivo em uma geração, envie os campos públicos retornados por 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
      }
    ]
  }
});

Toda imagem de referência do Image5 ou do Grok Imagine Image 2.0 exige os valores width, height, size_bytes e image_dimensions_token da resposta original do upload vinculado ao modelo. Uma chamada posterior a files.retrieve pode retornar o token como null; faça novo upload da imagem de origem em vez de tentar adivinhar o tipo MIME, as dimensões ou o tamanho em bytes. O Layer Decomposition também exige exatamente uma imagem dentro dos limites geométricos documentados; o Grok Image 2 aceita de 1 a 5 referências JPEG, PNG ou WebP assinadas para edição padrão de imagem.

Para um vídeo de referência do Video8, use video_width, video_height, frames_per_second, video_bitrate_mbps, video_file_size_bytes e video_metadata_token da resposta original do upload vinculado ao modelo como width, height, framesPerSecond, videoBitrateMbps, sizeBytes e videoMetadataToken. Mantenha durationSeconds e durationToken como uma comprovação de duração assinada separada. Se qualquer um dos tokens estiver ausente em uma chamada posterior a files.retrieve, faça novo upload do vídeo de origem.

O Wan 3.0 usa o mesmo mapeamento de campos do SDK em suas cenas mutuamente exclusivas text, frames e reference. Envie cada referência com model: "wan-3-0-video"; imagens exigem os campos de imagem assinados, vídeos exigem duração e metadados de vídeo assinados, e áudio exige os valores originais mime_type, size_bytes, duration_seconds e duration_token. Defina seedance_scene, variant, resolution, aspect_ratio, duration, audio e o seed opcional dentro de params. A duração inteligente é -1, reserva 30 segundos e não pode ser combinada com vídeo de referência; os atalhos de arquivo para vídeo e de link para vídeo continuam indisponíveis.

Verificar Créditos

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

Gerenciar Webhooks

Crie um endpoint de 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);

O signing_secret é retornado apenas após chamadas de criação ou rotação. Armazene-o no seu servidor.

Outras funções auxiliares de webhook:

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

Verifique as assinaturas de entrega antes de confiar no conteúdo de webhooks:

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

O helper do SDK usa o mesmo contrato HMAC-SHA256 documentado em Webhooks da API.

Chat

Use chat.completions.create para um turno da Chat API sem streaming:

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 com o session_id retornado:

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

Leia sessões criadas pela API:

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

Use chat.completions.stream para consumir Server-Sent Events como um iterador assíncrono:

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 serve apenas para exibição. O resultado confirmado fica disponível após message.completed e pode ser lido depois com chat.sessions.retrieve.

Erros

O SDK lança RivyaAPIError para respostas não 2xx da Public API:

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 inclui o status HTTP, o código público de erro, a mensagem, o ID da solicitação quando disponível e um subconjunto seguro de cabeçalhos de resposta.

Validação

Execute as checagens do SDK antes de tratar uma mudança como concluída:

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

pnpm sdk:check inclui uma checagem estática de contrato e uma checagem de execução sem rede para análise de erros, cabeçalhos seguros de erro, cabeçalhos de idempotência, autenticação Bearer, listagem pública de modelos, análise de SSE do streaming de Chat, eventos de erro no streaming de Chat e verificação de assinatura de webhook.

Páginas Relacionadas