Niravi Docs
npm ↗ Get a key ↗

TypeScript SDK

A small hand-written transport core (auth, retries, rate-limit, typed errors, pagination) over generated types (schema.d.ts, produced from the API’s OpenAPI). The API is the single source of truth — the SDK never hand-encodes field shapes.

Install

npm install @niravi/sdk    # 0.2.0

Quickstart

import { connect } from "@niravi/sdk";

const niravi = connect("nv_..."); // dashboard → Settings → Developer

// Semantic search: up to 3 moments per video
const hits = await niravi.search("a person walking at sunset", { limit: 5, momentsPerVideo: 3 });
for (const h of hits) console.log(h.video_id, h.timestamp, h.score, h.raw_score);

// Drill into one video
const video = await niravi.getVideo(hits[0].video_id);
console.log(await video.transcript());
console.log(await video.recallAsk("what happens in this clip?"));

API

connect(apiKey, opts?) → a Niravi handle.

MethodDescription
niravi.search(query, { limit?, videoId?, engine?, momentsPerVideo?, workspaceIds?, searchOptions?, rerank? })Semantic search → hits. engine is "arrow" or "classic" (omit for the workspace default); momentsPerVideo 1 to 10
niravi.searchResponse(query, opts?)The same, resolving to the whole response (results, engine, engine_fallback, …)
niravi.magicSearch(type, query, { limit?, videoId? })Typed search (character/location/music/emotion)
niravi.chat(message, { videoId?, maxTokens? })Conversational Q&A, with citations
niravi.videos({ limit?, allPages? })List videos (paginated)
niravi.getVideo(id)→ a Video
niravi.upload(filePath, { filename?, pipeline?, options?, language?, contentType?, timeoutMs? })Upload a video, photo or document, Node only (write scope; runs on Arrow). Streams from disk, no timeout unless you pass one
niravi.deleteVideo(id)Delete an asset your workspace owns (write scope)
niravi.downloadNmap(id, destPath?)The .nmap archive: bytes, or streamed to destPath
niravi.engines() / niravi.indexOptions()The search engines; the workspace’s index options
niravi.workspaces()The workspaces the key can reach
niravi.health() / niravi.rateLimitHealth / the last response’s limits: { limit, remaining, reset, limitMinute, limitDay, remainingMinute } (Rate limits)

Video: transcript(), scenes(), shots(), faces(), characters(), speakers(), sounds(), soundEvents(), audioSegments({ audioType? }), musicTracks(), regions({ page?, timestamp? }), screenplay(), storyboard(), subtitles(format, { raw? }) (raw: true → the SRT/VTT text), frame(timestamp, { jpeg? }) (jpeg: true → the JPEG bytes), nmap(destPath?), recallAsk(question), delete().

const v = await niravi.getVideo(videoId);
const srt = await v.subtitles("srt", { raw: true });
const jpeg = await v.frame(10, { jpeg: true });
await niravi.downloadNmap(videoId, `./${videoId}.nmap`);
await niravi.upload("./episode.mp4", { options: { faces: false }, language: "en" });

Generated types

import type { components } from "@niravi/sdk";
type SearchResponse = components["schemas"]["SearchResponse"];

Auth & options

connect("nv_...", {
  baseUrl: "https://api.niravi.io", // default
  authScheme: "x-api-key",          // default; or "bearer"
  workspace: "demo_newsroom",       // sent as X-Workspace-Id; omit for the key's home
  timeoutMs: 60000,                 // per request (default); uploads and downloads are not bound by it
  maxRetries: 3,
});

A 429 is retried for any call, honouring Retry-After. A 5xx or network error is retried only for idempotent calls (reads, search, chat, recall); an upload is never resent.

Errors

Throws typed errors built from the error envelope: AuthError (401/403), NotFoundError (404), ValidationError (422), RateLimitError (429, carries retryAfter), ServerError (5xx, including 502 chat_unavailable), all subclasses of NiraviError, which carries code, status, requestId and the legacy detail. Other statuses (400, 409 not_ready) throw a plain NiraviError.

import { NotFoundError } from "@niravi/sdk";
try { await niravi.getVideo("nope"); } catch (e) { if (e instanceof NotFoundError) console.log(e.code, e.requestId); }

Pages and People have no SDK helpers yet (their types are in the generated schema.d.ts): call them with fetch (reference). Package: @niravi/sdk · License Apache-2.0.