The Short Answer
To search what you generate on fal, send each output URL to a Mixpeek bucket, point a collection at that bucket with the multimodal extractor, and query a retriever in plain language. Three API calls, and nothing has to be downloaded or re-encoded first: a blob takes the fal output URL directly, extraction runs when the object arrives, and from then on "drone shot over water at dusk" returns the clips that match, not the filenames that match.

Why generated video gets lost
Generation speed is the problem that creates this one. A model that renders faster than real time produces more clips in an afternoon than a team can name, and the artifact it hands back is a URL ending in a hash. Nothing in that URL says whether the shot is a drone pass, an interior, or the third variant of the one the client rejected.
So the library grows and the only index is whatever the person who ran the job typed into a spreadsheet. Prompts help less than people expect: the prompt is what you asked for, not what came back, and the gap between those two is exactly the thing you are searching for later.
The fix is to index the output rather than the request. That means extracting features from the rendered frames and audio, then querying those.
The three calls
Each blob carries the fal output URL in
data. Mixpeek fetches it, so the file never passes through your machine.# 1. bucket: land every clip fal renders
POST /v1/buckets/{bucket_identifier}/objects
{"blobs":[{"property":"video","type":"video","data":"https://fal.media/files/.../output.mp4"}]}
# 2. collection: multimodal extraction runs on arrival
POST /v1/collections
{"collection_name":"renders",
"source":{"type":"bucket","bucket_ids":["{bucket_identifier}"]},
"feature_extractor":{"feature_extractor_name":"multimodal_extractor","version":"v1"}}
# 3. retriever: search everything you generated
POST /v1/retrievers/{retriever_id}/execute
{"inputs":{"query":"drone shot over water at dusk"}}What each call is doing
The bucket is the landing zone and the unit of ingestion.
property names the field in the bucket schema the blob belongs to, type is the schema field type, and data accepts an HTTP, HTTPS or S3 URL directly. Passing a URL rather than bytes is what keeps a fal render out of your egress bill.The collection is where extraction is declared, once, rather than per file. Point it at the bucket and every object that arrives afterwards is processed on the same terms.
multimodal_extractor handles frames, audio and any on-screen text together, so a clip becomes several kinds of feature rather than one embedding.The retriever is the query contract. It takes plain language and returns matching documents with scores, and because extraction happened at the segment level the result carries the timestamp of the moment that matched, not just the file that contains it.
Adding the prompt as metadata
The prompt is worth keeping even though it is not what you search. Attach it as blob metadata and it is promoted onto the object at ingest, so it comes back as a filterable field beside the semantic match:
POST /v1/buckets/{bucket_identifier}/objects
{"blobs":[{"property":"video","type":"video",
"data":"https://fal.media/files/.../output.mp4",
"metadata":{"prompt":"aerial drone, coastline, golden hour","model":"fal-video","seed":41823}}]}Frequently Asked Questions
Does this work for images and audio from fal, not just video?
Yes. The
type field takes image, audio, pdf and text alongside video, and the multimodal extractor handles each. The only thing that changes is the property and type on the blob. A bucket can hold several properties, so one object can carry a render, its thumbnail and its prompt text together and be retrieved as a unit.Do I have to move files off fal?
No.
data takes the fal output URL and Mixpeek fetches it, so the file does not pass through your infrastructure on the way in. If you would rather keep the canonical copy in storage you control, land the render in S3, GCS or Azure Blob first and point a storage connector at that instead; the rest of the flow is identical.What does the retriever actually search?
The features the extractor produced, not the filename and not the prompt. For video that means frame-level and segment-level representations plus any speech and on-screen text, which is why a query describing a shot works on a file whose name is a hash. The prompt is searchable too if you attach it as metadata, but as a filter rather than as the semantic match.
How is this different from tagging clips at generation time?
Tagging captures what you expected; extraction captures what arrived. Those diverge constantly with generative video, and the divergence is usually the reason you are searching. Tags also fix your vocabulary at write time, so a query nobody anticipated returns nothing, while embeddings let a description written months later still match.
Does this scale to a back catalogue of renders?
The pattern is the same for one clip and for a hundred thousand: the collection processes whatever lands in the bucket. Extraction is the dominant cost and it is paid once per object, so a large back catalogue is a one-time backfill rather than a recurring charge. Deduplicate first if the archive holds many variants of the same render, since extraction on near-identical clips is the easiest cost to avoid.