Documentation Rivya AI

SDK TypeScript Rivya

Utilisez la bêta du SDK TypeScript Rivya pour appeler Public API v1 sur les modèles, générations, fichiers, crédits, webhooks et Chat, y compris le streaming SSE.

Dernière révision le 2026/08/26

Rivya fournit une bêta du SDK TypeScript pour les intégrations Public API côté serveur.

Le SDK est un client léger au-dessus de Rivya Public API v1. Le contrat de niveau inférieur reste le contrat OpenAPI et schéma, et les méthodes du SDK doivent rester alignées avec ce schéma.

Statut

Le package est actuellement maintenu dans ce dépôt en beta privée. Il n'est pas publié sur npm tant que le nom du package, les métadonnées, le changelog et le processus de release ne sont pas explicitement approuvés.

Le SDK prend en charge :

  • la liste des modèles

  • la création et la récupération de générations asynchrones

  • l'import et la récupération via l'API Files

  • la récupération du solde de crédits

  • la gestion des endpoints webhook, les livraisons de test, la liste des événements, la liste des livraisons et la rotation des secrets

  • la vérification des signatures webhook

  • les completions Chat non-streaming et streaming, ainsi que les sessions de chat créées par l'API

Le streaming Chat est disponible dans cette bêta privée via l'analyse SSE côté serveur. Gardez les clés API secrètes sur votre serveur.

Installer dans ce dépôt

Utilisez la source du package local tant que le SDK est en bêta :

pnpm --dir packages/rivya-sdk typecheck

Le code applicatif doit garder la clé API secrète sur le serveur :

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

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

Ne placez pas de clés API secrètes dans les bundles navigateur, localStorage, événements analytics, captures d'écran ou tickets partagés.

Lister les modèles

models.list est public et ne nécessite pas de clé API :

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

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

Créer une génération

Utilisez generations.create pour la génération asynchrone d'image, de vidéo ou d'audio :

const generation = await rivya.generations.create(
  {
    model: "z-image",
    prompt: "Image produit éditoriale nette sur fond studio doux",
    client_request_id: "order-123-preview"
  },
  {
    idempotencyKey: "order-123-preview"
  }
);

console.log(generation.id, generation.status);

Interrogez ensuite avec generations.retrieve :

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

Utilisez Idempotency-Key pour les requêtes d'écriture en production. Le SDK l'expose sous la forme idempotencyKey.

Importer des fichiers

Utilisez files.upload pour les images, vidéos ou audios de référence :

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

Utilisez files.retrieve pour relire les métadonnées importées :

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

Lorsque vous utilisez un fichier dans une génération, transmettez les champs publics renvoyés via params.referenceMediaItems :

await rivya.generations.create({
  model: "nano-banana-2-lite",
  prompt: "Recompose cette photo produit pour une page catalogue éditoriale nette",
  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
      }
    ]
  }
});

Chaque image de référence Image5 ou Grok Imagine Image 2.0 exige les valeurs width, height, size_bytes et image_dimensions_token de sa réponse d'import d'origine liée au modèle. Un appel ultérieur à files.retrieve peut renvoyer null pour le token ; réimportez l'image source au lieu de deviner son type MIME, ses dimensions ou sa taille en octets. Layer Decomposition applique en plus ses limites géométriques à une seule image ; Grok Image 2 accepte 1 à 5 références JPEG, PNG ou WebP signées pour l'édition d'image standard.

Pour une vidéo de référence Video8, utilisez les valeurs video_width, video_height, frames_per_second, video_bitrate_mbps, video_file_size_bytes et video_metadata_token de la réponse d'import d'origine liée au modèle sous les noms width, height, framesPerSecond, videoBitrateMbps, sizeBytes et videoMetadataToken. Conservez durationSeconds et durationToken comme preuve de durée signée distincte. Si l'un des deux tokens manque lors d'un appel ultérieur à files.retrieve, réimportez la vidéo source.

Wan 3.0 utilise le même mappage de champs SDK dans ses scènes mutuellement exclusives text, frames et reference. Importez chaque référence avec model: "wan-3-0-video" ; les images exigent les champs d'image signés, les vidéos exigent à la fois la durée et les métadonnées vidéo signées, et l'audio exige les valeurs d'origine mime_type, size_bytes, duration_seconds et duration_token. Définissez seedance_scene, variant, resolution, aspect_ratio, duration, audio et le seed facultatif dans params. La durée intelligente vaut -1, réserve 30 secondes et ne peut pas être associée à une vidéo de référence ; les raccourcis fichier-vers-vidéo et lien-vers-vidéo restent indisponibles.

Vérifier les crédits

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

Gérer les webhooks

Créez un endpoint webhook :

const endpoint = await rivya.webhooks.create({
  name: "Webhook production",
  url: "https://example.com/rivya/webhook",
  event_types: ["generation.succeeded", "generation.failed"]
});

console.log(endpoint.id, endpoint.signing_secret);

Le signing_secret est renvoyé uniquement après les appels de création ou de rotation. Stockez-le sur votre serveur.

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

Vérifiez les signatures de livraison avant de faire confiance aux payloads 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("Signature webhook Rivya invalide");
}

Le helper du SDK utilise le même contrat HMAC-SHA256 que celui documenté dans Webhooks API.

Chat

Utilisez chat.completions.create pour un tour Chat API non-streaming :

const completion = await rivya.chat.completions.create(
  {
    model: "gpt-5-2-chat",
    message: "Rédige un plan de lancement concis pour une nouvelle campagne visuelle produit",
    client_request_id: "chat-001"
  },
  {
    idempotencyKey: "chat-001"
  }
);

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

Continuez avec le session_id renvoyé :

await rivya.chat.completions.create({
  model: "gpt-5-2-chat",
  session_id: completion.session_id,
  message: "Transforme maintenant cela en checklist opérationnelle en 5 étapes."
});

Lisez les sessions créées par l'API :

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

Utilisez chat.completions.stream pour consommer les Server-Sent Events comme un itérateur asynchrone :

const stream = await rivya.chat.completions.stream(
  {
    model: "gpt-5-2-chat",
    message: "Rédige un plan de lancement concis pour une nouvelle campagne visuelle produit",
    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 sert uniquement à l'affichage. Le résultat validé est disponible après message.completed et peut être relu plus tard avec chat.sessions.retrieve.

Erreurs

Le SDK lance RivyaAPIError pour les réponses Public API non-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 inclut le statut HTTP, le code d'erreur public, le message, l'id de requête lorsqu'il est disponible et un sous-ensemble sûr d'en-têtes de réponse.

Validation

Exécutez les contrôles du SDK avant de considérer un changement comme terminé :

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

pnpm sdk:check inclut un contrôle statique du contrat et un contrôle runtime sans réseau pour le parsing des erreurs, les en-têtes d'erreur sûrs, les en-têtes d'idempotence, l'authentification Bearer, la liste publique des modèles, le parsing SSE du streaming Chat, les événements d'erreur du streaming Chat et la vérification des signatures webhook.

Pages associées