Skip to content

API Getting Started

Live Pokémon TCG market data — try the playground free, then unlock the full API

Last updated:

Start here — Quick startLink copied!

  1. Get a key at the dashboard and send it as Authorization: Bearer [REDACTED]. Without one, price and search still answer at the playground tier (keyless calls return X-LOR-Tier: playground).
  2. Price a card (Umbreon VMAX, PSA 10):
    curl "https://silphcoanalytics.xyz/api/v3/price?tcg_card_id=swsh7-215&grade_key=PSA%3A10"
    { "value_usd": 1234.56, "status": "ok", "method": "median_3",
      "n_sales": 3, "cohort": { "resolved_by": "exact" } }
  3. Get its history (trailing 90 daily points):
    curl "https://silphcoanalytics.xyz/api/v3/cards/swsh7-215/price-history?grade_key=PSA%3A10&interval=day&limit=90"
    2026-10-05  1189.00  (n=3)
    2026-10-06  1210.50  (n=2)
    2026-10-07  1234.56  (n=3)
CallGives you
GET /priceThe price now
POST /price/batchMany prices at once (up to 100 cohorts)
GET /cards/{id}/price-historyHow a lane moved
GET /cards/{id}/chart-seriesSale buckets for charts

Identify a cardLink copied!

By idLink copied!

A card is its set code plus print number (base1-4, swsh7-215):

curl "https://silphcoanalytics.xyz/api/v3/cards/base1-4"
All id formats
TypeFormatExamples
English{set_id}-{number}base1-4, sv3-197
Japanese (TCGdex){jp_set_code}-{number}s12a-239, sv4pt5-232
Japanese (TCGCSV)jp-{slug}-{number}jp-pokemon-card-151-001

By name with qLink copied!

Resolve a name or TCGPlayer productId, then price the hit. A bare charizard is ambiguous (400 invalid_query with details.candidates) — use base set charizard or 42382:

curl "https://silphcoanalytics.xyz/api/v3/search?q=base+set+charizard&limit=5"

Print variants and finishesLink copied!

Each print run prices alone — lock it with finish (normal, holo, reverse_holo) on /price:

curl "https://silphcoanalytics.xyz/api/v3/price?tcg_card_id=base1-4&grade_key=PSA%3A10&finish=holo"
Finish vs lot variant

Spellings like holofoil or reverse are normalized on the way in, but send the canonical slug. First-edition runs are not finishes — they are lot variants (1st_edition, unlimited) on your own /api/v3/lists items. Prices never cross languages (en, ja, zh-cn).

Grade keysLink copied!

grade_key is colon-form and required on /price (PSA:10 for slabs); omitted means raw near mint.

Read the responseLink copied!

The price object and its statusesLink copied!

Speak value_usd when status is ok or thin, with method, n_sales, and cohort.resolved_by. An empty window is value_usd: null, never a fallback — and a one-sale thin window answers value_usd: null with the sale exposed as last_sale (surface it labelled Last sale, never as a market price).

All statuses and estimators

status: ok, thin, stale, suspect, none. method (median_3 default, last, median_7d, median_30d) and outliers (exclude default, include) pick the estimator; anything else is 400 invalid_query.

The envelopeLink copied!

Every v3 response uses silphco-envelope.v1: the payload lives in data, and contract names its schema version.

PaginationLink copied!

Lists accept offset and limit (max 200). Per-card sales page with an opaque next_cursor (playground returns at most 50 rows).

ErrorsLink copied!

Errors use contract: "error.v1" with error.code and error.message. Removed routes answer 410 Gone with error.code: "removed" and error.details.replacement pointing at the supported path. 404 is reserved for paths that were never part of the public API — use 410 to distinguish a retired route from one that never existed.

Caching and quota headersLink copied!

Responses can be served from the edge cache; x-cache-status says which ( MISS, HIT, BYPASS). A HIT replays the stored response, headers included, so x-quota-remaining and x-request-id repeat for identical URLs: the remaining-units counter moves on a MISS and stays put on a HIT. Do not read a flat counter across identical URLs as a broken meter.

X-Quota-Limit and X-Quota-Remaining report the plan limit and what is left; X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset report the request-rate bucket. Read account totals from GET /keys/usage (REST) or get_usage (MCP). Full rules are in the API contract notes.

More dataLink copied!

Sales tapeLink copied!

Individual recorded sale rows — research context, never a price (do not derive one from it); source=observed keeps grader-true sale days:

curl "https://silphcoanalytics.xyz/api/v3/sales?ids=base1-4&source=observed&since=2026-08-01&until=2026-08-31"

ListingsLink copied!

Live asks by marketplace:

curl "https://silphcoanalytics.xyz/api/v3/listings?ids=base1-4&marketplace=ebay"

Search recipesLink copied!

Price by name or TCGPlayer productId, then pin the tcg_card_id. For bulk history use POST /prices with {ids:[...]} (cap 1000). Omitting since/until returns the last 90 days; since=all returns full history. Series run newest first with slim rows; fields=full keeps every stored key:

curl "https://silphcoanalytics.xyz/api/v3/price?q=base+set+charizard&grade_key=PSA%3A10"

Next: Agents and reference →