> ## Documentation Index
> Fetch the complete documentation index at: https://docs.managem.co.uk/llms.txt
> Use this file to discover all available pages before exploring further.

# Vector image search

> 
Find visually similar trading cards using a precomputed image embedding.

**Use this endpoint for:**
- image-based card recognition flows
- camera upload search
- similarity search from a cropped card artwork image

**Preparation requirements:**
- Generate a single image embedding from one card image at a time.
- Use CLIP ViT-B/32-compatible image preprocessing so the model input is prepared as float32 pixel values with shape `[1, 3, 224, 224]`.
- Use the model embedding output with shape `[1, 512]`.
- L2-normalize the 512-dimensional vector before sending it to this API.
- Send only the normalized numeric vector in `vectors`. Do not send raw pixels, base64 image data, or wrapped model response objects.

**Behavior:**
- Accepts exactly one 512-dimensional embedding per request.
- Accepts an optional `limit` between 1 and 10. If omitted, the API returns up to 5 matches.
- Returns visually similar card matches, ordered by similarity score.
- Each match includes the scored card identifier fields needed to resolve the card and display a primary image preview.

**Good to know:**
- This route is designed for image embeddings only. It does not generate embeddings from uploaded files.
- Invalid vectors are rejected before any similarity search is performed.




## OpenAPI

