Pexafy Search API

Finding photos.

Operations 4

GET /search/photos Search photos by describing them #
POST /search/photos/by-image Search photos by handing over an image #
GET /api/v1/search/photos Search photos by text #
POST /api/v1/search/photos Search photos by image #

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/pexafy-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 email required.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

pexafy-search-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Pexafy Search API
  x-refined-note:
  - x-logo differs across the merged source definitions and was not carried
  version: '1.0'
  description: 'Operations tagged search across 2 of this provider''s published API definitions: pexafy-openapi-v1.3.0.json, pexafy-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.pexafy.com/api/v1
  description: Production
- url: https://api.pexafy.com
  description: Production
tags:
- name: search
  description: Finding photos.
paths:
  /search/photos:
    get:
      operationId: searchPhotos
      tags:
      - search
      summary: Search photos by describing them
      description: 'Ranking is semantic, not keyword based, so a full sentence outranks a pile of nouns: ''two people hiking on a ridge at dawn'' carries the relationships between the words and ''hiking dawn people'' throws them away.


        Filters are applied after the semantic match, which means a narrow filter on a broad query returns fewer results than the same filter on a narrow query. There is no total count and no page number; follow pagination.next_cursor.'
      parameters:
      - name: q
        in: query
        description: What you are looking for, in words.
        schema:
          type: string
          minLength: 1
          maxLength: 400
        required: true
      - name: color_name
        in: query
        description: Restrict to one dominant colour. The API filters on a single colour; passing several is rejected rather than silently using the last one.
        schema:
          $ref: '#/components/schemas/ColorName'
      - name: color_hex
        in: query
        description: Restrict to photos near one hex colour, used with color_tolerance.
        schema:
          type: string
          pattern: ^#?[0-9a-fA-F]{6}$
      - name: color_tolerance
        in: query
        description: How far from color_hex a photo may sit, in the same units as the colour distance the indexer stores.
        schema:
          type: integer
          minimum: 0
          maximum: 100
          default: 20
      - name: orientation
        in: query
        description: One or more orientations. Repeat the parameter or pass a comma separated list.
        schema:
          type: array
          items:
            $ref: '#/components/schemas/Orientation'
          maxItems: 3
      - name: source
        in: query
        description: Restrict to one or more upstream libraries.
        schema:
          type: array
          items:
            $ref: '#/components/schemas/Source'
          maxItems: 8
      - name: license_type
        in: query
        description: Restrict to one or more licence families.
        schema:
          type: array
          items:
            $ref: '#/components/schemas/LicenseType'
          maxItems: 8
      - name: photographer
        in: query
        description: Restrict to one photographer, by username.
        schema:
          type: string
          maxLength: 120
      - name: per_page
        in: query
        description: Results per page.
        schema:
          type: integer
          minimum: 1
          maximum: 80
          default: 20
      - name: limit
        in: query
        description: Hard ceiling on results across all pages of this query.
        schema:
          type: integer
          minimum: 1
          maximum: 200
      - name: score_threshold
        in: query
        description: Drop results whose relevance score is below this. Search is semantic, so every query returns something; this is how you decide it returned nothing useful.
        schema:
          type: number
          minimum: 0
          maximum: 1
      - name: cursor
        in: query
        description: Opaque cursor from pagination.next_cursor. Cursors are tied to the query that produced them and expire; treat them as single use.
        schema:
          type: string
          maxLength: 512
      - name: fields
        in: query
        description: Comma separated list of Photo fields to return. Trims the payload, does not change ranking.
        schema:
          type: string
      - name: after_date
        in: query
        description: Only photos uploaded on or after this date.
        schema:
          type: string
          format: date
      - name: sort_by
        in: query
        description: Ordering. Defaults to relevance.
        schema:
          $ref: '#/components/schemas/SortBy'
      responses:
        '200':
          description: One page of ranked results.
          headers:
            X-Request-Id:
              description: Echoed in error payloads; quote it in a support request.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Calls left in the current window.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchEnvelope'
              example:
                success: true
                data:
                - photo_id: 0192f3a1-6c1e-7a3b-9f2d-4c8e1b5a7d20
                  image_url: https://cdn.pexafy.com/p/0192f3a1/regular.jpg
                  urls:
                    thumb: https://cdn.pexafy.com/p/0192f3a1/thumb.jpg
                    small: https://cdn.pexafy.com/p/0192f3a1/small.jpg
                    regular: https://cdn.pexafy.com/p/0192f3a1/regular.jpg
                    large: https://cdn.pexafy.com/p/0192f3a1/large.jpg
                    full: https://cdn.pexafy.com/p/0192f3a1/full.jpg
                  width: 5472
                  height: 3648
                  orientation: landscape
                  color_name: blue
                  color_hex: '#2f4f6f'
                  photographer_username: a-photographer
                  source: unsplash
                  license_type: unsplash
                  alt_description: an empty office lit only by monitors
                  relevance_score: 0.71
                pagination:
                  next_cursor: c2NvcmU6MC42MQ
                  per_page: 20
                  has_more: true
                meta:
                  request_id: req_01J8Z3
                  took_ms: 61.4
        '400':
          description: The request could not be parsed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: bad_request
                  message: The request could not be parsed.
                  request_id: req_01J8Z3
        '401':
          description: The API key is missing, malformed or revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: unauthenticated
                  message: The API key is missing, malformed or revoked.
                  request_id: req_01J8Z3
        '403':
          description: The key is valid but lacks the scope for this call.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: forbidden
                  message: The key is valid but lacks the scope for this call.
                  request_id: req_01J8Z3
        '422':
          description: A parameter was rejected before the search ran.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: validation_failed
                  message: A parameter was rejected before the search ran.
                  request_id: req_01J8Z3
        '429':
          description: Too many requests, or the plan quota is exhausted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: rate_limited
                  message: Too many requests, or the plan quota is exhausted.
                  request_id: req_01J8Z3
        '500':
          description: Something broke on our side.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: internal_error
                  message: Something broke on our side.
                  request_id: req_01J8Z3
      security:
      - apiKey: []
    servers:
    - url: https://api.pexafy.com/api/v1
      description: Production
  /search/photos/by-image:
    post:
      operationId: searchPhotosByImage
      tags:
      - search
      summary: Search photos by handing over an image
      description: 'The image is embedded and matched against the same vector space as a text query, so the two are interchangeable as far as ranking is concerned. The image is not stored.


        Send either a file or a URL, not both. Anything over 10 MB is rejected before it reaches the encoder.'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                image:
                  type: string
                  format: binary
                image_url:
                  type: string
                  format: uri
                per_page:
                  type: integer
                  minimum: 1
                  maximum: 80
                  default: 20
                orientation:
                  type: array
                  items:
                    $ref: '#/components/schemas/Orientation'
                source:
                  type: array
                  items:
                    $ref: '#/components/schemas/Source'
                score_threshold:
                  type: number
                  minimum: 0
                  maximum: 1
      responses:
        '200':
          description: One page of results ranked against the image.
          headers:
            X-Request-Id:
              description: Echoed in error payloads; quote it in a support request.
              schema:
                type: string
            X-RateLimit-Remaining:
              description: Calls left in the current window.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchEnvelope'
              example:
                success: true
                data:
                - photo_id: 0192f3a1-6c1e-7a3b-9f2d-4c8e1b5a7d20
                  image_url: https://cdn.pexafy.com/p/0192f3a1/regular.jpg
                  urls:
                    thumb: https://cdn.pexafy.com/p/0192f3a1/thumb.jpg
                    small: https://cdn.pexafy.com/p/0192f3a1/small.jpg
                    regular: https://cdn.pexafy.com/p/0192f3a1/regular.jpg
                    large: https://cdn.pexafy.com/p/0192f3a1/large.jpg
                    full: https://cdn.pexafy.com/p/0192f3a1/full.jpg
                  width: 5472
                  height: 3648
                  orientation: landscape
                  color_name: blue
                  color_hex: '#2f4f6f'
                  photographer_username: a-photographer
                  source: unsplash
                  license_type: unsplash
                  alt_description: an empty office lit only by monitors
                  relevance_score: 0.71
                pagination:
                  next_cursor: c2NvcmU6MC42MQ
                  per_page: 20
                  has_more: true
                meta:
                  request_id: req_01J8Z3
                  took_ms: 61.4
        '400':
          description: The request could not be parsed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: bad_request
                  message: The request could not be parsed.
                  request_id: req_01J8Z3
        '401':
          description: The API key is missing, malformed or revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: unauthenticated
                  message: The API key is missing, malformed or revoked.
                  request_id: req_01J8Z3
        '403':
          description: The key is valid but lacks the scope for this call.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: forbidden
                  message: The key is valid but lacks the scope for this call.
                  request_id: req_01J8Z3
        '422':
          description: A parameter was rejected before the search ran.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: validation_failed
                  message: A parameter was rejected before the search ran.
                  request_id: req_01J8Z3
        '429':
          description: Too many requests, or the plan quota is exhausted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: rate_limited
                  message: Too many requests, or the plan quota is exhausted.
                  request_id: req_01J8Z3
        '500':
          description: Something broke on our side.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                success: false
                error:
                  code: internal_error
                  message: Something broke on our side.
                  request_id: req_01J8Z3
      security:
      - apiKey: []
    servers:
    - url: https://api.pexafy.com/api/v1
      description: Production
  /api/v1/search/photos:
    get:
      tags:
      - search
      summary: Search photos by text
      description: 'Search the photo library with **natural language**, not keywords. Pexafy understands the *meaning, mood and story* of a scene, so full descriptive sentences return far better matches than a couple of tags. For example:


        - `an old man sitting at a café table he has visited every morning for thirty years`

        - `two people sharing a bench in comfortable silence`

        - `the last sunlight of the day hitting a dusty windowsill`

        - `a child discovering snow for the first time`


        Short queries like `mountain sunset` still work, but the more you describe the scene, light and emotion you have in mind, the closer the results.


        You can combine your text query with filters (color, orientation, source, license, photographer, date) to narrow the results. **At least one criterion is required**: either a text query (`q`) or one of the filters.


        ### What you get back

        A list of photos in `data`. The most useful fields on each photo are:


        | Field | Description |

        | --- | --- |

        | `photo_id` | Unique Pexafy identifier — use it with the **Photos** and **Collections** endpoints. |

        | `urls` | Ready-to-use image links in five sizes: `thumb`, `small`, `regular`, `large`, `full`. |

        | `description` / `alt_description` | A short caption and accessibility-friendly text. |

        | `color_name`, `color_hex`, `orientation` | Visual attributes of the photo. |

        | `source`, `license_type` | Where the photo comes from and how it may be used. |

        | `photographer_username`, `attribution` | Credit information. `attribution.html` and `attribution.plain` are ready to display. |

        | `relevance_score` | How closely the photo matches your query, from `0` to `1` (higher is better). |


        Results are returned page by page — see the [Pagination](/pagination) guide to fetch the next page.'
      operationId: search_photos_api_v1_search_photos_get
      parameters:
      - name: q
        in: query
        required: false
        schema:
          anyOf:
          - type: string
            maxLength: 500
          - type: 'null'
          title: Q
        description: Your search query in plain language — full descriptive sentences work best (e.g. `two people sharing a bench in comfortable silence`), though short queries like `mountain sunset` are fine too. Up to 500 characters. Optional if you provide at least one filter instead.
      - name: color_name
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Color Name
        description: Keep only photos whose dominant color matches this name (e.g. `blue`, `red`, `teal`). Call `GET /api/v1/facets/colors` (see the **Facets** section) to get the list of available color names. Cannot be combined with `color_hex`.
      - name: color_hex
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Color Hex
        description: Keep only photos close to this hex color (e.g. `#1E90FF`). Cannot be combined with `color_name`. Use `color_tolerance` to widen or tighten the match.
      - name: color_tolerance
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
            maximum: 255
            minimum: 0
          - type: 'null'
          description: 'How far a photo''s colour may sit from the one you asked for, from `0` (strict) to `255` (very loose). Defaults to `20`. Applies to **both** `color_hex` and `color_name`: for a hex it is the radius around that exact shade, for a name it widens or narrows the colour family. The published spec used to say it applied to `color_hex` only, which was never true of the code.'
          title: Color Tolerance
        description: 'How far a photo''s colour may sit from the one you asked for, from `0` (strict) to `255` (very loose). Defaults to `20`. Applies to **both** `color_hex` and `color_name`: for a hex it is the radius around that exact shade, for a name it widens or narrows the colour family.'
      - name: orientation
        in: query
        required: false
        schema:
          anyOf:
          - type: array
            items:
              type: string
          - type: 'null'
          title: Orientation
        description: 'Keep only photos with these shapes: `landscape`, `portrait` and/or `square`. Repeat the parameter to pass several. See `GET /api/v1/facets/orientations`.'
      - name: source
        in: query
        required: false
        schema:
          anyOf:
          - type: array
            items:
              type: string
          - type: 'null'
          title: Source
        description: Keep only photos from these providers (e.g. `Pexels`, `Unsplash`, `Pixabay`). Repeat the parameter to pass several. Call `GET /api/v1/facets/sources` to list every available source.
      - name: license_type
        in: query
        required: false
        schema:
          anyOf:
          - type: array
            items:
              type: string
          - type: 'null'
          title: License Type
        description: Keep only photos with these license types (e.g. `free`). Call `GET /api/v1/facets/licenses` to list the available license types.
      - name: per_page
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
            maximum: 100
            minimum: 1
          - type: 'null'
          title: Per Page
        description: Number of photos per page, from 1 to 100. Defaults to 20.
      - name: limit
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
            maximum: 100
            minimum: 1
          - type: 'null'
          description: Maximum TOTAL number of results to return across all pages — NOT the page size (use `per_page` for that). e.g. limit=4 with per_page=2 returns two pages of 2 results, then stops. Omit for no cap.
          title: Limit
        description: Maximum TOTAL number of results to return across all pages — NOT the page size (use `per_page` for that). e.g. limit=4 with per_page=2 returns two pages of 2 results, then stops. Omit for no cap.
      - name: score_threshold
        in: query
        required: false
        schema:
          anyOf:
          - type: number
            maximum: 1.0
            minimum: 0.0
          - type: 'null'
          title: Score Threshold
        description: Minimum relevance a photo must reach to appear, from `0` to `1`. Raise it (e.g. `0.3`) to keep only strong matches and drop loosely related photos; leave it unset to get the widest set of results.
      - name: cursor
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Cursor
        description: Token used to fetch the next page. Take the `pagination.next_cursor` value from a previous response and pass it back here. See the [Pagination](/pagination) guide.
      - name: fields
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Fields
        description: Comma-separated list to return only the fields you need (e.g. `photo_id,urls,attribution`), which makes responses smaller. Omit to get every field your plan allows.
      - name: after_date
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Only return photos published on or after this date, formatted `YYYY-MM-DD`.
          title: After Date
        description: Only return photos published on or after this date, formatted `YYYY-MM-DD`.
      - name: sort_by
        in: query
        required: false
        schema:
          anyOf:
          - enum:
            - relevance
            - newest
            type: string
          - type: 'null'
          description: 'Order of the results: `relevance` (default — best match first) or `newest` (most recently added first).'
          title: Sort By
        description: 'Order of the results: `relevance` (default — best match first) or `newest` (most recently added first).'
      - name: photographer
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Only return photos from this photographer's username. Use `GET /api/v1/facets/photographers/suggest` to find usernames.
          title: Photographer
        description: Only return photos from this photographer's username. Use `GET /api/v1/facets/photographers/suggest` to find usernames.
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PhotoListResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
      - ApiKeyAuth: []
    post:
      tags:
      - search
      summary: Search photos by image
      description: 'Upload an image and get visually similar photos in return — same subject, composition, colors or style. Ideal for finding alternatives to a photo you already have.


        You can also pass a text query (`q`) together with the image to steer the results: the search then balances *what the image looks like* with *what your words describe*. Use `text_alpha` to control that balance.


        **Accepted formats:** JPEG, PNG, WebP or AVIF, up to 10 MB.


        The same filters as text search are available, and the response has the exact same shape — see **Search photos by text** for the list of fields you get back.'
      operationId: search_photos_by_image_api_v1_search_photos_post
      parameters:
      - name: q
        in: query
        required: false
        schema:
          anyOf:
          - type: string
            maxLength: 500
          - type: 'null'
          description: Optional words, in plain language, to steer the visual match (e.g. `the same scene but at golden hour` or `warmer and more cheerful`). When set, results match both the picture and your text.
          title: Q
        description: Optional words, in plain language, to steer the visual match (e.g. `the same scene but at golden hour` or `warmer and more cheerful`). When set, results match both the picture and your text.
      - name: text_alpha
        in: query
        required: false
        schema:
          anyOf:
          - type: number
            maximum: 10.0
            minimum: 0.0
          - type: 'null'
          description: Balance between your text and the image when both are provided, from `0` to `10`. `0` ignores the text (pure visual search), `1.7` (the default) is balanced, and higher values give your words more weight. Has no effect without `q`.
          title: Text Alpha
        description: Balance between your text and the image when both are provided, from `0` to `10`. `0` ignores the text (pure visual search), `1.7` (the default) is balanced, and higher values give your words more weight. Has no effect without `q`.
      - name: color_name
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Color Name
        description: Keep only photos whose dominant color matches this name (e.g. `blue`, `red`, `teal`). Call `GET /api/v1/facets/colors` (see the **Facets** section) to get the list of available color names. Cannot be combined with `color_hex`.
      - name: color_hex
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Color Hex
        description: Keep only photos close to this hex color (e.g. `#1E90FF`). Cannot be combined with `color_name`. Use `color_tolerance` to widen or tighten the match.
      - name: color_tolerance
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
            maximum: 255
            minimum: 0
          - type: 'null'
          description: 'How far a photo''s colour may sit from the one you asked for, from `0` (strict) to `255` (very loose). Defaults to `20`. Applies to **both** `color_hex` and `color_name`: for a hex it is the radius around that exact shade, for a name it widens or narrows the colour family. The published spec used to say it applied to `color_hex` only, which was never true of the code.'
          title: Color Tolerance
        description: 'How far a photo''s colour may sit from the one you asked for, from `0` (strict) to `255` (very loose). Defaults to `20`. Applies to **both** `color_hex` and `color_name`: for a hex it is the radius around that exact shade, for a name it widens or narrows the colour family.'
      - name: orientation
        in: query
        required: false
        schema:
          anyOf:
          - type: array
            items:
              type: string
          - type: 'null'
          title: Orientation
        description: 'Keep only photos with these shapes: `landscape`, `portrait` and/or `square`. Repeat the parameter to pass several. See `GET /api/v1/facets/orientations`.'
      - name: source
        in: query
        required: false
        schema:
          anyOf:
          - type: array
            items:
              type: string
          - type: 'null'
          title: Source
        description: Keep only photos from these providers (e.g. `Pexels`, `Unsplash`, `Pixabay`). Repeat the parameter to pass several. Call `GET /api/v1/facets/sources` to list every available source.
      - name: license_type
        in: query
        required: false
        schema:
          anyOf:
          - type: array
            items:
              type: string
          - type: 'null'
          title: License Type
        description: Keep only photos with these license types (e.g. `free`). Call `GET /api/v1/facets/licenses` to list the available license types.
      - name: per_page
        in: query
        required: false
        schema:
          type: integer
          maximum: 100
          minimum: 1
          default: 20
          title: Per Page
        description: Number of photos per page, from 1 to 100. Defaults to 20.
      - name: limit
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
            maximum: 100
            minimum: 1
          - type: 'null'
          description: Maximum TOTAL number of results to return across all pages — NOT the page size (use `per_page` for that). Omit for no cap.
          title: Limit
        description: Maximum TOTAL number of results to return across all pages — NOT the page size (use `per_page` for that). Omit for no cap.
      - name: score_threshold
        in: query
        required: false
        schema:
          anyOf:
          - type: number
            maximum: 1.0
            minimum: 0.0
          - type: 'null'
          title: Score Threshold
        description: Minimum relevance a photo must reach to appear, from `0` to `1`. Raise it (e.g. `0.3`) to keep only strong matches and drop loosely related photos; leave it unset to get the widest set of results.
      - name: after_date
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Only return photos published on or after this date, formatted `YYYY-MM-DD`.
          title: After Date
        description: Only return photos published on or after this date, formatted `YYYY-MM-DD`.
      - name: sort_by
        in: query
        required: false
        schema:
          anyOf:
          - enum:
            - relevance
            - newest
            type: string
          - type: 'null'
          description: 'Order of the results: `relevance` (default — best match first) or `newest` (most recently added first).'
          title: Sort By
        description: 'Order of the results: `relevance` (default — best match first) or `newest` (most recently added first).'
      - name: photographer
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Only return photos from this photographer's username. Use `GET /api/v1/facets/photographers/suggest` to find usernames.
          title: Photographer
        description: Only return photos from this photographer's username. Use `GET /api/v1/facets/photographers/suggest` to find usernames.
      - name: cursor
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Token to fetch the next page. Take `pagination.next_cursor` from a previous response and pass it back here — no need to re-upload the image. See the Pagination guide.
          title: Cursor
        description: Token to fetch the next page. Take `pagination.next_cursor` from a previous response and pass it back here — no need to re-upload the image. See the Pagination guide.
      requestBody:
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Body_search_photos_by_image_api_v1_search_photos_post'
        required: true
      responses:
        '200':
         

# --- truncated at 32 KB (44 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/pexafy/refs/heads/main/openapi/pexafy-search-api-openapi.yml