← Back to index Logout

Search APIs

POST /api/v1/search/smart

Auth: Required Scope: global / file-level

Semantic vector search using EmbeddingGemma-300m. Generates a query embedding via EmbeddingGemma (port 11436), then searches pgvector story_parent and llm_parent chunks by cosine similarity.

Request Parameters

Field Type Required Default Description
query string Yes Search text
file_uuid string No File UUID to search within. If omitted, searches all files (global search)
limit integer No 5 Max results to return
page integer No 1 Page number
page_size integer No 5 Items per page

Example (Global Search)

curl -s -X POST "$API/api/v1/search/smart" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JWT" \
  -d '{"query": "Audrey Hepburn"}'

Example (File-specific Search)

curl -s -X POST "$API/api/v1/search/smart" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JWT" \
  -d '{"file_uuid": "'"$FILE_UUID"'", "query": "Audrey Hepburn"}'

Response (200)

{
  "query": "Audrey Hepburn",
  "results": [
    {
      "file_uuid": "a6fb22eebefaef17e62af874997c5944",
      "parent_id": 1087822,
      "scene_order": 1087822,
      "start_frame": 104438,
      "end_frame": 104538,
      "fps": 24.0,
      "start_time": 4351.6,
      "end_time": 4355.76,
      "summary": "[4352s-4356s, 4s] Cast: Audrey Hepburn. Total: 2 lines, 10 words. Speakers: Audrey Hepburn (2 lines)",
      "similarity": 0.67
    }
  ],
  "page": 1,
  "page_size": 5,
  "strategy": "semantic_vector_search"
}
Field Type Description
results[].file_uuid string File UUID where result was found

POST /api/v1/search/universal

Auth: Required Scope: global / file-level

Multi-type BM25 full-text search across chunks, frames, and persons. Uses PostgreSQL tsvector.

Request Parameters

Field Type Required Default Description
query string Yes Search text
file_uuid string No Restrict to specific file. If omitted, searches all files (global search)
types string[] No ["chunk","frame","person"] Search types
limit integer No 10 Max results per type
page integer No 1 Page number
page_size integer No 20 Items per page

Example (Global Search)

curl -s -X POST "$API/api/v1/search/universal" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JWT" \
  -d '{"query": "Cary Grant"}'

Example (File-specific Search)

curl -s -X POST "$API/api/v1/search/universal" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JWT" \
  -d '{"file_uuid": "'"$FILE_UUID"'", "query": "Cary Grant"}'

Response (200)

{
  "results": [
    {
      "type": "chunk",
      "file_uuid": "a6fb22eebefaef17e62af874997c5944",
      "chunk_id": "bd80fec92b0b6963d177a2c55bf713e2_2",
      "chunk_type": "story_child",
      "start_frame": 5103,
      "end_frame": 5127,
      "start_time": 212.64,
      "end_time": 213.64,
      "text": "[213s-214s] Cary Grant: \"Olá!\"",
      "score": 0.9
    },
    {
      "type": "frame",
      "file_uuid": "a6fb22eebefaef17e62af874997c5944",
      "frame_number": 5105,
      "timestamp": 212.72,
      "score": 0.7,
      "objects": null,
      "ocr_texts": null,
      "faces": null
    },
    {
      "type": "person",
      "file_uuid": "a6fb22eebefaef17e62af874997c5944",
      "identity_id": 12,
      "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4",
      "name": "Cary Grant",
      "appearance_count": 542,
      "score": 0.95
    }
  ],
  "total": 20,
  "took_ms": 18
}
Field Type Description
results[].type string Result type: chunk, frame, or person
results[].file_uuid string File UUID where result was found (all types)

POST /api/v1/search/frames

Auth: Required Scope: global / file-level

Search frames by YOLO objects, OCR text, face IDs, or pose detections. Filters frames based on visual content detected during processing.

Request Parameters

Field Type Required Default Description
file_uuid string No Restrict to specific file
object_class string No Filter by YOLO object class (e.g., person, car, dog)
ocr_text string No Filter by OCR text content (ILIKE match)
face_id string No Filter by face detection ID
time_range [float, float] No Filter by time range [start_secs, end_secs]
limit integer No 100 Max results

Example

# Search for frames containing "person" objects
curl -s -X POST "$API/api/v1/search/frames" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $KEY" \
  -d '{"file_uuid": "'"$FILE_UUID"'", "object_class": "person", "limit": 20}'

# Search for frames with specific OCR text
curl -s -X POST "$API/api/v1/search/frames" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $KEY" \
  -d '{"file_uuid": "'"$FILE_UUID"'", "ocr_text": "hello", "time_range": [10.0, 30.0]}'

