Nandemo Analysis

Use Nandemo to register footage, upload to signed URLs, run full or selected analysis jobs, and produce structured video understanding for downstream apps or Dekiru.

How Nandemo Works

Nandemo analyzes each uploaded video source as a timeline, not as a single blob. The first step is to create a source record and upload the bytes. After the file is available, analysis jobs progressively add structure to that source.

Scene-related jobs split the video into timestamped scenes and describe what happens in each scene. Transcript jobs convert speech into timestamped segments and words. Metadata, face detection, and indexing jobs add higher-level fields that are easier for products and agents to query.

  • Register: validate the source and receive a signed upload target.
  • Upload: PUT the raw video bytes to storage using the returned URL and headers.
  • Analyze: run the full pipeline automatically or manually trigger a rerun.
  • Retrieve: read scene understanding, transcript words, metadata, people, speakers, and search results.

Register Videos

Registration validates upload duration against available credits, records the source under the project, and creates a signed URL for every accepted video. Rejected entries include a reason.

Registration does not upload video bytes by itself. It creates the durable source entry under the project and returns a temporary upload contract for each accepted file. Keep the original source name because later API calls identify the video by that name.

{
"videos": [
{ "name": "interview.mp4", "duration": 183.4 }
],
"analysis": {
"trigger": "auto"
}
}

Signed Upload

Upload URLs are short-lived and write-only. When headers are returned, pass them exactly; they can bind analysis metadata into the upload signature.

Treat the signed URL as a storage operation, not a normal Zonic API request. Do not add the project API key unless the returned upload headers ask for it. The upload succeeds when the storage provider accepts the bytes; analysis may start afterward depending on the selected mode and trigger.

const accepted = upload.validation.find(v => v.accepted && v.url)
if (!accepted?.url) throw new Error("Upload rejected")
await fetch(accepted.url, {
method: "PUT",
headers: accepted.headers ?? {},
body: file,
})

Analysis Modes

In cloud mode, object-finalize events normally trigger Nandemo analysis after upload. Manual calls are useful for reruns, corrected context, provider overrides, or post-upload retries.

Full analysis is appropriate when the source is new or when the prior output should be rebuilt as a whole. Selected jobs are better when only one part is stale or failed. For example, a silent video may not need transcript reruns, while a changed metadata prompt may only require metadata and index refreshes.

POST/api/projects/{pid}/videos/{vid}/analysis
curl -X POST "$BASE_URL/projects/$PID/videos/$VID/analysis" \
"${AUTH[@]}" \
-d '{"context_hint":"Two-camera interview with product b-roll"}'

Selected Jobs

Selected jobs rerun only part of Nandemo for one video. This is useful when a transcript needs a new provider, metadata needs a different prompt/model, or indexing should be refreshed after another job has produced new text.

Jobs are ordered around their data dependencies. Scene understanding depends on scene boundaries. Script indexing depends on transcript text. When you choose selected jobs, include the upstream jobs if the upstream data is missing, failed, or intentionally being refreshed.

  • scene_detection: detect shot/scene boundaries and timestamps.
  • transcription: produce transcript segments and word timings when speech exists.
  • scene_understanding: generate visual descriptions for detected scenes.
  • metadata: generate source-level description and labels. Supports outputs, usually ["description","labels"].
  • scene_index: refresh visual-scene search embeddings.
  • script_index: refresh transcript/script search embeddings.
  • face_detection: detect and update people appearances for one video.

Jobs are logical outputs, not necessarily one provider call each. Dependency order still matters: for example, scene_understanding expects scenes, script_index expects transcript text. Key quotes are generated only by asking for them in project chat (or invoking the quotes task directly).

POST/api/projects/{pid}/videos/{vid}/analysis/jobs
curl -X POST "$BASE_URL/projects/$PID/videos/$VID/analysis/jobs" \
"${AUTH[@]}" \
-d '{
"context_hint": "Trade show booth walkthrough",
"jobs": [
{ "type": "transcription", "provider": "azure" },
{ "type": "scene_understanding", "model": "gemini-3.1-flash" },
{ "type": "metadata", "outputs": ["description", "labels"] },
{ "type": "script_index" },
{ "type": "scene_index" }
]
}'

Troubleshooting

  • If accepted is false, check the returned reason before uploading.
  • If a signed URL expires, register again or ask Zonic for a refresh endpoint if your workflow needs long upload windows.
  • If analysis output is empty, first verify GET /projects/{pid}/videos includes the source name.