Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Hobby Card Index Data MCP 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: MCP
description: The Model Context Protocol server for AI assistants.
paths:
/api/v1/mcp:
post:
tags:
- MCP
summary: MCP server for AI assistants (JSON-RPC 2.0 over Streamable HTTP)
operationId: mcp
description: 'The Model Context Protocol server. POST one JSON-RPC 2.0 message, or a batch of up to 10, as application/json; the answer is JSON (no SSE stream, and GET answers 405). Stateless: no Mcp-Session-Id. Protocol versions 2024-11-05 through 2025-11-25. The manifest is at https://hobbycardindex.com/.well-known/mcp.json; the registry name is com.hobbycardindex/card-prices.
`initialize`, `ping` and `tools/list` work without a key, capped per address. Every data `tools/call` needs the same X-API-Key (or Authorization: Bearer) as the REST API and counts toward the same plan and limits; a call without a key gets a tool error that says where to get one. The buy tools work without a key.
Tools:
- `search_cards`: Find a sports or trading card and its current sold price. Describe the card the way a collector would, for example "1989 Upper Deck Ken Griffey Jr 1", "2018 Topps Update Acuna US250" or "Charizard Base Set". Returns up to 5 matching cards with the raw (ungraded) and PSA 10 price, a card_id, and the link to the card page. Use get_card_prices for every grade of one card. Needs a HobbyCardIndex API key.
- `get_card_prices`: Current sold prices for one card at every grade: raw (ungraded), PSA 7, PSA 8, PSA 9, PSA 10, BGS 9.5, CGC 10 and SGC 10, in US dollars, with the link to the card page for recent sales and price history. Take the card_id from search_cards. Needs a HobbyCardIndex API key.
- `list_plans`: The HobbyCardIndex plans a user can buy right now: the Commercial API sizes (requests, photo scans, sold-sale lookups, cert lookups) and the app plans Pro, Dealer and Enterprise (scans a month, dealer tools, API key on Enterprise), with monthly prices in US dollars, the terms and how to buy. Pass use_case to get the size and add-ons that fit what the user wants to do. Works without an API key.
- `start_checkout`: Start buying a Commercial API plan for the user. Returns a Stripe checkout_url where the user pays by card (HobbyCardIndex never sees the card) and a status_url that returns the API key once, after payment. Only call this after the user has picked a plan from list_plans and agreed to the terms (accept_terms: true). Use the user''s own email: the receipt and the account sign-in go there. Works without an API key.
A successful data lookup''s result ends with a text item: "Prices from Hobby Card Index. Credit https://hobbycardindex.com when you show this data."'
requestBody:
required: true
description: A JSON-RPC 2.0 message or batch.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/JsonRpcRequest'
- type: array
items:
$ref: '#/components/schemas/JsonRpcRequest'
minItems: 1
maxItems: 10
responses:
'200':
description: The JSON-RPC response, or an array of them for a batch
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/JsonRpcResponse'
- type: array
items:
$ref: '#/components/schemas/JsonRpcResponse'
'202':
description: 'The message was a notification (no id): accepted, no body.'
'400':
description: Parse error (-32700) or Invalid Request (-32600), as a JSON-RPC error.
content:
application/json:
schema:
$ref: '#/components/schemas/JsonRpcResponse'
'405':
description: Any method other than POST. The Allow header says POST.
content:
application/json:
schema:
$ref: '#/components/schemas/JsonRpcResponse'
security:
- {}
- ApiKeyAuth: []
x-mcp:
transport: streamable-http
manifest: https://hobbycardindex.com/.well-known/mcp.json
registryName: com.hobbycardindex/card-prices
tools:
- search_cards
- get_card_prices
- list_plans
- start_checkout
components:
schemas:
JsonRpcRequest:
type: object
properties:
jsonrpc:
type: string
const: '2.0'
id:
type:
- string
- integer
- 'null'
description: Leave it out for a notification (notifications/initialized); the server then answers 202 with no body.
method:
type: string
enum:
- initialize
- ping
- tools/list
- tools/call
description: initialize, ping and tools/list need no key. tools/call runs a tool.
params:
type: object
additionalProperties: true
description: 'For tools/call: { name, arguments }.'
required:
- jsonrpc
- method
JsonRpcResponse:
type: object
properties:
jsonrpc:
type: string
const: '2.0'
id:
type:
- string
- integer
- 'null'
result:
type: object
additionalProperties: true
description: 'For tools/call: { content: [{ type: "text", text }], structuredContent?, isError }. A successful data lookup ends with a text item carrying the credit line.'
error:
type: object
properties:
code:
type: integer
message:
type: string
required:
- code
- message
required:
- jsonrpc
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