FrameThrower Search API
Find frames by text, image or colour
Find frames by text, image or colour
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/framethrower:framethrower-search-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: FrameThrower Search API
version: 1.0.0
summary: Cinematography reference search over 5,489 films.
description: Search a film stills library indexed frame by frame on lighting, lens character, shot size, camera angle, colour palette and mood — in plain language, by reference image, or by colour.
contact:
name: FrameThrower
url: https://framethrower.ai/developers
email: contact@framethrower.ai
license:
name: Proprietary
url: https://framethrower.ai/legal/tos
termsOfService: https://framethrower.ai/legal/tos
servers:
- url: https://framethrower.ai/api/v1
description: Production
security:
- bearerAuth: []
tags:
- name: Search
description: Find frames by text, image or colour
paths:
/search:
post:
tags:
- Search
operationId: search
summary: Search by text
description: 'Describe a mood, scene or visual concept in natural language.
**Cost: 2 credits.** $1 = 1,000 credits. Returns 402 when the balance is short.'
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- query
properties:
query:
type: string
description: Natural-language query
examples:
- neon-lit rainy street at night
limit:
type: integer
minimum: 1
maximum: 50
default: 20
mode:
type: string
enum:
- hybrid
- description
default: hybrid
description: hybrid fuses the image and scene-description embeddings via reciprocal rank fusion — use it unless you have a reason not to. description ranks on the written descriptions only, better when the query is about story, action or named objects.
color:
type: string
pattern: ^#?[0-9a-fA-F]{6}$
examples:
- '#1f7a8c'
description: 'Bias the search toward frames dominated by this colour, without abandoning the query. Fused with the text ranking rather than replacing it — "ocean" with #1f7a8c returns teal seas, not teal anything. For colour alone, use /search/color.'
enhance:
type: boolean
default: false
description: 'Rewrite the query into the descriptive register the frames were embedded from before searching — "man on fire" becomes a full sentence. Benchmarked recall@10: 0.72 raw, 0.88 enhanced. This is what the website does by default. Adds ~1s on a cache miss and falls back to the raw query on error. When it fires, the rewritten text comes back as meta.enhancedQuery — send that as the query for later pages so every page ranks in the same neighbourhood.'
offset:
type: integer
minimum: 0
maximum: 500
default: 0
description: 'Skip this many results before returning. Use with limit to page: offset 0 then 50 then 100. Capped at 500 — ranking past that is noise, and the candidate pool is built to offset+limit.'
shot_type:
type: string
enum:
- medium
- closeup
- wide
- fullbody
- establishing
description: Shot size. Aliased, so close-up and closeup both land.
camera_angle:
type: string
enum:
- eye_level
- high_angle
- low_angle
- top_down
- overhead
- worms_eye
- dutch_angle
- pov
- birds_eye
description: Camera angle.
time_of_day:
type: string
enum:
- night
- day
- interior_indeterminate
- golden_hour
- dusk
- blue_hour
- dawn
- overcast
description: Time of day / light.
setting:
type: string
enum:
- interior
- exterior
- both
description: Interior or exterior.
visual_style:
type: string
enum:
- live_action
- cg_stylized
- anime
- cg_photorealistic
- cartoon_2d
- stop_motion
- mixed_media
- rotoscope
- noir
- watercolor
- minimalist
- documentary
- expressionist
- painterly
- surreal
description: Medium and treatment.
lens:
type: string
enum:
- anamorphic
- spherical
- vintage_soft
description: Lens character.
lighting:
type: string
enum:
- sun
- window
- moonlight
- practical
- neon
- fluorescent
- firelight
- candlelight
- streetlamp
- screen_glow
- headlight
- lightning
description: What is lighting the frame — a different question from the time of day.
depth_of_field:
type: string
enum:
- shallow
- deep
- rack_focus
- medium
description: Focus depth.
director:
type: string
genre:
type: string
film_title:
type: string
era:
type: string
enum:
- ancient
- medieval
- renaissance
- 1800s
- 1900s_1910s
- 1920s
- 1930s
- 1940s
- 1950s
- 1960s
- 1970s
- 1980s
- 1990s
- 2000s
- 2010s
- contemporary
- near_future
- far_future
- fantasy
description: The era depicted on screen, not the release year.
year_min:
type: integer
year_max:
type: integer
responses:
'200':
description: Matching frames
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Frame'
meta:
type: object
additionalProperties: true
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/InsufficientCredits'
/search/image:
post:
tags:
- Search
operationId: searchByImage
summary: Search by reference image
description: 'Find frames matching a reference image by visual similarity, colour and semantic meaning.
**Cost: 10 credits.** $1 = 1,000 credits. Returns 402 when the balance is short.'
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- imageUrl
properties:
imageUrl:
type: string
format: uri
limit:
type: integer
minimum: 1
maximum: 50
default: 20
responses:
'200':
description: Matching frames
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Frame'
meta:
type: object
additionalProperties: true
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/InsufficientCredits'
/search/color:
post:
tags:
- Search
operationId: searchByColor
summary: Search by colour
description: 'Find frames dominated by a hex colour or a blended palette. Use `color` OR `colors`, not both.
**Cost: 2 credits.** $1 = 1,000 credits. Returns 402 when the balance is short.'
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
color:
type: string
pattern: ^#?[0-9a-fA-F]{6}$
examples:
- '#e94560'
colors:
type: array
maxItems: 6
items:
type: string
pattern: ^#?[0-9a-fA-F]{6}$
limit:
type: integer
minimum: 1
maximum: 50
default: 20
responses:
'200':
description: Matching frames
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Frame'
meta:
type: object
additionalProperties: true
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/InsufficientCredits'
/browse:
post:
tags:
- Search
operationId: browse
summary: Filter by craft attribute
description: 'Filter frames by cinematography attributes — no text query needed. Combine any filters. Common spellings ("close-up", "magic hour") are normalised for you; anything unrecognised comes back in `meta.hint` rather than as a silent empty result.
**Cost: 2 credits.** $1 = 1,000 credits. Returns 402 when the balance is short.'
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
shot_type:
type: string
enum:
- medium
- closeup
- wide
- fullbody
- establishing
description: Shot size
lens_character:
type: string
enum:
- anamorphic
- spherical
- vintage_soft
description: Lens character
setting:
type: string
enum:
- interior
- exterior
- both
description: Interior or exterior
time_of_day:
type: string
enum:
- night
- day
- interior_indeterminate
- golden_hour
- dusk
- blue_hour
- dawn
- overcast
description: Time of day
camera_angle:
type: string
enum:
- eye_level
- high_angle
- low_angle
- top_down
- overhead
- worms_eye
- dutch_angle
- pov
- birds_eye
description: Camera angle
visual_style:
type: string
enum:
- live_action
- cg_stylized
- anime
- cg_photorealistic
- cartoon_2d
- stop_motion
- mixed_media
- rotoscope
- noir
- watercolor
- minimalist
- documentary
- expressionist
- painterly
- surreal
description: Visual style
director:
type: string
description: Free text, e.g. "Ridley Scott"
genre:
type: string
description: Free text, e.g. "Science Fiction"
era:
type: string
description: Depicted era, e.g. "1980s", "near_future"
year_min:
type: integer
year_max:
type: integer
limit:
type: integer
minimum: 1
maximum: 50
default: 20
responses:
'200':
description: Matching frames
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Frame'
meta:
type: object
additionalProperties: true
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/InsufficientCredits'
/similar:
post:
tags:
- Search
operationId: findSimilar
summary: Find similar frames
description: 'More frames like one already returned. Pass several ids to search from their centroid.
**Cost: 2 credits.** $1 = 1,000 credits. Returns 402 when the balance is short.'
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
frameId:
type: string
frameIds:
type: array
items:
type: string
mode:
type: string
enum:
- semantic
- visual
- color
default: semantic
limit:
type: integer
minimum: 1
maximum: 50
default: 20
responses:
'200':
description: Matching frames
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Frame'
meta:
type: object
additionalProperties: true
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/InsufficientCredits'
components:
responses:
InsufficientCredits:
description: Not enough credits. The body carries everything needed to recover without reading docs.
content:
application/json:
schema:
type: object
properties:
error:
type: string
code:
type: string
const: insufficient_credits
cost:
type: integer
balance:
type: integer
buy_credits:
type: string
format: uri
Unauthorized:
description: Missing, malformed, revoked or unknown token
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
BadRequest:
description: Malformed request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
Frame:
type: object
description: A single film frame. Thumbnails and deep links only — never raw image bytes.
properties:
id:
type: string
url:
type: string
format: uri
description: Deep link to this frame on FrameThrower
thumbnail:
type: string
format: uri
depthUrl:
type: string
format: uri
nullable: true
description: Precomputed depth map (Depth-Anything V2), WebP, same pixel dimensions as the frame — feed straight to a depth ControlNet. null when the frame has no map; a stale URL 404s, in which case compute depth locally. Never falls back to the colour image.
score:
type: number
description: Relevance, when the call was a search
film:
type: object
properties:
title:
type: string
year:
type: integer
slug:
type: string
frameCount:
type: integer
director:
type: string
cinematographer:
type: string
shot_type:
type: string
lens_character:
type: string
camera_angle:
type: string
setting:
type: string
time_of_day:
type: string
visual_style:
type: string
colorPalette:
type: array
items:
type: string
description: Dominant colours as hex
colorDescription:
type: string
prompt:
type: string
description: Stored descriptive prompt for the frame
Error:
type: object
properties:
error:
type: string
docs:
type: string
api_reference:
type: string
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: Personal access token, prefix `ft_`. Create one at https://framethrower.ai/settings?tab=api — free accounts included, no plan required.
externalDocs:
url: https://framethrower.ai/developers
description: Developer documentation