Skip to main content

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 Search request_id) and the API:
  1. Matches the selfie against faces detected across the event’s source videos.
  2. Groups matched frames into continuous time segments.
  3. Creates one clip per matched source video.
  4. Returns playable clip URLs you can hand to your UI.
The 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 Search request_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.
This lets your client trigger the expensive operation once, then read the stored result without re-uploading the selfie. The request_id follows the same idempotency model as Face Search — see Conventions.
Reuse a request_id returned by Face Search when you start a video clipping search. The same selfie record is updated, so the user gets photo and video results from a single upload.

Endpoints

POST /video-clipping/search-by-selfie — Start a Search

Accepts either a selfie image or a Face Search request_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

To reuse an existing 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

On a successful POST, 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

Treat POST as the start step. Use the GET endpoint to poll while status is processing and to recover stored results after refreshes or retries.

Example Request

Example Response

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.
A new POST (with a fresh request_id or no request_id) re-runs the full pipeline and is treated as a new billable search. Avoid issuing fresh POSTs on every refresh — use GET to recover stored results.

Response Models

Error Responses

See Errors for canonical descriptions and retry guidance.