Hobby Card Index Prices API

Current prices by grade, search, and daily price history.

GitHub OpenAPI

Operations 3

GET /api/v1/prices/search Search cards and their current prices by grade #
GET /api/v1/prices/{cardId} One card's prices at every grade #
GET /api/v1/prices/{cardId}/history Daily price history at every grade #

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/hobbycardindex-com:hobbycardindex-com-prices-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

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

hobbycardindex-com-prices-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Hobby Card Index Data Prices API
  version: '1'
  summary: Real sold prices, photo identification, cert lookups, pop reports, sold sales and price history for sports cards and trading cards.
  description: 'Real sold prices for sports cards and trading cards: a catalog of more than 16 million cards across 25-plus categories (baseball, basketball, football, hockey, soccer, Pokemon, Magic: The Gathering, Yu-Gi-Oh, One Piece and more) with more than 22 million raw and graded prices, refreshed daily, plus card identification from a photo, PSA, BGS, CGC and SGC cert lookups, population reports, verified sold-sale records, daily price history, set lists, market movers, a price watch list with a daily webhook, and bulk price files.


    ## Keys and plans


    Every endpoint needs an API key, sent as the `X-API-Key` header (or `Authorization: Bearer`). Keys come from Settings, API Access, after subscribing. An **Enterprise** plan ($49.99 a month) includes a key for your own business''s internal use: 1 request a second, up to 100,000 a day. Apps, websites and products whose users see the data need a **Commercial plan** (a commercial data license, Terms of Service section 8):


    - Lite (plan id `lite`): $99 a month; 25,000 requests, 25,000 photo scans, 5,000 sold-sale lookups, 150 cert lookups, 10 lookups a second, price history.

    - Growth Lite (plan id `growth_lite`): $249 a month; 125,000 requests, 125,000 photo scans, 25,000 sold-sale lookups, 750 cert lookups, 15 lookups a second, price history.

    - Growth (plan id `growth`): $499 a month; 500,000 requests, 500,000 photo scans, 100,000 sold-sale lookups, 3,000 cert lookups, 20 lookups a second, price history.

    - Platform (plan id `platform`): from $1,500 a month; 2,000,000 requests, 1,500,000 photo scans, 500,000 sold-sale lookups, 50,000 cert lookups, 50 lookups a second, price history, bulk price files.


    A **free setup month** is by application in Settings, API Access (one per company): enough to build and test against real data, with daily pools. Plans, prices and how to buy, including how an AI agent can buy a plan for its user with no account (GET /api/v1/agent/plans, POST /api/v1/agent/checkout): https://hobbycardindex.com/developers#commercial-plans. Questions or a bigger deal: sean@hobbycardindex.com.


    ## Credit the data (required)


    Commercial plans ask for one link back to https://hobbycardindex.com somewhere on your site, such as ''Prices and API supplied by Hobby Card Index''; it does not need to be beside the prices. Every successful JSON object response carries an `attribution` object (text, url, html, required, terms) and an `X-Attribution` header with the same credit, so it can be rendered straight from the response. Put the credit beside the prices or anywhere on your website, such as the footer. Snippet: `Prices from Hobby Card Index`.


    ## Conventions


    - Base URL `https://hobbycardindex.com`; every path starts with `/api/v1/`. Prices are US dollars with two decimals; a grade with no price is `null`. Grade keys: `loose` (raw), `psa10`, `psa9`, `psa8`, `psa7`, `bgs10` (BGS 9.5), `cgc10`, `sgc10`.

    - Successful responses are `{ "success": true, "data": { ... }, "attribution": { ... } }`; errors are `{ "success": false, "error": { "code", "message", "details"? } }` with the HTTP status that fits (400, 401, 402, 403, 404, 409, 413, 429, 500, 503). Streamed downloads (CSV, bulk files, the watch-list prices) are not wrapped.

    - Card ids: pass the integer `id` every response carries, or `ext-` plus the card''s `externalId`. Picture links (`imageUrl`) go through our image proxy and need no key; a link can answer 404 later if the picture is withdrawn, so show a placeholder on a 404.

    - Rate limits: 1 request a second on an Enterprise key, the plan''s lookups a second on a commercial key, with `RateLimit-*` and `X-RateLimit-*` headers on the one-second window. Commercial plans also return `X-HCI-Plan` and `X-HCI-*-Used` / `X-HCI-*-Allowance` headers for the monthly counters.

    - The same data through an MCP server for AI assistants: POST https://hobbycardindex.com/api/v1/mcp, manifest https://hobbycardindex.com/.well-known/mcp.json.'
  termsOfService: https://hobbycardindex.com/terms/
  contact:
    name: Sean Charman, Hobby Card Index
    email: sean@hobbycardindex.com
    url: https://hobbycardindex.com/developers
  license:
    name: Hobby Card Index Terms of Service (section 8, Commercial Data License)
    url: https://hobbycardindex.com/terms/#data-license
  x-logo:
    url: https://hobbycardindex.com/hci-logo2.png
    altText: Hobby Card Index
    href: https://hobbycardindex.com
  x-attribution:
    text: Prices from Hobby Card Index
    url: https://hobbycardindex.com
    html: <a href="https://hobbycardindex.com" rel="noopener">Prices from Hobby Card Index</a>
    required: true
    terms: https://hobbycardindex.com/terms/
