HobbyCardIndex Card Price API
Card prices at every grade, card ID from a photo, cert lookups and pop reports, for your own business or under a commercial license for your app.
16M+ cards across sports and trading card games. New here? Start with what the API covers, then the reference below.
Which plan do I need?
Your own business
Pricing your own inventory, your own buying and selling, internal tools and reports only your team uses.
Enterprise plan. View pricing
Your users see our data
Apps, websites, widgets and paid products that show our prices, valuations or sales to your customers.
Commercial plan, starting with a free setup month. Sign in to see commercial plans
Getting Started
Authentication
All API endpoints require an API key for authentication. Keys come with the Enterprise plan or a Commercial plan (see which plan do I need).
Authentication Methods:
- Include the
X-API-Keyheader - Use
Authorization: Bearerheader
X-API-Key Header
Recommended for backend services.
Bearer Token
Works with Authorization header.
Get Your API Key: Sign in to your Enterprise or Commercial account and go to Settings, then API Access, then Generate API Key. Save it right away, because it is only shown once. Each account has one active key, and generating a new key replaces the old one.
Rate Limits
Commercial plans: 10, 20 or 50 lookups a second depending on the plan, with a monthly allowance of requests, scans and sale lookups. The free setup month allows 10 lookups a second and 1,000 requests a day. Your plan's numbers are under Settings, then API Access.
Rate Limit Headers:
X-RateLimit-Remaining: requests left in the current one-second windowX-RateLimit-Reset: when that window resets. The standard RateLimit-* headers are sent as well.
Pricing Data Format
All prices are returned in USD dollars with 2 decimal places. Example: 12.50
Every successful response is wrapped as {"success": true, "data": {...}}. The examples below show what sits inside data.
Supported card grades:
- loose: raw, ungraded card
- psa10, psa9, psa8: PSA 10, 9 and 8
- bgs10: BGS 9.5, or BGS 10 when there is no 9.5 price. cgc10, sgc10: CGC 10 and SGC 10
API Endpoints
Search card prices by name. A plain q search returns the 10 best matches with all grade prices. Base cards come first, then parallels (a parallel's name shows it in brackets, for example Mike Trout [Gold] #US175), and the most-traded cards first within each. Add any filter below to narrow the search or page through it; filtered searches return 25 a page by default, with hasMore telling you when there's another page. To list every card in one set, pass category and set (a set id from GET /api/v1/sets) with no q. Pass a result's id to the card and sales endpoints below. Every plan.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| q | string | Yes, unless set or added_since is given | Search query (2 to 200 characters). Example: "Mike Trout 2011" |
| category | string | No | A category from /market/categories, for example pokemon or baseball |
| set | string | No | A set id from /sets, for example pokemon-scarlet-violet-151. Needs category. Results come in card-number order. |
| language | string | No | The language printed on the card: english, japanese, chinese, korean, german, french, spanish, italian, portuguese, dutch, thai, indonesian, russian or polish |
| year | integer | No | Card year, for example 2023 |
| added_since | date | No | Only cards added to our catalog since then (UTC): a date like 2026-10-01 or a time like 2026-10-01T12:00:00Z. Results come in the order they were added, and each result's addedAt says when. For a long list, setting added_since to the last addedAt you got is faster than a large offset. |
| min_price / max_price | number | No | Raw (ungraded) price range in US dollars |
| sort | string | No | price_asc, price_desc, volume_desc, name_asc, added_asc or added_desc (raw price, trading volume, name, or when the card was added) |
| limit / offset | integer | No | Page size 1 to 100 (default 25) and how many to skip. A q search pages through its best 2,000 matches; a set, or added_since without q, pages through every card in it. |
A search that matches too many cards to sort or filter by price returns 400 SEARCH_TOO_BROAD; add a category, set or year (or a later added_since).
Get detailed price information for a specific card across all grades and grading companies.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| cardId | integer or string | The card's id from search or scan results. To look a card up by its externalId instead, put ext- in front of it, for example ext-67890. |
List verified sold sales for a specific card: individual sale records with price, date, grade and marketplace, plus summary stats for the period. Growth and Platform plans (the free setup month includes 500 lookups to test with); other keys get REQUIRES_COMMERCIAL_LICENSE. Which plan do I need?
Parameters
| Parameter | Type | Description |
|---|---|---|
| cardId | integer or string | The card's id from search or scan results, or ext- plus its externalId. |
| days | integer | Lookback window in days, 1–365. Default 90. Each call returns the newest 100 sales in the window, and counts as one sale lookup. Need more sales per call? That's available on a written commercial agreement: email [email protected]. |
Look up a graded card by its cert number: the grading company's record (grade, autograph grade, player, year, set, card number, population when the grader reports it), the matching card in our catalog, its prices at every grade and the price at that grade. The slab block also links the cert on the grading company's own site (verifyUrl: PSA, CGC and TGA open the cert itself, Beckett and SGC open their lookup page, where the number is entered) and carries the grader's slab photos when the grader has them (frontImageUrl, backImageUrl). Growth and Platform, with a monthly number of cert lookups (Growth 3,000, Platform 50,000, the free setup month 100; the pop + cert add-on raises Growth's number). One lookup per second per key.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| grader | string | psa, bgs, cgc or sgc |
| certNumber | string | The cert number on the slab label, for example 12345678 |
The card's daily price at every grade over time, for charts. Growth and Platform plans. ?days= from 1 to 3650, default 365. Individual sales are in /sales.
Population report for the card: how many copies PSA, BGS, SGC and CGC have graded, grade by grade, with gem counts and gem rate. Platform, or Growth with the pop + cert add-on. population is null when we don't hold a report for that card yet.
Every set in a category, with the set id that search (set=) and the watch list take, the language printed on its cards, its year and how many cards it has. Query: category (required), language, q (part of the set name), limit (up to 5,000, default 1,000), offset. Every plan.
Choose the cards you want price updates for. Growth (up to 100,000 cards) and Platform (up to 500,000); the free setup month can watch 1,000. Send {"cardIds": [12345, 67890]} (up to 1,000 ids a call; a search id, or ext- plus an externalId), or a whole set: {"category": "pokemon", "set": "pokemon-scarlet-violet-151", "language": "english"}, or a whole category: {"category": "pokemon", "language": "english"}. A set or category added this way stays followed: cards we add to it later join your list on their own and come in the daily webhook as cards.added. The response says how many were added, how many were already on the list, any ids we couldn't find, and your total.
GET /api/v1/watchlist lists the watched cards (limit up to 5,000, offset) and the sets you follow (following). POST /api/v1/watchlist/remove with {"cardIds": [...]} takes cards off, {"category": "pokemon", "set": "pokemon-scarlet-violet-151", "language": "english"} takes that set's cards off and stops following it (send the same fields you added it with), or {"all": true} clears the list.
GET /api/v1/watchlist/prices downloads the current prices of every watched card in one call (JSON, or ?format=csv). Prices change once a day, so once a day is plenty; one download a minute at most.
Get a call at your own server once a day with every watched card whose price changed. Send {"url": "https://your-server.example/hci-prices", "hour": 14}: an https address and the hour (UTC, 0 to 23) you want it sent. The first time, the response includes your signing secret; it's shown only then, so save it (send "rotateSecret": true for a new one). Webhook deliveries don't count against your requests.
Once a day at that hour we compare every watched card with the prices we last sent you and POST the changes, up to 1,000 cards a request. Each card lists the grades that changed with the previous and new price (null means no price), plus its current prices. Answer with any 2xx. If your server doesn't, we retry after 5 minutes, 30 minutes, 2, 6 and 12 hours; after 3 deliveries fail every retry the webhook pauses, and setting the URL again turns it back on. GET /api/v1/webhook shows the URL, hour and last delivery; DELETE /api/v1/webhook stops it; POST /api/v1/webhook/test sends a signed ping right away.
HCI-Signature is t=<unix time>,v1=<hex>, where the hex is the HMAC-SHA256 of <t>.<raw request body> with your secret. Compute it over the raw body and compare; reject old t values to stop replays. Grades are loose (raw), psa10, psa9, psa8, psa7, bgs10 (BGS 9.5), cgc10 and sgc10.
A whole set or category added to the watch list stays followed. Each day, before the price changes, any card we've added to it since the day before goes onto your list and comes in its own cards.added event, up to 1,000 cards a request, with the set it joined (following), its prices if it has any yet, and when it was added. New cards count toward your watch limit; any that don't fit are counted in notAdded. With no webhook set, they still join the list.
Retrieve your portfolio collection with current values and performance metrics.
Example Request (cURL)Get top market movers by category. Shows cards with the highest average sale prices in recent period.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| category | string | baseball | Card category: baseball, football, basketball, hockey, pokemon, etc. |
| period | integer | 7 | Days of history to analyze (1-90) |
Get statistics for all card categories. Useful for market analysis and portfolio segmentation.
Example Request (cURL)Use it from an AI assistant (MCP)
HobbyCardIndex runs an MCP server, so AI assistants that speak the Model Context Protocol, like Claude Code and Cursor, can look up card prices with your API key. It is listed in the official MCP Registry as com.hobbycardindex/card-prices.
Server URL: https://hobbycardindex.com/api/v1/mcp (Streamable HTTP). Send your key as the X-API-Key header, or as Authorization: Bearer. It is the same key as the REST API, with the same plan and the same limits, and every lookup counts toward your usage.
Tools:
- search_cards: finds a card the way a collector describes it (year, set, player or character, card number). Up to 5 matches, each with its raw and PSA 10 price and a link to the card page.
- get_card_prices: one card at every grade: raw, PSA 7 to PSA 10, BGS 9.5, CGC 10 and SGC 10.
Claude Code
Cursor (.cursor/mcp.json)
In VS Code the same entry goes in .vscode/mcp.json under "servers", with "type": "http" added.
Without a key, an assistant can connect and see the two tools, but every lookup answers with a note to get a key. To get one, see which plan do I need.
Error Handling
All error responses follow a consistent JSON structure:
Common Error Codes
| Code | HTTP Status | Description |
|---|---|---|
| MISSING_API_KEY | 401 | API key not provided in X-API-Key header or Authorization header |
| INVALID_API_KEY | 401 | API key is invalid or malformed |
| KEY_REVOKED | 401 | API key has been revoked |
| PLAN_REQUIRED | 403 | The account's Dealer or Enterprise plan has ended; the key works again once the plan is renewed |
| REQUIRES_COMMERCIAL_LICENSE | 403 | The endpoint (individual sold-sale records) is only available under a Commercial Data License. See Data use below. |
| RATE_LIMITED | 429 | More than 1 request per second on one key. Wait a second and retry. |
| RATE_LIMIT_EXCEEDED | 429 | The key reached its daily ceiling of 100,000 requests. Resets at UTC midnight. |
| VALIDATION_ERROR | 400 | A required query parameter is missing or invalid, for example q on search |
| NOT_FOUND | 404 | No card with that ID |
| SERVER_ERROR | 500 | Internal server error. Try again later. |
Pricing & Tiers
Enterprise, for your own business
API access for internal use is included with the Enterprise plan, $49.99 a month or $499.99 a year, which also includes 30,000 card scans a month. Each key can make 1 request per second, up to 100,000 requests a day.
Included with Enterprise:
- One API key per account
- 1 request per second, up to 100,000 a day
- Access to all pricing data (16M+ cards)
- Market movers and category analytics
- Portfolio API endpoints
- Priority support
- Licensed for your own internal use (see Data use below)
Don't have Enterprise? View pricing plans →
Commercial plans, for apps and websites
If your customers or the public will see our data, you need a Commercial plan instead. A new account can start with a free setup month to build and test against real data, and an Enterprise payment already made comes off the first commercial invoice.
Data use & commercial license
What your Enterprise plan covers
Your API key licenses HobbyCardIndex data for your own business's internal use: pricing your own inventory, your own buying and selling decisions, internal reports, and tools only your team uses. Setting your own price on a card using our data counts as internal use.
What needs a Commercial Data License
- Showing our prices, sold sales or market data to your customers or the public: a website, app, marketplace, widget, stream overlay, point-of-sale screen or printed price list
- Reselling, sublicensing or redistributing the data, including API responses and bulk price files
- Building or training a price guide, database or AI model from the data that you sell or offer to others
- Including the data in a product or service you charge for
- Sharing your API key, exports or bulk files with another company
- Individual sold-sale records from
/prices/:cardId/sales: this endpoint is only switched on for commercial plans that include it, one card per call with a monthly cap. No plan includes a bulk download of sold sales.
How to get started
Sign in and open Settings, API Access to see the commercial plans, start a free setup month, or buy Starter or Growth by card. Questions, or a bigger deal in mind? Email [email protected] with the subject "Commercial Data License". Commercial plans ask for one credit to Hobby Card Index with a link, either beside the prices or on your website. Until you're on one, an Enterprise plan covers internal use only.
When your plan ends
Stop using the data and delete stored copies, including cached API responses, sold-sale records and bulk files, within 30 days.
Full terms: Terms of Service, section 8.
Common questions
Is there an API for sports card prices?
Yes. The HobbyCardIndex REST API returns current prices by grade: raw, PSA 10, 9 and 8, BGS 9.5, CGC 10 and SGC 10. It also returns real sold-sale history and market data, for baseball, football, basketball, hockey, soccer, Pokémon, Magic: The Gathering, Yu-Gi-Oh, One Piece and more than 25 categories in all.
How much does the HobbyCardIndex API cost?
For your own business's internal use, API access is included with the Enterprise plan: $49.99 a month or $499.99 a year, which also includes 30,000 card scans a month, at 1 request per second up to 100,000 requests a day. Apps and websites that show our data to their users need a Commercial plan, which starts with a free setup month. Sign in to see commercial plans.
How many cards does the API cover?
The catalog holds more than 16 million card records, with more than 22 million prices across grades and more than 8 million card images.
Can I identify a card from a photo with the API?
Photo identification runs our own scanner, which matches a card photo against more than 8 million card images. It is not in the public API documentation yet. To use it in your product, email [email protected].
How current are the prices?
Prices are based on real sold prices, and each card's price record includes the time it was last updated.
Can I show HobbyCardIndex prices on my own website or app?
Yes, with a Commercial plan. An Enterprise key licenses the data for your own business's internal use, like pricing your own inventory. Showing our prices to your customers or the public, or building them into a product you offer others, needs a Commercial plan, which starts with a free setup month. Sign in to see commercial plans, or read data use.
How do I get an API key?
Subscribe to the Enterprise plan, then generate a key in Settings under API Access. Each account has one active key, and generating a new one replaces the old one.
Does HobbyCardIndex have an MCP server?
Yes. AI assistants that speak the Model Context Protocol, such as Claude Code and Cursor, can connect to https://hobbycardindex.com/api/v1/mcp and look up card prices with a HobbyCardIndex API key, sent as the X-API-Key header. It has two tools, search_cards and get_card_prices, and is listed in the official MCP Registry as com.hobbycardindex/card-prices. How to connect.