Overview
Video Clipping Search is the API surface for 9Pic Motion, our selfie + BIB-driven video clipping pipeline. It finds the moments where a participant appears in the event’s videos and returns short playable clip URLs for those moments. The participant uploads a selfie (or reuses a Face Searchrequest_id) and the API:
- Matches the selfie against faces detected across the event’s source videos.
- Groups matched frames into continuous time segments.
- Creates one clip per matched source video.
- Returns playable clip URLs you can hand to your UI.
POST call starts clip creation and returns a request_id. The GET endpoint reads the stored result by request_id, so clients can safely poll, recover, or refresh the final clip payload. The same request_id is shared with Face Search, so a single selfie upload can power both photo and video discovery — and once Face Search has run, you can start a clip with just that request_id and no file upload, because the matching frames were already computed.
Video Clipping Search must be enabled for the event. Both
video_search (the event-level toggle) and video_selfie_search (the selfie-driven video toggle) returned by Event Details must be true.Why Two Endpoints?
Producing a video clip is substantially more expensive than searching for photos: it has to scan every video frame index, run face matching, decide on the best time window per source video, and generate playable video clips. We split this into:POST /video-clipping/search-by-selfie— accepts the selfie or a Face Searchrequest_id, persists the record, and starts clip generation.GET /video-clipping/{request_id}— reads the cached result and returns a structured status payload with clip URLs once available.
request_id follows the same idempotency model as Face Search — see Conventions.
Endpoints
POST /video-clipping/search-by-selfie — Start a Search
Accepts either a selfie image or a Face Searchrequest_id, persists the request, and starts video clip generation. Returns the request_id and current status.
Path Parameters
Multipart Form Fields
You must provide a
file, a request_id, or both. A request_id with no file only works after a Face Search has run for that request_id (so the matching frames exist); otherwise the call returns 400.Example Request
request_id (for example one returned by Face Search) while still uploading a selfie, add -F "request_id=<uuid>" (cURL), data={"request_id": "<uuid>"} (Python), or formData.append("request_id", "<uuid>") (JavaScript).
To recreate deleted or expired clips for an existing request, send the same request_id with force_recreate=true.
To clip without re-uploading — the recommended flow right after a Face Search — send only the request_id and omit the file. 9Pic reuses the matching frames it already computed and starts clipping:
Example Response
processing means the request was accepted and clip generation has started. Use the returned request_id with the GET endpoint to read the latest stored state. If no video frames match, POST can return a terminal empty state such as no_matches.
GET /video-clipping/ — Read Stored Results
Returns the current stored status of the search and any generated clips. Safe to call repeatedly.Path Parameters
Status Lifecycle
Example Request
Example Response
- completed
- processing
- no_matches
- no_segments
- clip_failed
- failed
Recommended Integration Sequence — “POST once, GET many”
1
Confirm video clipping is enabled
Call Event Details and check that both
video_search and video_selfie_search are true. If either is false, do not show the video clipping CTA.2
POST once
Upload the selfie to
POST /video-clipping/search-by-selfie. Persist the request_id from the response (URL state, local storage, or your DB).
If you already have a request_id from Face Search, send only that request_id (no file) to clip from the segments Face Search already computed.3
Read stored results
If the POST response is not terminal, or if the user refreshes the page, call
GET /video-clipping/{request_id} to read the stored status and clips.4
Render or fall back
On
completed, render the clips from videos[].video_url. Use videos[].download_url for downloads only when videos[].download_status is ready.
On no_matches / no_segments, show a friendly empty state (the selfie did not produce a clip).
On clip_failed / failed, surface a retry CTA — a fresh POST (with a new selfie) is the most reliable next step.Response Models
Error Responses
See Errors for canonical descriptions and retry guidance.