servers:
- url: https://hobbycardindex.com
  description: Production
security:
- ApiKeyAuth: []
tags:
- name: Prices
  description: Current prices by grade, search, and daily price history.
paths:
  /api/v1/prices/search:
    get:
      tags:
      - Prices
      summary: Search cards and their current prices by grade
      operationId: searchPrices
      description: 'A plain `q` search returns the 10 best matches with every grade price: base cards first, then parallels, the most traded first within each. Any filter turns it into a paged, filtered search (25 a page by default) with `hasMore`. To list every card in one set, send `category` and `set` (a set id from GET /api/v1/sets) with no `q`; to get only cards added since a date, send `added_since`. Prices are real sold prices in US dollars. Every plan; one request.'
      parameters:
      - name: q
        in: query
        required: false
        description: Search text, 2 to 200 characters, for example `Mike Trout 2011`. Required unless `set` or `added_since` is given.
        schema:
          type: string
          minLength: 2
          maxLength: 200
      - name: category
        in: query
        required: false
        description: A category id from GET /api/v1/market/categories, for example `pokemon` or `baseball`.
        schema:
          type: string
          pattern: ^[a-z0-9][a-z0-9-]{0,39}$
      - name: set
        in: query
        required: false
        description: A set id from GET /api/v1/sets. Needs `category`. Results come in card-number order.
        schema:
          type: string
          pattern: ^[a-z0-9][a-z0-9-]{0,79}$
      - name: language
        in: query
        required: false
        description: The language printed on the card.
        schema:
          type: string
          enum:
          - english
          - japanese
          - chinese
          - korean
          - german
          - french
          - spanish
          - italian
          - portuguese
          - dutch
          - thai
          - indonesian
          - russian
          - polish
      - name: year
        in: query
        required: false
        description: Card year, four digits.
        schema:
          type: integer
          minimum: 1850
          maximum: 2100
      - name: added_since
        in: query
        required: false
        description: Only cards added to our catalog since this date or time (UTC), for example `2026-10-01` or `2026-10-01T12:00:00Z`. Results come in the order they were added. It can reach back up to 90 days.
        schema:
          type: string
      - name: min_price
        in: query
        required: false
        description: Lowest raw (ungraded) price, US dollars.
        schema:
          type: number
          minimum: 0
          maximum: 10000000
      - name: max_price
        in: query
        required: false
        description: Highest raw (ungraded) price, US dollars.
        schema:
          type: number
          minimum: 0
          maximum: 10000000
      - name: sort
        in: query
        required: false
        description: Order of a filtered search.
        schema:
          type: string
          enum:
          - price_asc
          - price_desc
          - volume_desc
          - name_asc
          - added_asc
          - added_desc
      - name: limit
        in: query
        required: false
        description: Page size, 1 to 25. Default 25.
        schema:
          type: integer
          minimum: 1
          maximum: 25
          default: 25
      - name: offset
        in: query
        required: false
        description: How many to skip. A `q` search pages through its best matches (up to the search ceiling); a set, or `added_since` without `q`, pages through every card, up to 100,000.
        schema:
          type: integer
          minimum: 0
          default: 0
      responses:
        '200':
          description: Matching cards
          headers:
            X-Attribution:
              $ref: '#/components/headers/X-Attribution'
            X-HCI-Plan:
              $ref: '#/components/headers/X-HCI-Plan'
            X-HCI-Requests-Used:
              $ref: '#/components/headers/X-HCI-Requests-Used'
            X-HCI-Requests-Allowance:
              $ref: '#/components/headers/X-HCI-Requests-Allowance'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimit-Limit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimit-Remaining'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    const: true
                  data:
                    $ref: '#/components/schemas/SearchResponse'
                  attribution:
                    $ref: '#/components/schemas/Attribution'
                required:
                - success
                - data
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/ServerError'
      security:
      - ApiKeyAuth: []
  /api/v1/prices/{cardId}:
    get:
      tags:
      - Prices
      summary: One card's prices at every grade
      operationId: getCardPrices
      description: The card and its current prices by grade (raw, PSA 10, 9, 8 and 7, BGS 9.5, CGC 10, SGC 10) in US dollars, with recent sales volume and when the prices were last refreshed. Numbered parallels carry `printRun`. `imageUrl` is the card's picture through our image link (no key needed). Every plan; one request.
      parameters:
      - $ref: '#/components/parameters/cardId'
      responses:
        '200':
          description: The card and its prices
          headers:
            X-Attribution:
              $ref: '#/components/headers/X-Attribution'
            X-HCI-Plan:
              $ref: '#/components/headers/X-HCI-Plan'
            X-HCI-Requests-Used:
              $ref: '#/components/headers/X-HCI-Requests-Used'
            X-HCI-Requests-Allowance:
              $ref: '#/components/headers/X-HCI-Requests-Allowance'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimit-Limit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimit-Remaining'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    const: true
                  data:
                    $ref: '#/components/schemas/CardPricesResponse'
                  attribution:
                    $ref: '#/components/schemas/Attribution'
                required:
                - success
                - data
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/ServerError'
      security:
      - ApiKeyAuth: []
  /api/v1/prices/{cardId}/history:
    get:
      tags:
      - Prices
      summary: Daily price history at every grade
      operationId: getCardPriceHistory
      description: The card's price at every grade, day by day, for charts. A grade with no price on a day is null, never 0; days we hold no prices for are not in the list. Individual sales are in /sales. Commercial plans with price history (every size), signed deals and admins; other keys get 403 REQUIRES_GROWTH. One request.
      parameters:
      - $ref: '#/components/parameters/cardId'
      - name: days
        in: query
        required: false
        description: How far back, 1 to 3,650 days. Default 365.
        schema:
          type: integer
          minimum: 1
          maximum: 3650
          default: 365
      responses:
        '200':
          description: Daily prices
          headers:
            X-Attribution:
              $ref: '#/components/headers/X-Attribution'
            X-HCI-Plan:
              $ref: '#/components/headers/X-HCI-Plan'
            X-HCI-Requests-Used:
              $ref: '#/components/headers/X-HCI-Requests-Used'
            X-HCI-Requests-Allowance:
              $ref: '#/components/headers/X-HCI-Requests-Allowance'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimit-Limit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimit-Remaining'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    const: true
                  data:
                    $ref: '#/components/schemas/HistoryResponse'
                  attribution:
                    $ref: '#/components/schemas/Attribution'
                required:
                - success
                - data
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/ServerError'
      security:
      - ApiKeyAuth: []