Response (200)

{
  "frames": [
    {
      "frame_number": 1200,
      "timestamp": 50.0,
      "file_uuid": "d3f9ae8e471a1fc4d47022c66091b920",
      "objects": [{"class": "person", "confidence": 0.95, "bbox": [100, 50, 300, 400]}],
      "ocr_texts": ["Hello World"],
      "faces": [{"face_id": "face_42", "confidence": 0.88}],
      "pose_persons": [{"trace_id": 2, "bbox": [120, 60, 280, 380]}]
    }
  ],
  "total": 15
}
Field Type Description
frames array Array of matching frame objects
frames[].frame_number integer Frame number in video
frames[].timestamp float Timestamp in seconds
frames[].file_uuid string File UUID
frames[].objects array/null YOLO detections in this frame
frames[].ocr_texts array/null OCR text strings in this frame
frames[].faces array/null Face detections in this frame
frames[].pose_persons array/null Pose-detected persons in this frame
total integer Total matching frame count

POST /api/v1/search/llm-smart

Auth: Required Scope: global / file-level

Smart search with LLM re-ranking. First fetches candidate results via RRF (Reciprocal Rank Fusion) using the existing smart search, then uses an LLM (Gemma4 on port 8000) to re-rank candidates by relevance to the query.

Request Parameters

Field Type Required Default Description
query string Yes Search text
file_uuid string No File UUID to search within
limit integer No 10 Max results to return

Pipeline

  1. smart_search  fetch N candidates (limit × 3, clamped 10-20)
  2. LLM rerank    re-order by relevance using Gemma4
  3. trim          return top `limit` results

Example

curl -s -X POST "$API/api/v1/search/llm-smart" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $KEY" \
  -d '{"query": "two people having a conversation about business", "limit": 5}'

Response (200)

{
  "query": "two people having a conversation about business",
  "results": [
    {
      "file_uuid": "d3f9ae8e471a1fc4d47022c66091b920",
      "parent_id": 1234,
      "scene_order": 1234,
      "start_frame": 5000,
      "end_frame": 5200,
      "fps": 24.0,
      "start_time": 208.3,
      "end_time": 216.7,
      "summary": "[208s-217s, 9s] Two people discussing project timeline...",
      "similarity": 0.72
    }
  ],
  "page": 1,
  "page_size": 5,
  "strategy": "llm_reranked"
}
Field Type Description
strategy string Always "llm_reranked" for this endpoint
results array Re-ranked search results (same format as smart search)

Fallback

If LLM reranking fails (model unavailable, timeout), falls back to RRF order without error.


Visual Search

Auth: Required Scope: global / file-level

Search text chunks → find associated identities. Returns chunks where face detections overlap with text content.

Query Parameters

Field Type Required Default Description
q string Yes Search text (ILIKE match)
file_uuid string No Restrict to specific file. If omitted, searches all files (global search)
limit integer No 50 Max results
page integer No 1 Page number
page_size integer No 50 Items per page

Example (Global Search)

curl -s "$API/api/v1/search/identity_text?q=love" -H "X-API-Key: $KEY"

Example (File-specific Search)

curl -s "$API/api/v1/search/identity_text?file_uuid=$FILE_UUID&q=love" -H "X-API-Key: $KEY"

Response (200)

{
  "success": true,
  "total": 5,
  "results": [
    {
      "file_uuid": "a6fb22eebefaef17e62af874997c5944",
      "chunk_id": "llm_parent_..._256_270",
      "start_time": 256.256,
      "end_time": 270.228,
      "text_content": "...lack of affection...",
      "identity_id": 9,
      "identity_name": "Audrey Hepburn",
      "identity_source": "tmdb",
      "trace_id": 94
    }
  ]
}
Field Type Description
results[].file_uuid string File UUID where chunk was found
results[].identity_id integer Identity ID if face was detected
results[].trace_id integer Face trace ID

Visual Search (Planned)

Method Endpoint Status Description
POST /api/v1/search/visual Not implemented Search visual chunks
POST /api/v1/search/visual/class Not implemented Search by object class
POST /api/v1/search/visual/density Not implemented Search by object density
POST /api/v1/search/visual/combination Not implemented Search by object combination
POST /api/v1/search/visual/stats Not implemented Visual chunk statistics

Embedding Model

Detail Value
Model EmbeddingGemma-300m
Endpoint POST /api/v1/embeddings on port 11436
Dimension 768
Storage pgvector (chunk.embedding column)

Updated: 2026-06-20 — Added llm-smart search, completed frames search documentation, marked visual search as planned