Build

Sidecars

JSON metadata on every version, by namespace. The built-in schemas, writing your own, and keeping a namespace to one tool.

A sidecar is one JSON document attached to one version of a file, under a namespace. A video's version can carry its media facts, a transcript, AI tags, the prompt that generated it, people's ratings and your QC results, each in its own namespace and each written by whoever owns that job.

Sidecars are what search reads, what the apps show under Info, what compare diffs, and what AI agents read through MCP instead of downloading the file.

Read and write

ToCall
Every sidecar of a versionGET /v1/spaces/{sid}/versions/{vid}/sidecars
One namespaceGET /v1/spaces/{sid}/versions/{vid}/sidecars/{ns}
Write (replaces that namespace's document)PUT /v1/spaces/{sid}/versions/{vid}/sidecars/{ns} with {"doc": {…}}
RemoveDELETE /v1/spaces/{sid}/versions/{vid}/sidecars/{ns}
curl -X PUT "https://side.example.com/v1/spaces/$SPACE/versions/$VERSION/sidecars/x-acme.qc" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" -H "Content-Type: application/json" \
  -d '{"doc": {"passed": false, "issues": [{"at_s": 12.4, "kind": "dropped_frame"}]}, "producer": {"name": "acme-qc", "version": "1.4"}}'

Writing needs editor rights and the sidecars:write scope, or sidecars:write:<ns> for one namespace (sidecars:write:x-acme.* for a family). producer records which tool wrote it; the apps show it.

Built-in namespaces

Built-in namespaces are checked against a JSON Schema on write (in proto/sidecar/ in the repository), so every tool can rely on their shape.

NamespaceWritten byHolds
coreThe servercontent_hash, size, mime, author_id, device_id, client_mtime, created_at
mediaThe server (ffprobe)duration_s, container, bitrate, width, height (as displayed), fps, video_codec, audio_codec, audio_channels, creation_time
transcriptside.transcribe, or your tooltext, language, duration, segments (start, end, text, speaker), model, provider
ai.tagsside.tags, or your tooldescription, tags, shot_type, setting, mood, people, text_on_screen, frames, model
ai.generationThe tool that generated the assettool (required), model, provider, prompt, negative_prompt, seed, parameters, inputs, job_id, cost, regenerate_url
userPeople in the appstags, rating, label, note, status (draft, review, approved…)
derivedActions that make filesfrom (node_id, version_id, path), action, params, run_id

core and media are written only by the server. When a new version is saved, its user and ai.generation sidecars are carried over from the previous version (with producer.inherited_from), because a re-export keeps the same prompt and the same rating; the others describe the bytes and are made again.

Recording how an AI asset was made

If your tool generates images or video, write ai.generation when you upload. Search finds files by their prompt, and the apps show the model and a link back to regenerate.

JSON
{
  "tool": "cliptap",
  "model": "video-model-x",
  "prompt": "A fishing harbor at night, slow dolly in, rain",
  "seed": 1234,
  "inputs": [{ "role": "reference", "node_id": "nod_…", "version_id": "ver_…" }],
  "regenerate_url": "https://cliptap.example/jobs/9f2c"
}

Your own namespaces

Custom namespaces start with x-, usually x-<company>.<tool> (x-acme.qc). Any JSON object up to the server's size limit is accepted; nothing validates it but you.

One writer per namespace

A space manager can hand a namespace to one member, usually an agent. From then on only that member can write it in that space and everyone else can only read it, so two AI tools can't overwrite each other's results.

Shell
sidespace namespace claim "Film A" x-qc "Clip Tagger"
sidespace namespace list "Film A"
sidespace namespace release "Film A" x-qc

ai.generation and x-… namespaces can be claimed. core and media belong to the server, and user is everyone's.