FalconVQA Docs
API Reference

Aggregates

Reading and re-running the twelve video-level results.


GET /videos/{video_id}/aggregates

Video-level results. Pass ?aggregator=summary for one, or omit for all.

All

{
  "video_id": "95e110e25070fcfc",
  "available": ["chapters", "events", "ner", "novelty", "stats", "summary"],
  "aggregates": { "summary": { "…": "…" }, "chapters": { "…": "…" } }
}

One

{ "video_id": "95e110e25070fcfc", "aggregator": "summary", "result": { "…": "…" } }

Requesting an aggregate the video does not have is a 400, and the message lists what it does have — which is exactly the correction a caller needs. 404 is reserved for an unknown video.

The twelve

AggregatorDepends onLLMProduces
statsnoCounts over time, busiest/quietest moment, speech totals
noveltynoChunks ranked by how unlike the rest they are, plus outliers
speaker_statsdiarizationnoTalk time, turns, handovers, share per speaker
sentimentdiarizationnoSentiment of spoken language, per speaker and over time
nernoNamed entities across speech, scene text and OCR
summaryyesTiered summaries, finest first, plus key points and topics
chaptersyesConsecutive chunks grouped into titled sections
eventsyesDiscrete timestamped events with actor and category
entitiespeopleyesPeople linked across chunks, with narratives
entity_timelinesentitiesnoPresence and dwell time per person
cooccurrenceentitiesnoWhich people appear together
object_entitiesobject_detectionyesObjects tracked across chunks

An aggregator whose analyzer the video lacks is skipped, not failed.

Shapes

summary

{
  "summary": "…a few sentences covering the whole video",
  "key_points": ["…"],
  "topics": ["…"],
  "depth": 4,
  "tiers": [{ "level": 0, "section_count": 8,
              "sections": [{ "summary": "…", "start": 0.0, "end": 24.0, "chunk_ids": [0, 1, 2] }] }],
  "sections": [ "…tier 0, repeated for retrieval" ],
  "based_on": ["default_video", "diarization"]
}

tiers[0] is the finest level and the last is the whole video. Depth follows length rather than a fixed block size — a 39-chunk video produced 4 tiers of 8 / 4 / 2 / 1 sections.

chapters

{
  "chapters": [{ "title": "Checkout rush", "summary": "…", "first_chunk": 4, "last_chunk": 11,
                 "start": 96.0, "end": 240.0, "chunk_ids": [4, 5, 6, 7, 8, 9, 10, 11] }],
  "based_on": ["default_video"]
}

events

{
  "events": [{ "event": "A customer approaches the register", "chunk_id": 12,
               "actor": "woman in a grey coat", "category": "arrival",
               "start": 240.0, "end": 258.4 }],
  "categories": { "arrival": 4, "transaction": 2 },
  "based_on": ["default_video", "people"]
}

stats

{
  "duration": 300.4,
  "chunks": 39,
  "analyzers": ["default_video", "people"],
  "people": {
    "series": [{ "start": 0.0, "end": 6.9, "people_count": 3 }],
    "min": 0, "max": 11, "mean": 4.2, "total_observations": 164,
    "busiest": { "start": 120.0, "end": 140.0, "count": 11 },
    "quietest": { "start": 0.0, "end": 6.9, "count": 0 }
  },
  "objects": { "distinct": 42, "most_common": [["shopping cart", 31]] }
}

novelty

{
  "basis": "default_video",
  "mean_distance": 0.2841,
  "ranked": [{ "chunk_id": 27, "start": 540.0, "end": 558.0, "novelty": 0.61 }],
  "outliers": [ "…more than two standard deviations from the mean" ]
}

speaker_stats

{
  "speakers": [{ "speaker": "SPEAKER_00", "seconds": 184.2, "turns": 41, "share": 0.62 }],
  "speaker_count": 2, "total_turns": 66, "handovers": 39,
  "total_speech_seconds": 297.1, "dominant_speaker": "SPEAKER_00",
  "timeline": [{ "start": 1.2, "end": 4.8, "speaker": "SPEAKER_00" }]
}

sentiment

{
  "model": "…",
  "overall": { "positive": 0.41, "neutral": 0.5, "negative": 0.09 },
  "dominant": "neutral",
  "per_speaker": [ "…" ],
  "timeline": [ "…" ],
  "note": "Sentiment of language used, not inferred emotion; ASR errors propagate."
}

ner

{
  "entities": [{ "text": "Tesco", "label": "ORG", "count": 6 }],
  "by_label": { "ORG": 4, "PERSON": 2 },
  "labels_used": ["ORG", "PERSON", "GPE"],
  "based_on": ["diarization", "ocr"]
}

entities, entity_timelines, cooccurrence — see Entities.

object_entities

{
  "objects": [ "…linked object tracks with narratives" ],
  "total": 18, "linked": 11, "unlinked": 7, "observations": 240, "narrated": 11,
  "fixtures": [["checkout counter", 39]],
  "people_sightings": 164
}

Fixtures are counted but not tracked: "the counter was present throughout" is true of every frame and tells a search nothing.


POST /videos/{video_id}/aggregates

Re-run aggregators over already-analysed output. Returns 202 and a job_id to poll.

ParamInTypeDefaultNotes
aggregatorsformstringallComma-separated ids
forcequerybooltrueRecompute even when already stored
curl -X POST "http://127.0.0.1:8077/videos/95e110e25070fcfc/aggregates?force=true" \
  -H "X-Core-Token: $TOKEN" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data "aggregators=summary,chapters"
{ "job_id": "9f2c1a77b410", "status": "queued", "video_id": "95e110e25070fcfc" }

Job result

{
  "video_id": "95e110e25070fcfc",
  "ran": ["summary", "chapters"],
  "reused": ["stats", "novelty", "ner"],
  "skipped": ["sentiment", "speaker_stats"],
  "failed": {},
  "aggregates": ["chapters", "ner", "novelty", "stats", "summary"],
  "recomputed_because_analyzers_changed": false,
  "llm_calls_saved": []
}
FieldMeaning
ranComputed this time
reusedAlready stored — pass force=true to recompute
skippedDependencies this video cannot satisfy
failed{aggregator: "TypeName: message"} — one failing does not lose the others' work
aggregatesEverything now stored for the video
recomputed_because_analyzers_changedThe analyzer set changed, so everything was recomputed regardless of force
llm_calls_savedWhich of the reused ones would have billed API calls

Aggregators read stored analyzer output rather than the video, so this costs no re-analysis. It is the cheap half of re-processing — re-summarising or re-linking entities after tuning costs only the LLM calls for the five aggregators that make them.

Aggregates are recomputed automatically when the analyzer set changes. A summary written before people ran describes a video it could not see people in, and serving it would be confidently out of date.

Errors

CodeCause
400Unknown aggregator id
404Unknown video

On this page