FrameThrower Search API

Find frames by text, image or colour

Operations 5

POST /search/image Search by reference image #
POST /search/color Search by colour #
POST /browse Filter by craft attribute #
POST /similar Find similar frames #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • 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.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/framethrower:framethrower-search-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

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 Specification

framethrower-search-api-openapi.yml Raw ↑
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