FalconVQA Docs
API Reference

Ingestion

POST /videos and POST /videos/url — starting an analysis job from a file or a URL.

Both routes return 202 immediately, because ingestion takes minutes. They end the same way: the video lands in the Storage bucket under its content hash, and every response from then on carries a URL, never a path.


POST /videos

multipart/form-data. Upload a video file and start ingestion.

Fields

FieldTypeDefaultNotes
filefilerequiredThe video
analyzersstringdefault_videoComma-separated ids. Chosen per upload because costs differ wildly: default_video bills per chunk, transcript is free
modestringpresetpreset | weights | interval
presetstringaudio_videomode=preset only: audio | video | audio_video
speaker, silence, cut, semanticfloatmode=weights only; at least one required
intervalfloatmode=interval only: seconds per chunk
min_durationfloat5Ignored when mode=interval
max_durationfloat20Ignored when mode=interval

Example

curl -X POST http://127.0.0.1:8077/videos \
  -H "X-Core-Token: $TOKEN" \
  -F "file=@clip.mp4" \
  -F "analyzers=default_video,diarization" \
  -F "mode=preset" -F "preset=audio_video" \
  -F "min_duration=5" -F "max_duration=20"
{ "job_id": "d9b16a609ab1", "status": "queued", "source": "clip.mp4" }

This route pushes the whole video through the API process and through whatever body-size cap sits in front of it. Convenient for a browser or curl; for anything large, upload straight to Storage and use POST /videos/url instead.


POST /videos/url

application/json. Same fields, with url in place of file. The primary path for a frontend.

Body

FieldTypeDefault
urlstringrequired
analyzersstringdefault_video
modestringpreset
presetstringaudio_video
intervalfloat | nullnull
speaker, silence, cut, semanticfloat | nullnull
min_durationfloat5
max_durationfloat20

Example

curl -X POST http://127.0.0.1:8077/videos/url \
  -H "X-Core-Token: $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com/clip.mp4",
    "analyzers": "default_video,diarization",
    "mode": "preset",
    "preset": "audio_video"
  }'
{ "job_id": "d9b16a609ab1", "status": "queued", "source": "https://example.com/clip.mp4" }

A URL that already points into core's own bucket needs no special case — the bytes still have to come down to be decoded, and the re-upload is skipped because the object is already there.

video_id is the hash of the bytes, so it does not exist until the download finishes. It arrives in the job result along with video_url. Design your rows for that: create them before the id exists, and fill it in from the job.


Chunking modes

A named weighting of the four boundary signals.

{ "url": "…", "mode": "preset", "preset": "video", "min_duration": 5, "max_duration": 20 }
PresetSuits
audioPodcasts, calls, lectures
videoSurveillance, silent footage, b-roll, sports
audio_videoMost footage — interviews, meetings, edited video

See Chunking for what these actually do to retrieval quality.


Re-ingesting

There is no separate re-index endpoint. Ingest is idempotent on the content hash, so handing core the same source again re-analyses the same video in place.

Same source, and…Result
same chunking, same analyzersExisting output is reused; aggregates re-run with caching
same chunking, new analyzersNew analyzers run and are added to the record; existing vectors untouched
different chunkingChunks are replaced; every vector for the video is dropped first

Aggregates recompute automatically whenever the analyzer set changed.


Errors

CodeCause
400Unknown analyzer; mutually exclusive analyzers (transcript + diarization); unknown mode; a mode missing its required parameters; a non-http(s) URL
401Missing or wrong token

A URL that 404s, serves HTML instead of a video, or exceeds VIDEOMIND_MAX_BYTES fails the job, not the request — the download starts after the 202. See Errors.

On this page