Changelog
New fields, capabilities, and improvements. We ship every few days.
The Catalog API — 15.2M+ cards with permanent UCIDs
GET /api/v1/catalog?set_id=UC-2EMB5-SR6Q6-R&card_number=27 → one record: Mike Trout, 2023 Topps #27, UC-1KJZD-TZG7C-6.
The Catalog API is generally available: structured access to 15.2M+ cards across 306,000+ sets and 15 sports — full checklists, rookie/auto/relic flags, print runs, parallels linked to their parent products, and card images. Sales tell you what's trading; the catalog tells you what exists. It's included with Pro and Enterprise at no extra charge, and available on Builder as a $29/mo add-on.
Every card and set now carries a UCID — a permanent, check-digit-protected identifier (UC-XXXXX-XXXXX-C) that never changes and is never reused. Pass a UCID anywhere an ID is accepted; a typo returns an error instead of the wrong card. Parallels answer with their parent product — a "Gold Rainbow Foil" card knows it belongs to 2021 Topps Chrome — and serial-numbered parallels expose print_run for deterministic version identification.
| Field | Description |
|---|---|
| ucid | Permanent unique identifier on every card and set — the join key to build on |
| card_number + set_id | One-record existence checks — "is there a #27 in this set?" costs 1 record, not 100 |
| parent_set_name | Parallels and inserts carry their parent product name and UCID |
| set_name | Case-insensitive substring filter on set names |
| X-RateLimit headers | Catalog allowance headers on every response — catalog usage never touches your sales budget |
| Strict validation | Unrecognized query parameters return a 400 listing supported ones — misspelled filters never silently return wrong results |
original_price and real currencies on /sales
A card listed at $19.99 that closed at $15.69 now shows both numbers — the accepted-vs-asking spread is queryable for the first time.
Two new response fields on every /market/sales record. original_price is the pre-negotiation asking price on Best Offer sales — the price the card was listed at before the offer was accepted. It's populated on eBay Best Offer records from August 2026 onward.
currency now reports the listing's real currency (ISO 4217 — USD, GBP, CAD, AUD, EUR, …) instead of always reading USD. About 5% of eBay sales settle in non-USD currencies; those records are now labeled honestly so you can convert or filter as needed. Records indexed before August 2026 continue to report USD until the historical backfill completes.
| Field | Description |
|---|---|
| original_price | number | null — asking price before the accepted offer (Best Offer sales, eBay Aug 2026+) |
| currency | string — ISO 4217 currency of price and original_price (was always "USD" before) |
| Zero changes | Purely additive — existing integrations keep working untouched |
A faster API — new serving infrastructure
Nothing to change on your end — same endpoints and keys, just faster responses. This is the first of several performance investments landing this quarter.
We've moved The Card API onto dedicated, always-on infrastructure. The result: typical search queries now return in under half a second — roughly 6x faster than before — and the slow "first request after idle" delays some of you measured at up to 10 seconds are gone entirely. There is no cold start anymore, because the servers never sleep.
We then went deeper: we rebuilt the search index at the heart of /sales, overhauled how results are fetched, and upgraded the database hardware behind every query. Searches that name a specific card or player now resolve in tens of milliseconds on our side — 10–30x faster than before — and response times stay flat even when many requests land at once. We also fixed two long-standing quirks along the way: searches containing an ampersand (Allen & Ginter, Scarlet & Violet) or an apostrophe were silently taking a much slower path, and identical requests could occasionally return results in a different order. Both are gone. Continuous automated health monitoring now watches the whole path so we know about any issue before you do. Nothing changes on your end: same base URL, same API keys, same response format — your integration just got dramatically faster without you touching a line of code.
| Field | Description |
|---|---|
| 6–10x faster | Typical search queries: ~0.3–0.4s end-to-end, down from ~2.6s |
| 10–30x on heavy searches | Rebuilt search index: specific-card and player queries resolve in tens of milliseconds server-side |
| No cold starts | The up-to-10s first-request-after-idle delay is eliminated — always-on servers |
| Burst-proof | Latency spikes under concurrent traffic are gone — response times stay flat under load |
| Bug fixes | "&" and apostrophe searches no longer take a slow fallback path; result ordering is now fully deterministic |
| Zero changes | Same endpoints, keys, and response format — nothing to update in your code |
graded=true — one flag for graded-only sales
?graded=true — every graded sale, every platform, one parameter. No more client-side null checks on grader.
The most-requested filter is live: add ?graded=true to /v1/market/sales and get only professionally graded cards — PSA, BGS, SGC, CGC, and every other company we recognize — in one flag. ?graded=false does the inverse and returns only raw, ungraded sales. It works on every platform, and combines with all existing filters.
Grading data also got materially better this week: we found and fixed 640,000+ historical eBay sales whose PSA/BGS/SGC/CGC details were present in the listing but never extracted. The graded eBay pool grew from 2.35M to over 3M records, and every new record is now checked at ingest time.
| Field | Description |
|---|---|
| graded=true | Only sales where the card's condition was professionally graded (any company) |
| graded=false | Only raw/ungraded sales — cleanly excludes every slab |
| Semantics | Autograph-authentication-only slabs (PSA/DNA, JSA, BAS "Authentic") count as ungraded — the card itself was never condition-graded. Dual-graded slabs carry the card grade. |
| Combine | Works with grader, grade, platform, q, dates, and every other parameter — e.g. ?graded=true&platform=goldin |
TCGplayer sold prices — a new data source
?platform=tcgplayer returns TCGplayer sales only. Data begins July 12, 2026 — the raw TCG singles market eBay doesn't capture, updated continuously.
The Card API now covers TCGplayer, the largest dedicated trading-card-game marketplace. Every record is a true final sold price — TCGplayer is a pure fixed-price marketplace, so there are no hidden accepted offers or asking prices in the data.
Coverage begins July 12, 2026 and runs forward continuously, starting with the full Pokémon English catalog (~32,000 products). TCGplayer records include condition (Near Mint through Damaged), set, card number, variant (Holofoil, Reverse Holofoil, 1st Edition), rarity, and language — variant, rarity, and language arrive in the features field.
| Field | Description |
|---|---|
| platform | "TCGplayer" — filter with ?platform=tcgplayer |
| category | All TCGplayer records are category=tcg, so ?category=tcg spans eBay and TCGplayer together |
| condition | TCGplayer's raw-card condition scale: Near Mint, Lightly Played, Moderately Played, Heavily Played, Damaged |
| features | Variant, rarity, and language — e.g. "1st Edition Holofoil, Secret Rare" |
Self-serve API key regeneration
Visit thecardapi.com/regenerate any time. Works for every plan, Free through Enterprise.
Lost your API key — or need to rotate it after a leak? You can now regenerate it yourself at thecardapi.com/regenerate. Enter your account email, click the confirmation link we send you, and your new key is issued instantly.
Regenerating is safe by design: your plan, rate limits, usage counters, and billing are completely unaffected — only the key itself changes. The old key stops working the moment the new one is issued, which makes this the right tool if a key was ever exposed in client-side code or a public repo.
| Field | Description |
|---|---|
| Instant | Old key revoked and new key issued in one click — no support ticket, no waiting |
| Secure | Confirmation links are single-use and expire after 30 minutes |
| Zero churn | Tier, limits, and billing carry over — swap the key in your code and you're done |
category field — filter sports, TCG, and non-sport
?category=sports returns only sports cards. Combine with any existing filter — platform, date, grader, print run, etc.
Every eBay record now includes a category field with one of three values: sports, tcg, or non_sport. Use ?category=sports to filter to sports cards only and exclude Pokémon, Magic, and other TCG listings.
Coverage: eBay records indexed from June 6, 2026 onward. Earlier eBay history and auction house records (Goldin, REA, SCP, Lelands, Hake's) return null — categorization for those sources is in progress.
| Field | Description |
|---|---|
| sports | Baseball, basketball, football, hockey, soccer, and all other sports cards |
| tcg | Pokémon, Magic: The Gathering, and all other trading card games |
| non_sport | Entertainment cards, non-sport memorabilia |
New tier structure — Free, Starter, Builder, Pro
Add-ons for Pro: Full Daily Feed ($99/mo) and Unlimited Lookback ($99/mo). Webhooks add-on ($9/mo) available on Starter and Builder. All paid plans include a 7-day free trial.
We've restructured our plans to better fit the full range of use cases we see — from hobbyists to commercial data products. The new tiers are Free ($0), Starter ($9/mo), Builder ($49/mo), and Pro ($199/mo), with Enterprise on custom terms.
All existing Starter subscribers ($19/mo) are grandfathered at their current limits — 100,000 records/day and 30-day lookback — with no change to billing. If you're on that plan, nothing changes.
| Field | Description |
|---|---|
| Free | 5,000 records/day · 3-day lookback · MCP access |
| Starter | $9/mo · 10,000 records/day · 14-day lookback · CSV export |
| Builder | $49/mo · 50,000 records/day · 30-day lookback |
| Pro | $199/mo · 200,000 records/day · 90-day lookback · Webhooks included |
MCP authentication fix
If you were seeing 401 errors on tools/call, update your MCP server URL to https://www.thecardapi.com/api/mcp.
MCP tools/call requests were returning 401 for some clients due to a redirect stripping the Authorization header. The correct MCP endpoint is https://www.thecardapi.com/api/mcp — all documentation has been updated to reflect this.
Exclusion-term queries up to 10× faster
No integration changes required. All existing queries benefit automatically.
Queries that exclude variants — graded copies, parallels, colored borders, and similar — are now significantly faster. The fix applies automatically to any query that uses the -term syntax to exclude unwanted listings.
The previous implementation issued one NOT hasToken() check per exclusion term, preventing the query engine from short-circuiting early. The new implementation wraps all exclusion terms in a single NOT (A OR B OR C …) expression, which allows the engine to stop evaluating as soon as any excluded token is found. Queries with 10 or more exclusion terms see the largest benefit.
| Field | Description |
|---|---|
| p95 (exclusion queries) | 6,300ms → 617ms. ~10× improvement. |
| p50 (exclusion queries) | 507ms → 219ms. |
| p95 (no exclusions) | 601ms → 503ms. |
image_url now full-resolution (1,600px); thumbnail_url stays at 500px
No integration changes required. Both fields remain in the response.
image_url now always returns the full-resolution listing image (1,600px wide). Previously, the stored URL size was inconsistent — approximately 98% of records returned a 140px thumbnail, making image_url unsuitable for detail views.
thumbnail_url is unchanged at 500px and remains the right choice for list and card views. Both fields are derived from the same underlying eBay CDN URL — only the size parameter differs.
| Field | Description |
|---|---|
| image_url | Full-resolution listing image — 1,600px wide. Use for detail / lightbox views. |
| thumbnail_url | 500px. Unchanged. Use for list views, card grids, and previews. |
CSV export now returns rate-limit headers
No breaking changes. Headers appear automatically on all CSV responses.
GET /v1/market/sales/export/csv now returns X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers alongside the file download — the same headers you already see on JSON responses.
X-RateLimit-Remaining reflects your remaining daily budget after the download is charged, so you can tell exactly how much headroom you have left without making an extra API call.
| Field | Description |
|---|---|
| X-RateLimit-Limit | Your total daily row budget (e.g. 100000 on Starter). "unlimited" for plans without a cap. |
| X-RateLimit-Remaining | Rows remaining for today after this download. Deducted at the time the file is served. |
| X-RateLimit-Reset | Unix timestamp (UTC) when the budget resets — midnight UTC of the current day. |
GET /v1/market/sales/export/csv?q=ohtani&date_from=2026-01-01
-H "x-market-api-key: tca_..." -o ohtani_sales.csv
Response headers:
X-RateLimit-Limit: 100000
X-RateLimit-Remaining: 62000
X-RateLimit-Reset: 1751155200One daily budget — 100K rows, shared across JSON calls and CSV downloads
Starter: 100K rows/day · JSON calls and CSV downloads share the same budget · no breaking changes
Starter plan now has a single shared daily budget of 100,000 rows. Every row you receive counts toward the same pool — whether it comes from a paginated JSON call or a CSV file download. Pull 60,000 rows today and you have 40,000 left, available as more API calls or a CSV download.
CSV downloads are now counted toward your budget. When you call GET /v1/market/sales/export/csv, the number of rows in the file is deducted from your daily total. Check X-RateLimit-Remaining after any call — it always reflects your true remaining budget.
| Field | Description |
|---|---|
| GET /sales | Each row returned counts against your daily budget. X-RateLimit-Remaining updates after every response. |
| GET /sales/export/csv | Rows in the downloaded file count against the same daily budget. Same filter params as /sales. |
| X-RateLimit-Remaining | Your remaining rows for the day — updated after every JSON call and every CSV download. |
// JSON call: 1,000 rows returned
GET /v1/market/sales?q=ohtani&limit=1000
→ X-RateLimit-Limit: 100000
→ X-RateLimit-Remaining: 99000
// CSV download: 40,000 rows in the file
GET /v1/market/sales/export/csv?q=ohtani&date_from=2026-01-01
-H "x-market-api-key: tca_..." -o ohtani_sales.csv
// Next JSON call: budget reflects both
→ X-RateLimit-Remaining: 59000Webhooks add-on — $10/mo on Starter, 7-day free trial
$9/mo · Starter and Builder add-on · Up to 5 endpoints · 7-day free trial · HMAC-SHA256 signed · 3 retries with backoff
Webhooks are now available as a self-serve add-on for Starter subscribers. Register up to 5 HTTPS endpoints and we'll push every new card sale to them within ~30 seconds of indexing — no polling loop required.
Each delivery is a signed batch of up to 1,000 records in the same schema as GET /sales. We retry 3 times with backoff (0s / 5s / 30s) on failure. If all three fail, your cursor holds and you pick up exactly where you left off on the next cycle — no missed records, no duplicates.
| Field | Description |
|---|---|
| POST /webhook | Add an endpoint (max 5). Required: url, secret. Optional: label. |
| GET /webhook | List all active endpoints for your key. |
| DELETE /webhook/{id} | Remove an endpoint by ID. |
| X-Webhook-Signature | HMAC-SHA256 signature on every delivery. Verify against the raw request body. |
// Register an endpoint
POST /v1/market/webhook
{ "url": "https://your-server.com/hook", "secret": "your-secret", "label": "prod" }
// Delivery (POSTed to your URL every ~30s when new sales exist)
{
"event": "sales.batch",
"timestamp": "2026-06-20T10:00:00Z",
"count": 83,
"data": [ { "id": "ebay-...", "price": 312.00, ... } ]
}Cursor pagination on all plans · CSV export on Starter
Cursor pagination on all plans including Free · CSV export on Starter and above · no breaking changes
Cursor pagination is now available on every plan, including Free and Starter. Every response from /v1/market/sales now includes a next_cursor field in the pagination object when more results exist. Pass it as ?cursor= on your next request to fetch the next page — no offset drift, no missed or duplicated records as new data is indexed.
CSV export is now available on Starter and above. Hit GET /v1/market/sales/export/csv with the same filter params you'd use on /sales and receive a download-ready CSV file. Rows count against your shared daily budget (100K on Starter).
Both features require no integration changes if you're already on the API — just start using the new parameters.
| Field | Description |
|---|---|
| next_cursor | Opaque string in pagination object. Present when has_more=true. Pass as ?cursor= on the next request. |
| cursor | Request param. Pass next_cursor from a previous response to continue from exactly where you left off. |
| GET /sales/export/csv | Same filter params as /sales. Returns a CSV file download. Rows count against the shared daily budget. |
// Cursor pagination — page through large result sets
GET /v1/market/sales?q=psa+10+trout&limit=1000
→ pagination.next_cursor: "eyJwZ19pZCI6IDE4N..."
GET /v1/market/sales?q=psa+10+trout&limit=1000&cursor=eyJwZ19pZCI6IDE4N...
→ pagination.next_cursor: null // last page
// CSV download
GET /v1/market/sales/export/csv?q=ohtani&date_from=2026-01-01
→ CSV file downloadMajor auction house results — 175,000+ lots, 2012 to today
175,000+ lots · 3 auction houses · 2012–today · hammer price (add ~22% for all-in buyer cost) · use ?platform= to filter by house.
Sales data from three major card auction houses is now live in the API. Results appear automatically in any search alongside eBay data — no integration changes required. Use ?platform= to query a specific house or omit it entirely to search across all sources at once.
The combined dataset covers 175,000+ completed auction lots from 2012 through today — over a decade of high-value card sales. It includes bid counts, lot images, direct links to each lot page, and parsed grade/grader fields for slabbed cards. This is the same underlying data serious collectors and dealers use to establish market value.
One important distinction: auction house prices are hammer prices — the amount called at close by the auctioneer. Buyers pay an additional buyer's premium on top (typically 20–22%). eBay prices in the API are all-in. If you're comparing prices across platforms, account for this difference.
| Field | Description |
|---|---|
| platform | Filter to a specific auction house with ?platform=<name>. Omit to search across all platforms. |
| price | Hammer price for auction house lots — not all-in. Buyers pay an additional ~20–22% buyer's premium on top. |
| sold_at | Exact UTC close time — 100% populated for auction house lots. |
| listing_url | Direct link to the lot page. |
| feedback | Always null — not applicable for auction houses. |
// Search across all platforms (eBay + auction houses)
GET /v1/market/sales?q=psa+10+mickey+mantle
// Auction house record
{
"platform": "goldin",
"listing_type": "auction",
"title": "1952 Topps #311 Mickey Mantle — PSA VG-EX 4",
"sale_date": "2024-03-17",
"sold_at": "2024-03-17T02:30:00Z",
"price": 75000.00,
"bids": 18,
"grader": "PSA",
"grade": "4",
"price_confirmed": true
}shipping_price — buyer shipping cost, separate from sale price
~67% of records have shipping_price populated. ?shipping_max=0 for free shipping only.
Every sale response now includes shipping_price — the amount the buyer paid for shipping, separate from the card price. A free-shipping listing returns 0.00. When shipping cost was not disclosed by the seller, the field is null.
Filter by shipping cost with ?shipping_max=0 (free shipping only) or ?shipping_max=10 (shipping ≤ $10). Combine with price filters to compare true all-in costs across listings.
Coverage is approximately 67% of records. The remaining ~33% of listings did not publish shipping cost and return null.
| Field | Description |
|---|---|
| shipping_price | number|null. Buyer shipping cost in USD. 0.00 = free shipping. Null when not disclosed by the seller. |
| shipping_max | Filter param. Only return records with shipping_price ≤ this value. Use shipping_max=0 for free shipping only. Records with null shipping_price are excluded. |
// Free shipping only
GET /v1/market/sales?q=psa+10+mike+trout&shipping_max=0
// ≤ $10 shipping
GET /v1/market/sales?q=psa+10+ohtani&shipping_max=10
// Response (each record)
{
"id": "123456789",
"price": 312.00,
"shipping_price": 0.00,
...
}Webhooks — delivery daemon deployed, multi-endpoint fanout
Auction close → delivery: 9 min median · 11 min 90th pct. Every POST signed with HMAC-SHA256.
The webhook delivery daemon shipped. It polls every 30 seconds and fans out to all registered endpoints per API key. Each batch is HMAC-SHA256 signed and retried three times with backoff (0s / 5s / 30s) on failure.
This update also added support for multiple endpoints per key (up to 5) via a new webhook_endpoints table — moving from a single URL column to a normalized per-endpoint model.
| Field | Description |
|---|---|
| event | "sales.batch" — type identifier for the delivery |
| timestamp | ISO 8601 UTC timestamp of the delivery |
| count | Number of records in this batch (up to 1,000) |
| data | Array of sale records — same schema as /v1/market/sales |
POST https://your-endpoint.com/webhook
Content-Type: application/json
X-Webhook-Signature: sha256=<hmac-sha256>
{
"event": "sales.batch",
"timestamp": "2026-06-14T06:09:00Z",
"count": 47,
"data": [
{
"id": "ebay-123456789",
"price": 312.00,
"listing_type": "auction",
"sold_at": "2026-06-14T06:00:24Z",
"player": "Shohei Ohtani",
...
}
]
}Card catalog — 13.8M cards, sets, and metadata
The catalog API is now in beta. Search and browse 13.8M cards across sports, years, sets, and player names — with structured flags for rookies, autos, relics, short prints, print runs, and more. Card images are served from our own CDN.
The catalog is a complement to the sales API, not a replacement. Use it to build structured lookups, enrich your own records with card metadata, or power a type-ahead search by player or set name. The Catalog API is an add-on available to any plan. Access is currently invite-only while we finalize pricing. Email hello@thecardapi.com to join the beta.
| Field | Description |
|---|---|
| GET /v1/catalog | Search and filter cards by set, player, sport, year, variant flags |
| GET /v1/catalog/{id} | Single card by ID |
| GET /v1/catalog/sets | Browse sets — filterable by sport, year, name |
| GET /v1/catalog/sets/{id} | Single set with card count and image coverage |
| GET /v1/catalog/sports | List of distinct sports in the catalog |
{
"id": 1042981,
"set_id": 4821,
"sport": "Baseball",
"year": 2011,
"set_name": "2011 Topps Update Series",
"card_number": "US175",
"subject": "Mike Trout",
"is_rookie": true,
"is_auto": false,
"print_run": null,
"image_url_front": "https://cdn.thecardapi.com/cards/1042981_front.jpg",
"has_front_image": true
}print_run field — filter by serial run, retrieve structured print-run value
~36% of records have print_run populated. /99 → 99. 1/1 → 1. Base cards → null.
Every sale response now includes a print_run field — the denominator of the serial fraction stamped on the card. A card serialized /99 returns "print_run": 99. A 1/1 returns "print_run": 1. A base card with no serial number returns null.
Filter results directly with ?print_run_max=99 (any card numbered /99 or lower) or ?print_run_min=1 (1/1s only). Combine both to target a range — e.g. print_run_min=1&print_run_max=10 for ultra-rare single-digit print runs.
Approximately 36% of all records (6.2 million rows) have print_run populated. Coverage grows automatically as historical data backfills.
| Field | Description |
|---|---|
| print_run | Integer or null. Denominator of the serial fraction. /99 → 99. /10 → 10. 1/1 → 1. Null for unlisted base cards. |
| print_run_min | Filter param. Only return records with print_run ≥ this value (inclusive). |
| print_run_max | Filter param. Only return records with print_run ≤ this value (inclusive). |
// Cards serialized /10 or lower
GET /v1/market/sales?q=mike+trout&print_run_max=10
// Response (each record)
{
"id": "ebay-387214905012",
"title": "2011 Topps Update Mike Trout RC /10 BGS 9.5",
"price": 14500.00,
"listing_type": "auction",
"sold_at": "2026-06-14T04:22:11Z",
"print_run": 10
}10 structured metadata fields added to the response schema
Every response from /v1/market/sales now includes 10 structured fields — player, sport, team, manufacturer, card_set, card_number, year, season, league, and features. These fields are populated where available from the original listing data. They will be null (or [] for features) when not present.
Coverage is currently limited to recent sales where structured listing data was provided by the seller. Coverage grows automatically as more listings include this data — no integration changes are required.
| Field | Description |
|---|---|
| player | Player name |
| sport | Sport (Baseball, Basketball, Hockey, …) |
| team | Team name at time of card printing |
| manufacturer | Card manufacturer (Topps, Panini, Bowman, …) |
| card_set | Set name (e.g. 2022 Topps Update Series) |
| card_number | Set card number (e.g. #295 or BCP-42) |
| year | Card year |
| season | Sports season (e.g. 2024-25) |
| league | League (e.g. Major League (MLB), NBA) |
| features | Array of card attributes. e.g. ["Auto", "Rookie", "Patch"]. Empty array when not provided. |
{
"player": "Bobby Witt Jr.",
"sport": "Baseball",
"team": "Kansas City Royals",
"manufacturer": "Topps",
"card_set": "2022 Topps Update Series",
"card_number": "SMLB-82",
"year": 2022,
"season": "2022",
"league": "Major League (MLB)",
"features": ["Insert", "Rookie"]
}Print-run and serial-number search — exact matching, no false positives
Previously /10 matched PSA 10 grades. Previously 47/100 matched any record containing 47. Both fixed.
Searching for /10 now returns cards from a 10-copy print run — not PSA 10 grades. Searching for 47/100 now matches the exact serial-numbered card stamped 47 out of 100, not any record containing the number 47.
Two distinct search intents are handled separately: N/M (e.g. 47/100) targets the specific physical card with that serial stamp. /N (e.g. /10) matches any card from that print run. Both work identically in the playground and the market API.
price_confirmed — distinguish confirmed prices from early captures
Every record now includes price_confirmed. true means the price is the verified final transaction amount. false means the record was captured very shortly after close and the final price will be confirmed on our next daily run (within 24 hours).
Most use cases can ignore this. It matters most if you are building something that processes data continuously and needs to distinguish between an early capture and a settled transaction.
| Field | Description |
|---|---|
| price_confirmed | true = verified final price. false = early capture, confirmed price available within 24 hours. |
3–5ms search across 17 million records
683ms → 3–5ms. No API changes required.
A full-text sales search — e.g. 'PSA 10 Mike Trout 2011 Topps Update' filtered by grade, grader, and date range — now returns in 3–5ms across 17 million records. The same query previously took 683ms.
This was a complete rewrite of the query backend. No API changes were required. All existing integrations benefit automatically.
Coming soon
- →Additional auction houses — PWCC, Heritage, and more
- →Historical bulk exports — full dataset downloads for companies that need years of data at once
- →Per-card price history — time-series comps by catalog ID
Questions or feedback? hello@thecardapi.com