````yaml https://api.managem.co.uk/doc post /search/vector
openapi: 3.1.0
info:
  version: 0.0.0
  title: Managem API
  description: >+

    Managem API is the platform API for the Managem marketplace. It powers
    discovery, checkout, messaging, account management, and seller operations
    through a single REST surface with OpenAPI 3.1 documentation.


    ## API at a glance


    - Every action on Managem has a corresponding API route

    - **Public and authenticated access**: public discovery routes for search
    and profile data, with authenticated routes for account, basket, orders, and
    seller operations

    - **Domain-first structure** so clients can integrate one product area at a
    time


    ## Domain map


    ### Discover


    Find cards and products, resolve item identifiers, inspect item hierarchies,
    and browse marketplace listings:

    - `/search` and `/search/*` for full-text search, bulk lookup, and hierarchy
    navigation

    - `/listings` for listing search, seller listing views, and item price
    history

    - `/profile/{identifier}` for public profile and review data


    ### Buyer


    Support the full customer lifecycle:

    - `/basket` for basket state, summaries, fees, delivery costs, and checkout
    session creation

    - `/conversations` for inbox, unread counts, messaging, attachments, and
    conversation locking

    - `/user/*` for account updates, addresses, purchases, reviews, cases,
    invoices, portal access, personal access tokens, and account stats


    ### Seller


    Operate and scale marketplace supply:

    - `/seller` for onboarding, account status, dashboard links, vacation mode,
    and balance

    - `/seller/listings`, `/seller/orders`, and `/seller/cases` for day-to-day
    trading operations

    - `/seller/delivery-options`, `/seller/payouts`, and `/seller/transfers` for
    logistics and finance

    - `/seller/imports` for bulk listing workflows

    - `/seller/webhooks` for event delivery, testing, subscriptions, metrics,
    and failure diagnostics


    Use this reference to integrate each domain independently, then compose them
    into complete marketplace experiences.


    ## Authentication


    Protected routes accept:

    - Access tokens with `Authorization: Bearer <access-token>`.

    - Personal Access Tokens (PATs) with `Authorization: ApiKey
    <personal-access-token>`.


    For first-party and OAuth-style user sessions, contact support@managem.co.uk
    to apply for a custom application that you can use to authenticate Managem
    users.


    ### Personal Access Tokens (PATs)


    PATs are user-scoped API credentials designed for automation, scripts, and
    server-to-server integrations where interactive login is not practical.


    Use the `/user/personal-access-tokens` endpoints to manage them:

    - List active tokens

    - Create new tokens

    - Revoke existing tokens


    PAT behavior:

    - Each user can have up to 5 active tokens

    - Token names must be unique per user

    - `expires` is optional, but if provided it must be at least 24 hours in the
    future


    Use PATs with the API key authorization scheme:


    ```http

    Authorization: ApiKey <personal-access-token>

    ```


    Recommended lifecycle:

    1. Create a token for each integration

    2. Store it in a secure secret manager

    3. Rotate on a schedule

    4. Revoke immediately if exposed or no longer needed


    ## Third-party Integrations


    We welcome third-party integrations that enhance the Managem ecosystem. If
    you're interested in building an integration, contact us on
    [Discord](https://discord.gg/qaU4KSEQRd) to arrange the creation of your
    third-party application, which will allow you to authenticate and link
    Managem users. We will need:

    - Your application name

    - Your logo

    - A terms of use URL (if you have one)

    - A privacy policy URL (if you have one)


    Once your application has been created, Managem users can sign in to your
    application. This will provide you with a refreshable access token for each
    user who links their account, which you can use to make API calls on their
    behalf.


    ### Important API Endpoints

    - [Get seller
    status](https://api.managem.co.uk/#tag/seller-account/GET/seller/status)

    - [Manage seller listings](https://api.managem.co.uk/#tag/listings)

    - [Importing listings](https://api.managem.co.uk/#tag/seller-imports)

    - [Registering webhooks](https://api.managem.co.uk/#tag/seller-webhooks)

servers:
  - url: https://api.managem.co.uk
    description: Production API
security: []
tags:
  - name: search
    x-displayName: Search
    description: >

      Search and discovery endpoints for cards, products, and user references.


      These routes support free-text search, hierarchy-driven browsing, and
      image embedding search flows.
  - name: listings
    x-displayName: Listings
    description: |

      Public endpoints for retrieving seller listings.
  - name: profile
    x-displayName: Profile
    description: |

      Public endpoints for user profiles and reviews.
  - name: basket
    x-displayName: Basket
    description: >

      Basket (cart) endpoints used to add, update, remove, review, and checkout
      items.


      These routes support both lightweight basket summaries and full
      checkout-ready pricing breakdowns.
  - name: conversations
    x-displayName: Conversations
    description: |

      Endpoints for messaging between users.
  - name: user-account
    x-displayName: Account
    description: Manage account profile, credentials and media.
  - name: user-addresses
    x-displayName: Addresses
    description: Manage saved addresses and postcode lookup for checkout and shipping.
  - name: user-purchases
    x-displayName: Purchases
    description: List and manage buyer purchases and order updates.
  - name: user-reviews
    x-displayName: Reviews
    description: >

      Reviews are the trust layer between buyers and sellers after an order
      interaction.


      ## How review permissions work


      - Reviews are currently order-scoped only.

      - Only the buyer and seller attached to that order can review each other.

      - You cannot review yourself.

      - Each reviewer can leave only one review per order.


      ## How review scoring works


      1. A valid review is created.

      2. The reviewed user's aggregate rating stats are updated immediately.

      3. If the review is edited, aggregates are recalculated from rating delta.

      4. If the review is deleted, aggregates are adjusted again.


      ## Auto-generated reviews after inactivity


      Managem also backstops missing reviews in the purchase workflow:


      1. When a purchase reaches completed state, the workflow starts a review
      timer.

      2. Managem then waits 14 days for a review to be left manually by either
      the buyer and/or seller.

      3. For each order in the purchase, if buyer->seller or seller->buyer
      review is missing, Managem creates a default 5-star review with an
      automatic message.


      This ensures both parties are not left without reciprocal feedback when
      one side does not submit a review in time.
  - name: user-cases
    x-displayName: Cases
    description: >

      Cases are Managem's dispute workflow between a buyer and seller for
      contested order items.


      From the buyer side, these endpoints let you track a dispute from first
      report to final resolution without leaving the purchase flow.


      ## Dispute lifecycle (step-by-step)


      1. A case begins when disputed items are submitted through a
      purchase/order dispute action.

      2. Managem opens the case, records reason/comment, links disputed items,
      and stores initial proposed outcomes.

      3. Both sides can upload case evidence (create upload URL, then finalize
      attachment).

      4. Both sides can continue negotiation by proposing outcomes (`RETURN`,
      `REFUND`, `REPLACEMENT`).

      5. Outcomes can be accepted or rejected by the opposite party:
         - accepted `RETURN` -> case moves to `SETTLED` and later `CLOSED` when resolved
         - accepted `REFUND`/`REPLACEMENT` -> case moves directly to `CLOSED`
      6. Either party can escalate, and unresolved open/remediation cases are
      auto-escalated by the system after 7 days.


      ## Buyer-focused behavior


      - If a `RETURN` outcome is proposed, seller return-address details are
      hidden until a seller accepts the return outcome.

      - Case history is recorded as actions happen, so timeline/audit views can
      explain who did what.

      - Stats are invalidated as case state changes to keep buyer/seller
      dashboard counts current.


      ## Buyer endpoint usage


      - `GET /user/cases`: list buyer-owned cases.

      - `GET /user/cases/{id}`: retrieve one case.

      - `PUT /user/cases/{id}`: propose/accept/reject/escalate actions.

      - `POST /user/cases/{id}/attachments` + `PATCH
      /user/cases/{id}/attachments`: evidence upload flow.
  - name: user-invoices
    x-displayName: Invoices
    description: List invoices and download invoice documents.
  - name: user-portal
    x-displayName: Portal
    description: Access the customer billing and subscription portal.
  - name: user-personal-access-tokens
    x-displayName: Personal Access Tokens
    description: >

      Create, rotate, and revoke Personal Access Tokens (PATs) for
      non-interactive API integrations.


      PATs authenticate as the user who created them. If that user has an active
      seller account, the PAT can be used to perform seller actions on their
      behalf, including creating listings, updating orders, and managing
      webhooks.


      Typical integration flow:

      1. Create a PAT from the personal access token endpoints.

      2. Store the token in your secrets manager.

      3. Send requests with `Authorization: ApiKey <personal-access-token>`.

      4. Rotate regularly and revoke tokens that are no longer required.


      Security boundaries:

      - Maximum 5 active PATs per user.

      - PAT names must be unique per user.

      - Expiry is optional, but when provided it must be at least 24 hours in
      the future.
  - name: user-stats
    x-displayName: Stats
    description: Retrieve account-level counters for purchases, cases and messages.
  - name: seller-account
    x-displayName: Account
    description: Manage seller onboarding, status, dashboard access and vacation mode.
  - name: seller-finance
    x-displayName: Finance
    description: View balances, transfers and payouts for the authenticated seller.
  - name: seller-delivery-options
    x-displayName: Delivery Options
    description: Configure package and shipping delivery options.
  - name: seller-listings
    x-displayName: Listings
    description: Create, search, update and manage seller listings and listing attachments.
  - name: seller-orders
    x-displayName: Orders
    description: View, update and fulfill seller orders, including shipment attachments.
  - name: seller-cases
    x-displayName: Cases
    description: >

      Cases are Managem's dispute workflow between a buyer and a seller for one
      or more order items.


      Use the seller-cases endpoints when a seller needs to review evidence,
      negotiate an outcome, and close disputes in a structured way.


      ## Dispute lifecycle (step-by-step)


      1. A dispute is opened against order items through an order update action
      (`action: "dispute"`).

      2. Managem creates a case, links disputed items, records initial outcomes,
      and starts a background case workflow.

      3. Both parties can add evidence using the case attachment upload/finalize
      flow.

      4. Buyer and seller can propose outcomes (`RETURN`, `REFUND`,
      `REPLACEMENT`), then accept or reject the other party's proposals.

      5. If a `RETURN` outcome is accepted, the case enters `SETTLED` until the
      return is resolved (`resolve`), then closes.

      6. If `REFUND` or `REPLACEMENT` is accepted, the case closes directly.

      7. If unresolved, the system escalates open/remediation cases after 7
      days.


      ## Rules and guardrails


      - Disputes are limited to eligible order items (for example, not already
      refunded/resolved/disputed).

      - Items can only be disputed within 30 days of their last update.

      - Outcome amount proposals cannot exceed disputed item total + delivery
      charge.

      - A party cannot accept or reject its own proposed outcome.

      - Escalated/closed cases are locked from normal case updates.


      ## Seller endpoint usage


      - `GET /seller/cases`: list seller-visible cases.

      - `GET /seller/cases/{id}`: retrieve one seller case with outcomes and
      attachments.

      - `PUT /seller/cases/{id}`: propose/accept/reject/resolve/escalate.

      - `POST /seller/cases/{id}/attachments` + `PATCH
      /seller/cases/{id}/attachments`: evidence upload flow.
  - name: seller-imports
    x-displayName: Imports
    description: >

      Create, monitor, and control CSV-based bulk listing imports for the
      authenticated seller.


      Use imports when you need to create or update many listings in one job
      without sending per-listing API requests.


      Authentication model:

      - Import endpoints are scoped to the authenticated seller.

      - Use access tokens with `Authorization: Bearer <access-token>`.

      - Personal Access Tokens are also supported with `Authorization: ApiKey
      <personal-access-token>`.


      ## Import lifecycle


      1. Build a CSV using the exact header and column order shown below.

      2. Upload the file with `POST /seller/imports`.

      3. Track progress with `GET /seller/imports` and `GET
      /seller/imports/{id}`.

      4. Control active jobs with `PATCH /seller/imports/{id}/status/{mode}`
      (`pause`, `resume`, `terminate`).


      Processing model:

      - Upload accepts `multipart/form-data` with a `text/csv` file field named
      `file`.

      - Files are validated, stored, then split into background workflow
      batches.

      - Each row is applied independently: successful rows are committed even if
      other rows fail.

      - Import details include per-batch progress and row-level errors (`code`,
      `message`, `line`).


      ## CSV contract


      Current header (recommended, exact order):

      ```csv

      MODE,URN,GAME,SET,NAME,CARDMARKET_ID,TCGPLAYER_ID,CONDITION,PRICE,QUANTITY,VARIANTS,HIDDEN,COMMENT,NOTES,REFERENCE

      ```


      Column rules:

      - `MODE` (required): `CREATE` or `UPDATE`.

      - Item identity (required): provide at least one of:
        - `URN` (recommended),
        - `GAME` + `SET` + `NAME`,
        - `CARDMARKET_ID`,
        - `TCGPLAYER_ID`.
      - `CONDITION` (required): one of `MT`, `NM`, `EX`, `GD`, `LP`, `PL`, `PO`.

      - `PRICE` (required): integer price in pence (for example, `100` = £1.00).

      - `QUANTITY` (required): integer quantity.

      - `VARIANTS` (optional): comma-separated variant identifiers.

      - `HIDDEN` (optional): `true` or `false`.

      - `COMMENT`, `NOTES` (optional): free text values.

      - `REFERENCE` (optional): integration-owned listing reference; blank
      values clear stored reference.


      Upload-level validation:

      - Header mismatch returns `400`.

      - Empty files (header only) return `400`.

      - Files over 2,000,000 non-empty rows return `400`.


      ## Examples


      ### Create using a URN


      ```csv

      CREATE,urn:managem:pokemon:set/surging-sparks/card/16,,,,,,NM,350,1,,,,SKU65125,partner-ref-16

      ```


      Creates a new listing by using Managem's URN identifier, to target a
      specific item (single card), creating it with a "Near Mint" condition for
      £3.50 and a quantity of 1. It also has a seller note, indicating a SKU
      that the seller will recognise upon receiving an order containing it, plus
      a third-party integration reference.


      ### Create using Game/Set/Name


      ```csv

      CREATE,,Pokemon,Surging Sparks,Vulpix,,,,LP,200,5,,true,"Quick
      delivery",,erp-ref-vulpix

      ```


      Creates a new listing for Vulpix, in the Surging Sparks (Pokemon) set.
      Upon processing this row, our system will perform a search, attempting to
      match the game, set and name fields with a specific item.


      ### Create using an external marketplace ID


      ```csv

      CREATE,,,,,794271,,NM,2,1,,false,,,cardmarket-ref-794271

      ```


      Creates using Cardmarket's ID for Vulpix in the Surging Sparks (Pokemon)
      set, to create a new listing.


      ---


      ## Statuses


      - `RUNNING`: batches are processing.

      - `PAUSED`: processing is paused and can be resumed.

      - `TERMINATED`: job was stopped; already-processed rows remain applied.

      - `FAILED`: one or more rows failed; successful rows remain applied.

      - `COMPLETED`: all rows across all batches finished without row errors.


      ## Error handling and retries


      Common row error codes:

      - `400`: row validation failed (for example bad types, invalid
      `CONDITION`, invalid `HIDDEN`).

      - `404`: item/listing not found (lookup miss, or `UPDATE` with no existing
      seller listing).

      - `409`: ambiguous/conflicting match (multiple item matches or multiple
      seller listings for one item).

      - `500`: unexpected internal processing error.


      Retry pattern:

      1. Open import details and review `errors` entries.

      2. Copy only failing rows into a new CSV with the same header.

      3. Fix the data and upload as a new import job.


      Recommended practice:

      - Prefer `URN` for the most deterministic matching.

      - Start with a small smoke test (5-10 rows) before large imports.
  - name: seller-webhooks
    x-displayName: Webhooks
    description: >

      Manage outbound event delivery from Managem to your seller integrations.


      Seller webhooks let your systems react to marketplace activity without
      polling. Endpoints in this tag cover full lifecycle management: create,
      list, update, subscription changes, test delivery, and failure/metrics
      diagnostics.


      Authentication model:

      - Webhook endpoints are scoped to the authenticated seller.

      - Calls can be authenticated with normal bearer access tokens.

      - Automation services can also use Personal Access Tokens (PATs) created
      by the seller account and sent as `Authorization: ApiKey
      <personal-access-token>`.


      ## Events


      ### `LISTING_CREATED`

      Fired after a listing is successfully created, including single and bulk
      creates.


      Payload

      ```json

      {
        "type": "LISTING_CREATED",
        "data": {
          "sellerId": "string",
          "createdAt": "ISO-8601 datetime",
          "urn": "string",
          "listingId": "string",
          "quantity": "integer >= 0",
          "price": "number >= 0"
        }
      }

      ```


      ---


      ### `LISTING_UPDATED`

      Fired after a seller updates an existing listing through `PUT
      /seller/listings/{id}`.


      > Note: Quantity updates from orders do not trigger this event. Only
      explicit seller-initiated listing updates through the API will fire
      `LISTING_UPDATED`.


      Payload

      ```json

      {
        "type": "LISTING_UPDATED",
        "data": {
          "sellerId": "string",
          "createdAt": "ISO-8601 datetime",
          "urn": "string",
          "listingId": "string",
          "quantity": "integer >= 0",
          "price": "number >= 0"
        }
      }

      ```


      ---


      ### `ORDER_CREATED`

      Fired when checkout is committed into seller orders. One event per created
      seller order.


      Payload

      ```json

      {
        "type": "ORDER_CREATED",
        "data": {
          "sellerId": "string",
          "createdAt": "ISO-8601 datetime",
          "orderId": "string",
          "listings": [
            {
              "urn": "string",
              "listingId": "string",
              "quantity": "integer >= 0",
              "price": "number >= 0"
            }
          ]
        }
      }

      ```


      ---


      ### `TEST_WEBHOOK`

      Fired when you trigger a test delivery for a webhook endpoint. This is a
      synthetic event type used to validate your receiver logic and endpoint
      configuration. It is not related to any marketplace activity and will not
      be fired automatically by any system events.


      Payload

      ```json

      {
        "type": "TEST_WEBHOOK",
        "data": {
          "sellerId": "string",
          "createdAt": "ISO-8601 datetime"
        }
      }

      ```


      Forward-compatibility:

      - Subscription enums already include additional event types such as
      `LISTING_DELETED` and `ORDER_UPDATED`.

      - Receivers should treat unknown event types as forward-compatible
      additions and ignore unsupported events safely.


      Recommended rollout:

      1. Create the endpoint in a disabled state.

      2. Configure subscriptions and optional custom headers.

      3. Run webhook test delivery and validate receiver processing.

      4. Enable deliveries in production.

      5. Monitor reliability with webhook metrics and failure inspection
      endpoints.
  - name: seller-stats
    x-displayName: Stats
    description: Retrieve seller counters for orders, cases and listings.
paths:
  /search/vector:
    post:
      tags:
        - search
      summary: Vector image search
      description: >

        Find visually similar trading cards using a precomputed image embedding.


        **Use this endpoint for:**

        - image-based card recognition flows

        - camera upload search

        - similarity search from a cropped card artwork image


        **Preparation requirements:**

        - Generate a single image embedding from one card image at a time.

        - Use CLIP ViT-B/32-compatible image preprocessing so the model input is
        prepared as float32 pixel values with shape `[1, 3, 224, 224]`.

        - Use the model embedding output with shape `[1, 512]`.

        - L2-normalize the 512-dimensional vector before sending it to this API.

        - Send only the normalized numeric vector in `vectors`. Do not send raw
        pixels, base64 image data, or wrapped model response objects.


        **Behavior:**

        - Accepts exactly one 512-dimensional embedding per request.

        - Accepts an optional `limit` between 1 and 10. If omitted, the API
        returns up to 5 matches.

        - Returns visually similar card matches, ordered by similarity score.

        - Each match includes the scored card identifier fields needed to
        resolve the card and display a primary image preview.


        **Good to know:**

        - This route is designed for image embeddings only. It does not generate
        embeddings from uploaded files.

        - Invalid vectors are rejected before any similarity search is
        performed.
      operationId: searchVector
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VectorSearchRequest'
            examples:
              NormalizedCardEmbedding:
                summary: Normalized 512-dimensional card embedding
                description: >-
                  Example payload structure for a single normalized card image
                  embedding.
                value:
                  limit: 3
                  vectors:
                    - 1
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
                    - 0
      responses:
        '200':
          description: Scored vector matches for the submitted image embedding
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VectorSearchResponse'
              examples:
                SimilarPokemonCards:
                  description: >-
                    Example response showing visually similar Pokemon card
                    matches for one submitted embedding.
                  value:
                    count: 2
                    matches:
                      - score: 0.9987
                        urn: urn:managem:pokemon:set/151/card/25
                        game: Pokemon
                        title: '151: Pikachu'
                        number: '25'
                        image: >-
                          https://images.managem.co.uk/urn:managem:pokemon:set/151/card/25/image/0
                      - score: 0.9921
                        urn: urn:managem:pokemon:set/base-set/card/58
                        game: Pokemon
                        title: 'Base Set: Pikachu'
                        number: '58'
                        image: >-
                          https://images.managem.co.uk/urn:managem:pokemon:set/base-set/card/58/image/0
        '400':
          description: >-
            Validation error. The request must include a single non-zero
            512-dimensional numeric vector.
components:
  schemas:
    VectorSearchRequest:
      type: object
      properties:
        limit:
          type: integer
          minimum: 1
          maximum: 10
          description: >-
            Maximum number of matches to return. Must be between 1 and 10.
            Defaults to 5.
          example: 3
        vectors:
          type: array
          items:
            type: number
          description: >-
            A 512-dimensional image embedding prepared from a single trading
            card image.
      required:
        - vectors
      description: >-
        Request payload for similarity search using a precomputed trading card
        image embedding.
    VectorSearchResponse:
      type: object
      properties:
        count:
          type: integer
          minimum: 0
          description: Number of matches returned for the submitted vector.
        matches:
          type: array
          items:
            $ref: '#/components/schemas/VectorSearchMatch'
          description: Scored vector matches sorted from most similar to least similar.
      required:
        - count
        - matches
      description: Similarity search results for a single trading card image embedding.
    VectorSearchMatch:
      allOf:
        - $ref: '#/components/schemas/VectorizedCardMetadata'
        - type: object
          properties:
            score:
              type: number
          required:
            - score
      description: A single scored vector match containing the matched card metadata.
    VectorizedCardMetadata:
      type: object
      properties:
        urn:
          type: string
          pattern: '[^/]$'
        game:
          type: string
          enum:
            - Pokemon
        title:
          type: string
        number:
          type:
            - string
            - 'null'
        image:
          type: string
      required:
        - urn
        - game
        - title
        - image
      description: >-
        Card metadata returned for a vector search match. This mirrors the
        searchable card attributes stored alongside the image embedding.

````