Niravi Docs
npm ↗ Get a key ↗

Indexing & engines

Arrow is Niravi’s engine: it indexes videos, photos and documents in the cloud and answers search with the moment, the page, the passage and the box. What it extracts is up to you, per upload or per workspace.

Engines

EngineUpload withSearch withStatus
ArrowThe default (or pipeline=arrow)The default for new workspaces (or "engine": "arrow")Current. Everything new (images, documents, pages, regions, People, index options) is Arrow-only
NiNo (Lite / Pro / Max)pipeline=lite | pro | max or nino_* (videos only)Deprecated
NiQu (classic)"engine": "classic"Deprecated

Which engine answers a search. A new workspace searches with Arrow by default, and so does every workspace that is empty or holds only Arrow assets. A library indexed by NiNo still defaults to classic: pass "engine": "arrow" there to search what you upload. engine on a request always overrides the default, and every search response’s engine says which one answered.

GET /api/v1/engines lists the search engines with their status (Arrow current, classic deprecated) and available flags, answered for your workspace: default marks the engine your searches use when you omit engine, workspace_default says your workspace is set to it, and deployment_default marks the deployment’s fallback. See Deprecations for what that means and what to change.

Every upload path runs Arrow: POST /videos, both SDKs’ upload(), the dashboard and link imports. A finished upload is searchable within seconds of completing (3 to 7 s measured); until it is completed it never appears in search results.

Stages

An Arrow run is made of stages. Each one can be switched on or off, and some take values:

StageDefaultValuesProduces
transcriptonlanguage (auto or an ISO code, e.g. hi)Timed transcript
captionsonA description per shot (and per picture page) + a summary
speakersonmin_speakers, max_speakersWho spoke when, speaker on each transcript segment
soundsonmin_confidence (0.25)Sound events (AudioSet labels)
labelsonmin_confidence (0.5), top_k (5)Scene labels per frame
ocronfps (0.5), languages (en, hi)On-screen and on-page text with boxes
facesonfps (1), min_face_px (32)Faces with boxes and quality
objectsonmin_confidence (0.45), max_regions (50), vocabularyObject boxes on photos and picture pages
peopleonFaces grouped into workspace People (needs faces)
musicoffNot available on this deployment

A stage that does not apply reports not_applicable (no audio stages on a photo; no objects on video).

Not produced by Arrow yet: shot scale, camera angle, setting and mood per shot; content classification (classification, ai_tags); song identification; speaker names. These fields are null on Arrow assets. A video can complete with a failed stage: index.report names it.

Objects

Objects come from a closed-set detector (people, vehicles, animals, screens and other everyday things) and an open-vocabulary detector asked for logo, sign, screen, flag, chart, diagram, map, poster and helmet. Add your own phrases with vocabulary (up to 40; each costs a detector pass, so keep it short):

{ "objects": { "vocabulary": ["hard hat", "forklift", "safety vest"] } }

Per upload

Uploads run on Arrow; add an options form field holding JSON. Fields you omit fall back to your workspace’s defaults, then to the deployment’s.

curl https://api.niravi.io/api/v1/videos \
  -H "X-API-Key: $NIRAVI_API_KEY" \
  -F "file=@interview.mp4" \
  -F 'options={"ocr": {"languages": ["en", "hi"]}, "objects": false}'

The upload acknowledgement echoes the effective index_options. A stage takes true / false or an object of its values. Bad options answer 422 invalid_options before anything is stored.

Per workspace

GET /api/v1/index-options lists every stage with its description, default, availability and values, plus your workspace’s overrides (workspace) and the result (effective). PUT the same shape to set the workspace’s defaults (write scope; {} clears them):

curl -X PUT https://api.niravi.io/api/v1/index-options \
  -H "X-API-Key: $NIRAVI_API_KEY" -H "Content-Type: application/json" \
  -d '{"ocr": {"languages": ["en", "hi"]}, "people": false}'

What ran

GET /api/v1/videos/{id} returns index.options (what the run was asked to do) and index.report (what each stage did: ok, off, not_applicable or failed with the reason, counts and timings). A failed stage never fails the whole run: the rest of the index is still written and searchable, and index.stages_failed lists the failed stages (index.degraded is true when there is one), so you can spot a gap without reading the report. A run that cannot finish at all marks the video status: failed, so polling always ends.

Long videos are processed with bounded memory: audio is transcribed in 300-second windows and diarized window by window. A 54-minute 1080p episode indexed in about 22 minutes (about 2.5x real time); uploads are processed one at a time per GPU worker.

To take the whole index of one asset with you (rows and vectors), download its .nmap archive.