components:
  schemas:
    SearchResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/SearchResult'
        count:
          type: integer
          description: How many results are in this response.
        limit:
          type: integer
          description: 'Filtered searches only: the page size.'
        offset:
          type: integer
          description: 'Filtered searches only: how many were skipped.'
        hasMore:
          type: boolean
          description: 'Filtered searches only: whether another page exists.'
      required:
      - results
      - count
    Attribution:
      type: object
      properties:
        text:
          type: string
          const: Prices from Hobby Card Index
        url:
          type: string
          format: uri
          const: https://hobbycardindex.com
        html:
          type: string
          const: <a href="https://hobbycardindex.com" rel="noopener">Prices from Hobby Card Index</a>
          description: 'Ready to paste: the credit as a link.'
        required:
          type: boolean
          const: true
        terms:
          type: string
          format: uri
          const: https://hobbycardindex.com/terms/
      required:
      - text
      - url
      - html
      - required
      - terms
      description: 'The credit this data must carry wherever it is shown: a visible "Prices from Hobby Card Index" link to https://hobbycardindex.com. Added to every successful JSON object response (also sent as the X-Attribution header).'
    SearchResult:
      type: object
      properties:
        id:
          type: integer
          description: The catalog id. Pass it to GET /api/v1/prices/{cardId} and the other card endpoints.
        externalId:
          type:
          - string
          - 'null'
          description: Secondary id; the card endpoints also accept `ext-<externalId>`.
        name:
          type: string
          description: Card name; a parallel is named in brackets.
        year:
          type:
          - integer
          - string
          - 'null'
        setName:
          type:
          - string
          - 'null'
          description: Set name.
        setId:
          type:
          - string
          - 'null'
          description: The set id GET /api/v1/sets lists and `set=` takes.
        cardNumber:
          type:
          - string
          - 'null'
          description: The number printed on the card.
        printRun:
          type:
          - integer
          - 'null'
          description: For numbered cards, the print run (50 for a card numbered to /50); null when not numbered or unknown.
        category:
          type:
          - string
          - 'null'
          description: Category.
        playerName:
          type:
          - string
          - 'null'
          description: Player or character.
        imageUrl:
          type:
          - string
          - 'null'
          description: The card's picture through our image link, or null when we have no usable picture. The link needs no key; it can answer 404 later if the picture is withdrawn.
          format: uri
        addedAt:
          type:
          - string
          - 'null'
          format: date-time
          description: When the card joined our catalog.
        prices:
          oneOf:
          - $ref: '#/components/schemas/SearchPrices'
          - type: 'null'
        hciUrl:
          type:
          - string
          - 'null'
          description: The card's page on hobbycardindex.com, with recent sales and price history.
          format: uri
      required:
      - id
      - name
    Card:
      type: object
      properties:
        id:
          type: integer
        externalId:
          type:
          - string
          - 'null'
          description: Secondary id; also accepted as `ext-<externalId>`.
        name:
          type: string
          description: Card name; a parallel is named in brackets.
        year:
          type:
          - integer
          - string
          - 'null'
        setName:
          type:
          - string
          - 'null'
          description: Set name.
        cardNumber:
          type:
          - string
          - 'null'
          description: The number printed on the card.
        printRun:
          type:
          - integer
          - 'null'
          description: Print run for numbered cards; null otherwise.
        category:
          type:
          - string
          - 'null'
          description: Category.
        playerName:
          type:
          - string
          - 'null'
          description: Player or character.
        imageUrl:
          type:
          - string
          - 'null'
          description: Picture through our image link, or null.
          format: uri
        hciUrl:
          type:
          - string
          - 'null'
          description: The card's page on hobbycardindex.com.
          format: uri
      required:
      - id
      - name
    CardRef:
      type: object
      properties:
        id:
          type: integer
          description: The catalog id. Pass it to the other card endpoints.
        externalId:
          type:
          - string
          - 'null'
          description: Our catalog's secondary id for the card. Accepted by the card endpoints as `ext-<externalId>`.
        name:
          type: string
          description: 'The card name, with the parallel in brackets when it is not the base card, for example `Mike Trout [Gold] #US175`.'
        year:
          type:
          - integer
          - string
          - 'null'
          description: The year the card came out (for Pokemon, the year its set was released); null when unknown.
        setName:
          type:
          - string
          - 'null'
          description: The set the card belongs to.
        category:
          type:
          - string
          - 'null'
          description: The category, for example Baseball or Pokemon.
        playerName:
          type:
          - string
          - 'null'
          description: The player or character on the card.
      required:
      - id
      - name
      description: The card block the sales, listings, history and population endpoints return.
    CardPricesResponse:
      type: object
      properties:
        card:
          $ref: '#/components/schemas/Card'
        prices:
          oneOf:
          - $ref: '#/components/schemas/Prices'
          - type: 'null'
          description: null when we hold no price for this card.
      required:
      - card
      - prices
    SearchPrices:
      allOf:
      - $ref: '#/components/schemas/PriceGrid'
      - type: object
        properties:
          volume:
            type:
            - integer
            - 'null'
            description: Recent sales volume, a count.
          fromSales:
            type: array
            items:
              type: string
            description: Grades whose price came from our own recent sold sales.
      description: The price block of a search result. null on the whole block when the card has no price at any grade, and on every result for keys on the pop + certs plan.
    HistoryResponse:
      type: object
      properties:
        card:
          $ref: '#/components/schemas/CardRef'
        days:
          type: integer
          description: The window that was applied.
        history:
          type: array
          items:
            $ref: '#/components/schemas/HistoryPoint'
          description: Days we hold prices for, so dates can skip.
        soldByGrade:
          type: object
          additionalProperties: true
          description: 'Only with soldByGrade=1. Sold prices at every grade we have sales for, half grades and every grading company included, from our own verified sales. Keyed by grade ("PSA 8.5", "BGS 9", "Raw"), newest first: [{ date, price (the middle sale that day), sales }]. A day with no sale has no point.'
        count:
          type: integer
      required:
      - card
      - days
      - history
      - count
    Prices:
      allOf:
      - $ref: '#/components/schemas/PriceGrid'
      - type: object
        properties:
          volume:
            type:
            - integer
            - 'null'
            description: Recent sales volume, a count.
          updated:
            type:
            - string
            - 'null'
            format: date-time
            description: When this card's prices were last refreshed.
          fromSales:
            type: array
            items:
              type: string
            description: Grades (keys of this object) whose price came from our own recent sold sales because no other price was on file for that grade.
      description: 'The price block of GET /api/v1/prices/{cardId}: the grade grid plus volume and the last update.'
    HistoryPoint:
      allOf:
      - $ref: '#/components/schemas/PriceGrid'
      - type: object
        properties:
          date:
            type: string
            format: date
            description: The day, UTC.
          volume:
            type:
            - integer
            - 'null'
            description: Sales volume that day, a count (0 is a real 0).
        required:
        - date
      description: One day's prices. A grade with no price that day is null, never 0.
    PriceGrid:
      type: object
      properties:
        loose:
          type:
          - number
          - 'null'
          description: raw (ungraded) price in US dollars; null when there is no price at that grade.
        psa10:
          type:
          - number
          - 'null'
          description: PSA 10 price in US dollars; null when there is no price at that grade.
        psa9:
          type:
          - number
          - 'null'
          description: PSA 9 price in US dollars; null when there is no price at that grade.
        psa8:
          type:
          - number
          - 'null'
          description: PSA 8 price in US dollars; null when there is no price at that grade.
        psa7:
          type:
          - number
          - 'null'
          description: PSA 7 price in US dollars; null when there is no price at that grade.
        bgs10:
          type:
          - number
          - 'null'
          description: BGS 9.5 (BGS 10 when there is no 9.5 price) price in US dollars; null when there is no price at that grade.
        cgc10:
          type:
          - number
          - 'null'
          description: CGC 10 price in US dollars; null when there is no price at that grade.
        sgc10:
          type:
          - number
          - 'null'
          description: SGC 10 price in US dollars; null when there is no price at that grade.
      description: Current prices by grade, in US dollars with two decimals. A grade with no price is null; `bgs10` holds the BGS 9.5 price.
    Error:
      type: object
      properties:
        success:
          type: boolean
          const: false
          description: false on every error the API itself sends. The per-second rate limiter's 429 body has only `error`.
        error:
          type: object
          properties:
            code:
              type: string
              description: Machine-readable code, for example VALIDATION_ERROR, INVALID_PARAM, MISSING_API_KEY, INVALID_API_KEY, KEY_REVOKED, PLAN_REQUIRED, TRIAL_ENDED, NOT_ON_PLAN, REQUIRES_COMMERCIAL_LICENSE, REQUIRES_GROWTH, REQUIRES_PARTNER_PLAN, RATE_LIMITED, MONTHLY_LIMIT_REACHED, DAILY_LIMIT_REACHED, NOT_FOUND, SERVER_ERROR.
            message:
              type: string
              description: What went wrong and, where there is one, what to do about it.
            details:
              type: object
              additionalProperties: true
              description: 'Extra fields on some errors: plans_url, upgrade_url, limit, allowance, plan, upgrade.'
          required:
          - code
          - message
      required:
      - error
      description: The error envelope from every endpoint.
  headers:
    X-Attribution:
      description: 'Always "Prices from Hobby Card Index (https://hobbycardindex.com)" on a successful JSON object response: the credit the data must carry.'
      schema:
        type: string
    X-HCI-Requests-Used:
      description: 'Commercial plans only: requests used this month, after this one.'
      schema:
        type: integer
    X-HCI-Requests-Allowance:
      description: 'Commercial plans only: the plan''s monthly requests.'
      schema:
        type: integer
    RateLimit-Remaining:
      description: Requests left in the current one-second window.
      schema:
        type: integer
    RateLimit-Limit:
      description: Requests allowed in the current one-second window (X-RateLimit-* are sent too).
      schema:
        type: integer
    X-HCI-Plan:
      description: 'Commercial plans only: the plan id behind this key.'
      schema:
        type: string
  parameters:
    cardId:
      name: cardId
      in: path
      required: true
      description: The card's `id` from search, scan, movers or watch-list results (an integer), or `ext-` followed by its `externalId` (for example `ext-67890`). Letters, digits, dashes, underscores and dots, up to 150 characters.
      schema:
        type: string
        maxLength: 150
        pattern: ^[a-zA-Z0-9\-_.]+$
  responses:
    NotFound:
      description: 'NOT_FOUND: no card (or file) matches.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    PaymentRequired:
      description: 'TRIAL_ENDED: the free setup month is over and the first month of the plan is not paid yet.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: 'The key''s plan does not include this: PLAN_REQUIRED, DEALER_KEY_SCOPE, NOT_ON_PLAN, REQUIRES_COMMERCIAL_LICENSE, REQUIRES_GROWTH, REQUIRES_PARTNER_PLAN, REQUIRES_PLATFORM_PLAN, REQUIRES_PRICE_FILES, REQUIRES_ENTERPRISE, LISTINGS_NOT_ENABLED. The message says which plan has it and `details.plans_url` where to get it.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    TooManyRequests:
      description: RATE_LIMITED (the per-second window; slow down and retry), RATE_LIMIT_EXCEEDED (the daily ceiling), MONTHLY_LIMIT_REACHED, DAILY_LIMIT_REACHED, SALES_LIMIT_REACHED, CERT_LIMIT_REACHED, POP_LIMIT_REACHED, LISTINGS_LIMIT_REACHED, SCAN_ENGINE_BUSY (Retry-After says when).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ServerError:
      description: 'SERVER_ERROR (500 or 503): something failed on our side; retry in a minute.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    BadRequest:
      description: 'The request is not valid: VALIDATION_ERROR, INVALID_PARAM, BAD_REQUEST, SEARCH_TOO_BROAD, NO_IMAGE, INVALID_IMAGE.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: No key (MISSING_API_KEY), a key we do not know (INVALID_API_KEY) or one that was revoked (KEY_REVOKED).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: 'Your HobbyCardIndex API key (hci_live_...). `Authorization: Bearer <key>` is accepted too. Keys: https://hobbycardindex.com/developers.'
externalDocs:
  description: Developer documentation with examples in curl, JavaScript and Python
  url: https://hobbycardindex.com/developers