---
title: "Semantic search over the org's own footage"
method: GET
path: "/v1/media/search"
tags: ["media"]
---

# Semantic search over the org's own footage

`GET /v1/media/search`

## Request

- Base URL: `https://api.cueframe.ai`
- URL: `https://api.cueframe.ai/v1/media/search`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.cueframe.ai/api/auth/mcp/authorize`, token URL `https://api.cueframe.ai/api/auth/mcp/token`, scopes: `media:read`)
  - API key in header `PAYMENT-SIGNATURE`

Find MOMENTS in your library by describing what they look like. The query uses the same visual-semantic index as the footage, so it matches on visual content — "wide shot of a speaker at a whiteboard", "hands on a keyboard", "city skyline at dusk" — including shots nobody talks about (which is where transcript search fails). Results are time-ranged: feed `mediaId` + `startSec`/`endSec` straight into apply_composition as a clip. `q` is required; `limit` defaults to 10 and caps at 25. `indexing` reports missing chunks observed in a bounded membership window; false does not prove complete coverage. Inspect `coverage` for scope and limits. Empty results mean retrieval returned no hits, not that no suitable footage exists. Optional repeated `mediaId` parameters restrict retrieval before top-k truncation (maximum 32).

## Query parameters

- `projectId` string
- `mediaId` string[]
- `q` string, required
- `limit` integer

## Response `200`

Matching moments, best first.

- LibrarySearchResponse: Semantic retrieval over authorized footage; explicit media scope applies before candidate truncation.
  - `results` LibrarySearchResult[], required: Ranked retrieved moments. Empty results do not prove absence of suitable footage.
    - `mediaId` string, required: The media item this moment belongs to — feed it to apply_composition as a clip source, or GET /v1/media/{id}/context for its faces/beat/word grids.
    - `name` string, required: The media item's name, so a result is readable without a second call.
    - `score` number, required: Cosine similarity between the query text and the chunk's frame, in [-1, 1]. Higher is closer. Compare scores WITHIN one response; absolute values are not calibrated across queries.
    - `startSec` number, required: Moment start, SECONDS from the media item's start.
    - `endSec` number, required: Moment end, SECONDS from the media item's start.
    - `thumbUrl` string, nullable, required: Presigned URL for the media item's thumbnail, or null when it has none. This is the ITEM's thumbnail, not a still of this moment — render a still of the exact range with preview_frame.
  - `indexing` boolean, required: Missing chunks observed in the bounded coverage window; false does not establish whole-library completeness.
  - `coverage` object, required: Declared scope and bounded membership evidence. Legacy chunk existence cannot certify complete interval or generation coverage.
    - `indexing` boolean, required
    - `hasAnyIndexed` boolean, required
    - `scope` 'workspace' | 'explicit_media' | 'project', required
    - `examinedMedia` integer, required
    - `membershipComplete` boolean, required
    - `analysisComplete` false, required
    - `scopedIndexReady` boolean, required

## Other responses

- `400`: Bad request — validation_error / invalid_cursor / invalid_query.
- `401`: Missing or invalid Authorization header.
- `402`: Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).
- `403`: Forbidden — permission insufficient.
- `404`: Resource not found.
- `409`: Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.
- `429`: Rate limited. Retry-After header present.
- `500`: Internal error.
- `503`: Service unavailable — billing_unavailable / honest-503 for runtime deps.

---

[API](https://skmtc.dev/cueframe/apis/cueframe-api.md) · [All operations](https://skmtc.dev/cueframe/apis/cueframe-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cueframe/apis/cueframe-api/revisions/8f9bfe362b4a?raw)
