API Reference
Raw transaction-level access to trading card sales across all major platforms — via REST endpoints and an MCP server with 7 AI analysis tools.
Authentication
Authentication
All requests require an x-market-api-key header (REST) or an Authorization: Bearer header (MCP). The same key works for both. Get one free — no credit card required.
# REST API
GET /api/v1/market/sales
x-market-api-key: tca_your_key_here
# MCP Server
POST /api/mcp
Authorization: Bearer tca_your_key_hereDon't have a key? Get one free →
Base
Base URL
REST API
https://thecardapi.com/api/v1/marketAll REST paths below are relative to this base.
MCP Server
https://thecardapi.com/api/mcpJSON-RPC 2.0 over streamable HTTP. See the MCP Server section.
Endpoints
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /sales | Search and filter sales records |
| GET | /sales/{id} | Single sale by ID |
| GET | /daily | Aggregate stats for a date |
| GET | /platforms | Platform list with last updated date |
| GET | /coverage | Latest data freshness status |
| GET | /sales/export/csv | Download filtered sales as CSV |
| POST | /webhook | Register a webhook URL (Pro/Enterprise) |
| GET | /webhook | Get current webhook config |
| DELETE | /webhook | Remove webhook registration |
MCP tools are invoked via POST /api/mcp — see the MCP Tools section for individual tool references.
GET
GET /sales
Search and filter individual sale records. Results are ordered by date descending by default. Your plan's lookback window is enforced on date_from automatically.
| Parameter | Type | Description | |
|---|---|---|---|
| q | string | optional | Full-text search on listing title (min 4 chars). Supports eBay boolean syntax: (term1,term2) for OR, -term for NOT, "exact phrase" for phrase match. |
| platform | string | optional | Comma-separated: ebay, goldin, heritage, fanatics-vault, fanatics-weekly, rea, alt, pristine, myslabs, sterlingsportsauctions |
| listing_type | string | optional | Comma-separated: auction, fixed_price, best_offer |
| date_from | date | optional | Start date YYYY-MM-DD. Clamped to your plan's lookback window. |
| date_to | date | optional | End date YYYY-MM-DD |
| price_min | number | optional | Minimum sale price (USD) |
| price_max | number | optional | Maximum sale price (USD) |
| sort | string | optional | date_desc (default) | date_asc | price_desc | price_asc |
| page | integer | optional | Page number (default: 1) |
| limit | integer | optional | Results per request (default: 25, max: 1,000). Same cap on all plans. |
| indexed_after | datetime | optional | ISO 8601 UTC. Return only records indexed after this time. Useful for incremental sync. |
| cursor | string | optional | Keyset pagination cursor. Enterprise only. |
eBay boolean syntax
(psa,bgs) — title contains "psa" OR "bgs"-reprint — title does NOT contain "reprint""topps chrome" — exact phrase matchohtani (psa,bgs) -rookie — combine all threeResponse
Response schema
{
"data": [
{
"id": "ebay-137222685761",
"platform": "eBay",
"listing_type": "auction",
"title": "2021 Bowman Chrome Kyle Harrison Auto PSA 10",
"sale_date": "2026-05-14",
"sold_at": "2026-05-14T14:32:17Z",
"price": 47.50,
"currency": "USD",
"seller": "dcsports87",
"bids": 12,
"feedback": 99.7,
"image_url": "https://i.ebayimg.com/...",
"thumbnail_url": "https://i.ebayimg.com/...",
"listing_url": "https://www.ebay.com/itm/137222685761",
"card_description": "Kyle Harrison Auto",
"cert": "93265128",
"condition": null,
"grade": "10",
"grader": "PSA",
"grading_company": "Professional Sports Authenticator",
"has_autograph_grade": false,
"has_qualifier": false,
"label": null,
"qualifier_type": null,
"slab_serial": "93265128",
"autograph_grade": null
}
],
"pagination": {
"total": 258817,
"page": 1,
"limit": 25,
"pages": 10353,
"next_cursor": null
},
"meta": {
"coverage_date_from": "2026-05-01",
"coverage_date_to": "2026-05-17",
"platforms_covered": ["Alt", "eBay", "Fanatics-Vault", "Fanatics-Weekly", "Goldin", "Heritage", "MySlabs", "Pristine", "REA", "SterlingSportsAuctions"],
"generated_at": "2026-05-17T10:00:00Z"
}
}| Field | Type | Coverage | Description |
|---|---|---|---|
| id | string | 100% | Unique sale identifier (platform-prefixed) |
| platform | string | 100% | eBay · Goldin · Heritage · Fanatics-Vault · Fanatics-Weekly · REA · Alt · Pristine · MySlabs · SterlingSportsAuctions |
| listing_type | string | 100% | auction · fixed_price · best_offer |
| title | string | 100% | Raw listing title as scraped |
| sale_date | string | 100% | YYYY-MM-DD of the sale |
| sold_at | string | 100% | ISO 8601 timestamp of sale (UTC) |
| price | number | 100% | Final sale price in USD. For best_offer, the true negotiated price. |
| currency | string | 100% | Always USD |
| seller | string | ~95% | Seller username |
| bids | integer|null | ~60% | Number of bids (auction only) |
| feedback | number|null | ~96% | Seller feedback score (e.g. 99.7) |
| image_url | string|null | ~85% | Full-size listing image URL |
| thumbnail_url | string|null | ~85% | Thumbnail image URL |
| listing_url | string|null | ~99% | Original listing URL |
| card_description | string|null | ~40% | Parsed card description from grading label |
| cert | string|null | ~12% | Grading certificate number |
| condition | string|null | ~8% | Raw condition string from listing |
| grade | string|null | ~12% | Numeric grade (e.g. "10", "9.5", "Auth") |
| grader | string|null | ~12% | Grader abbreviation: PSA · BGS · CGC · SGC |
| grading_company | string|null | ~12% | Full grading company name |
| has_autograph_grade | boolean|null | ~12% | Whether the slab has a separate auto grade |
| has_qualifier | boolean|null | ~12% | Whether the grade has a qualifier (e.g. OC, MK) |
| label | string|null | ~10% | Grading label variant (e.g. "Gold Label") |
| qualifier_type | string|null | ~3% | Qualifier description (e.g. "OC", "MK", "ST") |
| slab_serial | string|null | ~12% | Slab serial / cert number (may match cert) |
| autograph_grade | string|null | ~4% | Autograph sub-grade where graded separately |
listing_type: "best_offer" — the pricefield is the true final negotiated price, not the listing price. Most data providers don't expose this. We do.Error
Error codes
| Status | Meaning |
|---|---|
| 401 | Invalid or missing API key |
| 403 | Action requires a higher plan (e.g. cursor pagination, webhook management) |
| 404 | Resource not found |
| 422 | Validation error — check parameter types and ranges |
| 429 | Daily sales limit reached. Resets at midnight UTC. Upgrade for more. |
| 500 | Server error — try again shortly |
Webhooks
Webhooks
Pro and Enterprise plans can register an HTTPS endpoint to receive a POST notification after each data refresh.
Register
POST /api/v1/market/webhook
x-market-api-key: tca_your_key_here
Content-Type: application/json
{
"url": "https://your-server.com/webhook",
"secret": "your-hmac-signing-secret"
}Payload
{
"event": "data_refresh_complete",
"date": "2026-05-16",
"records": 258817,
"timestamp": "2026-05-16T10:05:00Z"
}Verify the signature
Each request includes X-Webhook-Signature: sha256=<hex>. Compute HMAC-SHA256 over the raw body using your secret.
import hashlib, hmac
def verify_webhook(body: bytes, secret: str, sig_header: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, sig_header)Rate
Rate limits
The only enforced limits are sales rows returned per day and how far back you can query. Counters reset at midnight UTC.
| Plan | Sales/day | Lookback |
|---|---|---|
| Free | 5,000 | 3 days |
| Starter | 50,000 | 14 days |
| Pro | 500,000 | 90 days |
| Business | 1,000,000 | 1 year |
| Enterprise | Unlimited | All time |
Max limit is 1,000 rows per request on all plans. View full pricing →
MCP
MCP Server
The MCP (Model Context Protocol) server exposes 7 analysis tools over a single streamable HTTP endpoint. Any MCP-compatible client — Claude Desktop, Claude Code, Cursor, Windsurf, ChatGPT Desktop, LangChain — can connect with one URL.
Endpoint
Protocol: JSON-RPC 2.0 · Transport: streamable HTTP
Discover available tools
{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/list"
}Claude Desktop
{
"mcpServers": {
"thecardapi": {
"command": "npx",
"args": ["mcp-remote", "https://thecardapi.com/api/mcp",
"--header", "Authorization: Bearer YOUR_API_KEY"]
}
}
}Claude Code
claude mcp add thecardapi \
--transport http \
--url https://thecardapi.com/api/mcp \
--header "Authorization: Bearer YOUR_API_KEY"Cursor / Windsurf
{
"mcpServers": {
"thecardapi": {
"url": "https://thecardapi.com/api/mcp",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}See the full MCP integration guide → for all clients.
MCP
MCP Tools
Each tool is called via method: "tools/call" with a name and arguments object.
Find recent sold prices for any card across eBay, Goldin, Heritage, Fanatics, and more. Returns individual sale records sorted by date. Supports filtering by platform, grader, grade, listing type, date range, and price range.
Parameters
| query | string | optional | Full-text search — e.g. 'PSA 10 Luka Doncic 2018 Prizm Silver' |
| platform | string | optional | eBay | Goldin | Heritage | Fanatics-Vault | Fanatics-Weekly | REA | Pristine | Alt | MySlabs | SterlingSportsAuctions |
| grader | string | optional | psa | cgc | beckett | sgc |
| grade | string | optional | 10 | 9.5 | 9 | 8.5 | 8 | 7 | auth | 10pristine |
| listing_type | string | optional | Auction | FixedPrice | BestOffer |
| date_from | string | optional | Start date YYYY-MM-DD |
| date_to | string | optional | End date YYYY-MM-DD |
| price_min | number | optional | Minimum sale price |
| price_max | number | optional | Maximum sale price |
| limit | integer | optional | Results to return (1–20, default: 10) |
Example call
{
"jsonrpc": "2.0", "id": "1",
"method": "tools/call",
"params": {
"name": "search_cards",
"arguments": {
"query": "PSA 10 Luka Doncic 2018 Prizm Silver",
"listing_type": "BestOffer",
"limit": 10
}
}
}Response (abbreviated)
{
"total_returned": 10,
"results": [
{
"id": "ebay-137222685761",
"title": "2018 Panini Prizm Silver Luka Doncic PSA 10",
"platform": "eBay",
"listing_type": "BestOffer",
"price": 4800.00,
"sale_date": "2026-05-16",
"sold_at": "2026-05-16T14:23:00Z",
"seller": "pwcc_auctions",
"feedback": 99.8,
"bids": null,
"grader": "PSA",
"grade": "10",
"slab_serial": "84566824",
"listing_url": "https://www.ebay.com/itm/137222685761"
}
],
"note": "BestOffer prices reflect the true final negotiated amount, not the list price."
}See exactly how PSA/BGS grade affects price for a specific card. Returns a full price ladder sorted grade-high to grade-low, plus the grade where the value jump is sharpest.
Parameters
| query | string | required | Card to analyze — e.g. 'Luka Doncic 2018 Prizm Silver' |
| grader | string | optional | psa (default) | cgc | beckett | sgc |
| lookback_days | integer | optional | Days of history to include (default: 90) |
Example call
{
"jsonrpc": "2.0", "id": "1",
"method": "tools/call",
"params": {
"name": "grade_impact_analysis",
"arguments": {
"query": "Luka Doncic 2018 Prizm Silver",
"grader": "psa",
"lookback_days": 90
}
}
}Response (abbreviated)
{
"query": "Luka Doncic 2018 Prizm Silver",
"grader": "PSA",
"lookback_days": 90,
"total_sales": 49,
"price_ladder": [
{ "grade": "10", "sales": 6, "avg_price": 9200, "median_price": 8750, "min_price": 7800, "max_price": 11200 },
{ "grade": "9", "sales": 28, "avg_price": 3400, "median_price": 3250, "min_price": 2800, "max_price": 4100 },
{ "grade": "8", "sales": 12, "avg_price": 1950, "median_price": 1875, "min_price": 1600, "max_price": 2300 },
{ "grade": "7", "sales": 3, "avg_price": 850, "median_price": 820, "min_price": 750, "max_price": 980 }
],
"best_value_grade": {
"grade": "9",
"reason": "Stepping up to 10 costs 171% more — this is the steepest value jump in the price ladder."
}
}PSA vs CGC vs SGC vs BGS for the same card at the same grade. Find which grader commands the highest market premium.
Parameters
| query | string | required | Card to compare — e.g. 'Wembanyama 2023 Prizm Silver' |
| grade | string | required | Grade to compare across graders — e.g. 10 | 9.5 | 9 | 8.5 | 8 |
| lookback_days | integer | optional | Days of history (default: 90) |
Example call
{
"jsonrpc": "2.0", "id": "1",
"method": "tools/call",
"params": {
"name": "grader_comparison",
"arguments": {
"query": "Wembanyama 2023 Prizm Silver",
"grade": "9"
}
}
}Response (abbreviated)
{
"query": "Wembanyama 2023 Prizm Silver",
"grade": "9",
"lookback_days": 90,
"by_grader": [
{ "grader": "PSA", "sales": 18, "avg_price": 1450, "median_price": 1380 },
{ "grader": "BGS", "sales": 7, "avg_price": 1210, "median_price": 1175 },
{ "grader": "CGC", "sales": 4, "avg_price": 980, "median_price": 950 },
{ "grader": "SGC", "sales": 2, "avg_price": 890, "median_price": 890 }
],
"takeaway": "PSA commands the highest avg price at $1450",
"comparisons": [
{ "grader": "BGS", "pct_cheaper_than_top": 17 },
{ "grader": "CGC", "pct_cheaper_than_top": 32 },
{ "grader": "SGC", "pct_cheaper_than_top": 39 }
]
}Is this card trending up or down? Compares a recent time window against the prior window of equal length, with volume data. Upper bound is always yesterday so partial-day data never skews the result.
Parameters
| query | string | required | Card to analyze — e.g. 'Prizm Silver Wembanyama' |
| lookback_days | integer | optional | Length of each comparison window in days (default: 7) |
| grader | string | optional | Optional — filter by grader: psa | cgc | beckett | sgc |
| grade | string | optional | Optional — filter by grade (e.g. 10, 9.5) |
Example call
{
"jsonrpc": "2.0", "id": "1",
"method": "tools/call",
"params": {
"name": "price_momentum",
"arguments": {
"query": "Wembanyama Prizm Silver",
"lookback_days": 14
}
}
}Response (abbreviated)
{
"query": "Wembanyama Prizm Silver",
"window_days": 14,
"recent_window": {
"from": "2026-05-03", "to": "2026-05-16",
"sales": 42, "avg_price": 1380
},
"prior_window": {
"from": "2026-04-19", "to": "2026-05-02",
"sales": 35, "avg_price": 1150
},
"price_change_pct": 20.0,
"volume_change_pct": 20.0,
"momentum": "rising",
"note": "'rising' means both price and volume increased vs the prior window of the same length."
}Should you grade this card? Real cost math (PSA/CGC/SGC/BGS fees + shipping, all tiers including bulk) vs actual market comps. Returns expected profit at each grade, break-even analysis, and honest caveats.
Parameters
| query | string | required | Card to evaluate — e.g. '1986 Fleer Jordan 57' |
| raw_purchase_price | number | required | What you paid (or plan to pay) for the raw ungraded card |
| target_grade | string | optional | Grade you hope to achieve: 10 | 9.5 | 9 | 8.5 (default: 10) |
| grader | string | optional | psa (default) | cgc | beckett | sgc |
| submission_tier | string | optional | bulk | economy | standard (default) | express |
Example call
{
"jsonrpc": "2.0", "id": "1",
"method": "tools/call",
"params": {
"name": "grading_value_calculator",
"arguments": {
"query": "1986 Fleer Jordan 57",
"raw_purchase_price": 6500,
"target_grade": "10",
"grader": "psa",
"submission_tier": "standard"
}
}
}Response (abbreviated)
{
"query": "1986 Fleer Jordan 57",
"raw_purchase_price": 6500,
"grader": "PSA",
"target_grade": "10",
"grading_costs": {
"service_tier": "standard",
"per_card_fee": "$79.99",
"turnaround": "25 days",
"shipping_roundtrip": "$40–$60 (continental US)",
"total_estimate": "$119.99–$139.99",
"total_mid_estimate": 130
},
"grade_scenarios": [
{ "grade": "10", "sales": 8, "avg_price": 42000, "expected_profit": 35370, "is_target": true },
{ "grade": "9", "sales": 22, "avg_price": 9800, "expected_profit": 3170, "is_target": false },
{ "grade": "8", "sales": 11, "avg_price": 4200, "expected_profit": -2330, "is_target": false }
],
"math": {
"if_card_grades_at_target": "$42000 (avg sale price)",
"minus_raw_cost": "-$6500",
"minus_grading_and_ship": "-$130 (midpoint estimate)",
"expected_profit": "$+35370",
"break_even_grade": "8"
},
"caveats": [
"Grading outcome is NOT guaranteed — these numbers assume the card achieves each grade.",
"Only 8 comps found at 10 — price estimate may be unreliable."
]
}Research any card seller — feedback score, total sales, average prices, which grades they specialize in, and a trust signal. Works across all platforms, not just eBay.
Parameters
| seller | string | required | Seller name or partial name — e.g. 'probstein', 'dcsports87' |
| lookback_days | integer | optional | Days of history to analyze (default: 90) |
Example call
{
"jsonrpc": "2.0", "id": "1",
"method": "tools/call",
"params": {
"name": "seller_lookup",
"arguments": {
"seller": "pwcc_auctions",
"lookback_days": 90
}
}
}Response (abbreviated)
{
"seller": "pwcc_auctions",
"lookback_days": 90,
"stats": {
"total_sales": 847,
"avg_price": 1240,
"median_price": 680,
"max_sale": 42000,
"feedback_score": 99.8,
"last_active": "2026-05-16"
},
"top_platforms": [
{ "platform": "eBay", "sales": 847 }
],
"top_grades": [
{ "grader": "PSA", "grade": "10", "sales": 312 },
{ "grader": "PSA", "grade": "9", "sales": 198 },
{ "grader": "BGS", "grade": "9.5","sales": 87 }
],
"trust_signal": "High-volume established dealer — very safe to buy from"
}Enter a PSA/BGS/SGC/CGC serial number and see every time that specific graded card sold. Like Carfax, but for slabs — full ownership price history with appreciation trend.
Parameters
| slab_serial | string | required | The serial or cert number on the graded slab label — e.g. '84566824' |
| lookback_days | integer | optional | Limit to sales within this many days (default: all-time) |
Example call
{
"jsonrpc": "2.0", "id": "1",
"method": "tools/call",
"params": {
"name": "slab_lookup",
"arguments": {
"slab_serial": "84566824"
}
}
}Response (abbreviated)
{
"found": true,
"slab_serial": "84566824",
"card": "2018 Panini Prizm Silver Luka Doncic PSA 10",
"grader": "PSA",
"grade": "10",
"total_sales": 3,
"sales": [
{ "date": "2025-07-22", "price": 3600, "platform": "eBay", "listing_type": "Auction", "seller": "cards4sale" },
{ "date": "2025-11-08", "price": 3850, "platform": "eBay", "listing_type": "BestOffer", "seller": "pwcc_auctions" },
{ "date": "2026-03-12", "price": 4200, "platform": "eBay", "listing_type": "Auction", "seller": "goldenage_cards" }
],
"appreciation_pct": 16.7,
"trend": "rising",
"summary": "From $3600 → $4200 (16.7% rising)"
}Code
Code examples
Python — REST API
import requests
API_KEY = "tca_your_key_here"
BASE = "https://thecardapi.com/api/v1/market"
HEADERS = {"x-market-api-key": API_KEY}
# Search recent Ohtani auctions
r = requests.get(f"{BASE}/sales", headers=HEADERS, params={
"q": "Shohei Ohtani",
"listing_type": "auction",
"price_min": 50,
"limit": 50,
})
for sale in r.json()["data"]:
print(sale["sale_date"], sale["price"], sale["title"][:60])
# Incremental sync — only records scraped since your last poll
r = requests.get(f"{BASE}/sales", headers=HEADERS, params={
"indexed_after": "2026-05-15T10:00:00Z",
"limit": 100,
})Python — MCP tools/call
import requests
MCP_URL = "https://thecardapi.com/api/mcp"
HEADERS = {"Authorization": "Bearer tca_your_key_here", "Content-Type": "application/json"}
def call_tool(name: str, arguments: dict) -> dict:
payload = {
"jsonrpc": "2.0", "id": "1",
"method": "tools/call",
"params": {"name": name, "arguments": arguments},
}
r = requests.post(MCP_URL, headers=HEADERS, json=payload)
result = r.json()
if result.get("error"):
raise RuntimeError(result["error"]["message"])
import json
return json.loads(result["result"]["content"][0]["text"])
# Grade ladder for Mantle cards over $1,000
data = call_tool("grade_impact_analysis", {
"query": "Mickey Mantle",
"grader": "psa",
"lookback_days": 30,
})
for row in data["price_ladder"]:
avg = "{:,.0f}".format(row['avg_price'])
print(f"PSA {row['grade']}: ${avg} avg ({row['sales']} sales)")cURL
# REST — search for PSA 10 cards
curl "https://thecardapi.com/api/v1/market/sales?q=psa+10&limit=25" \
-H "x-market-api-key: tca_your_key_here"
# MCP — call price_momentum tool
curl https://thecardapi.com/api/mcp \
-H "Authorization: Bearer tca_your_key_here" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":"1","method":"tools/call","params":{"name":"price_momentum","arguments":{"query":"Wembanyama Prizm Silver"}}}'Node.js
const res = await fetch(
"https://thecardapi.com/api/v1/market/sales?q=topps+chrome&limit=50",
{ headers: { "x-market-api-key": "tca_your_key_here" } }
);
const { data, pagination } = await res.json();
console.log(`${pagination.total} results`);LangChain (Python)
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
from langchain_anthropic import ChatAnthropic
async def main():
async with MultiServerMCPClient({
"thecardapi": {
"url": "https://thecardapi.com/api/mcp",
"transport": "streamable_http",
"headers": {"Authorization": "Bearer tca_your_key_here"},
}
}) as client:
tools = await client.get_tools()
model = ChatAnthropic(model="claude-sonnet-4-6")
agent = create_react_agent(model, tools)
result = await agent.ainvoke({
"messages": "Is grading my 1986 Fleer Jordan worth it at $6,500?"
})
print(result["messages"][-1].content)
asyncio.run(main())Ready to start building?
Free tier includes 5,000 sales/day with 3-day lookback. No credit card required.