ShinyHits

Developers

Build on ShinyHits

Prices for every English Pokémon card in the US, Europe and the Netherlands, each with the day it was checked, and your own collection, wherever you work: in an AI assistant, a spreadsheet, a script or your browser.

Your API token

Prices are public. Your collection, wishlist and targets need a personal token: make one in Settings → API tokens once you're signed in. Send it as Authorization: Bearer omni_…. It can read, never change; delete it there to cut off whatever uses it.

Your collection in an AI assistant (MCP)

ShinyHits runs a remote Model Context Protocol server. Connect it and ask things like “What's my collection worth in Europe, and which cards moved most this week?”, “Is anything on my wishlist under my target?” or “Where is Umbreon VMAX 215/203 cheapest right now?”

Server URL
https://www.shinyhits.com/mcp
Transport
Streamable HTTP, JSON answers
Auth
Authorization: Bearer omni_…
Protocol
2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26
Limit
60 requests a minute per token

Tools (all read-only)

  • search_cards Find English Pokémon cards by what a person would type: a name ('umbreon vmax'), a name and number ('charizard ex 199' or 'charizard ex 199/165'), a name with its set ('Umbreon VMAX (Evolving Skies)') or a card id. Returns the best matches, most valuable first, with their prices in the three markets and whether you own or want each.
  • get_card_prices One card's prices in the US, Europe and the Netherlands with the date each was checked, its 1/7/30-day changes, the last 30 days of daily prices, and your copies, wishlist target and alerts for it. Give card_id (from search_cards) or a query like 'charizard ex 199/165'.
  • get_my_collection_summary Your collection's value in each market, what you paid, profit/loss, how many cards, your most valuable cards, the sets worth most and this week's biggest movers. Values are condition-adjusted the way ShinyHits values them everywhere.
  • get_my_wishlist Your wishlist: each card's target price, where it's cheapest now (US, Europe or the Netherlands, compared in euros), whether it's at or under your target, and its priority.
  • find_deals Deals from ShinyHits' nightly cross-market check: cards clearly cheaper in one market than another (scope 'market'), or your wishlist cards at or under your target (scope 'wishlist'). Market deals carry a confidence level; a gap can close by the time you buy.

Claude Code

claude mcp add --transport http shinyhits https://www.shinyhits.com/mcp \
  --header "Authorization: Bearer omni_YOUR_TOKEN"

The Claude API (MCP connector)

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: mcp-client-2025-11-20" -H "content-type: application/json" \
  -d '{"model": "claude-opus-5-5", "max_tokens": 1024,
       "messages": [{"role": "user", "content": "What is my Pokémon collection worth?"}],
       "mcp_servers": [{"type": "url", "url": "https://www.shinyhits.com/mcp", "name": "shinyhits",
                        "authorization_token": "omni_YOUR_TOKEN"}],
       "tools": [{"type": "mcp_toolset", "mcp_server_name": "shinyhits"}]}'

Claude for Teams and Enterprise

An organisation admin adds a custom connector with the server URL above and the request header Authorization: Bearer omni_… (Claude's request-header authentication, in beta). The token is then shared by the organisation, so use one made for that purpose.

Personal Claude.ai accounts and ChatGPT connect remote servers with an OAuth sign-in, which ShinyHits doesn't offer yet, so the connector can't be added there today. Claude Code, the Claude API and any MCP client that can send a header work now.

Try it with curl

curl https://www.shinyhits.com/mcp \
  -H "Authorization: Bearer omni_YOUR_TOKEN" -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/call",
       "params": {"name": "search_cards", "arguments": {"query": "umbreon vmax 215"}}}'

Public API

JSON over HTTPS at https://www.shinyhits.com/api/v1. Price answers can be cached for ten minutes (they carry an ETag; prices change once a day). Every price names its market, currency and the day it was checked: US is TCGplayer's market price (USD), EU Cardmarket's trend (EUR), NL the cheapest English Near Mint listing from a Dutch, Belgian or German seller (EUR), with trusted: false when that one listing is far from the Europe trend. How our prices work.

EndpointTokenWhat it gives
GET /lookup?name=&set=&number=—One card from its name, set and number (or title= a listing title, code= a set code like OBF, cm_id= a Cardmarket product id), with prices; candidates when several fit
GET /prices?ids=a,b—Prices of up to 100 cards
GET /card/<id>/prices.csv—One card's prices as CSV (Sheets)
GET /prices.csv?ids=a,b—Up to 100 cards as CSV, one row each
GET /search?q=—Cards by name
GET /card/<id>—A card and every price we hold for it
GET /sets—Every set
GET /meyesYour account
GET /me/cards?ids=a,byesWhether you own or want each card, your copies, target and alerts
GET /me/collectionyesYour collection's lots

With a token: 120 requests a minute per token (see the X-RateLimit-* headers; 429 with Retry-After past it). English cards only during the beta.

Examples

curl "https://www.shinyhits.com/api/v1/lookup?name=Charizard%20ex&number=199/165"
curl "https://www.shinyhits.com/api/v1/prices?ids=sv03.5-199,swsh7-215"
curl -H "Authorization: Bearer omni_YOUR_TOKEN" "https://www.shinyhits.com/api/v1/me/cards?ids=sv03.5-199"

Prices in Google Sheets

Sheets' IMPORTDATA reads our CSV straight into cells, no add-on needed. A card's id is at the end of its ShinyHits page address (/card/sv03.5-199).

A card's prices, with a header row:

=IMPORTDATA("https://www.shinyhits.com/api/v1/card/sv03.5-199/prices.csv")

Just its Europe price in one cell (US, EU or NL):

=IMPORTDATA("https://www.shinyhits.com/api/v1/card/sv03.5-199/prices.csv?only=EU")

A whole list, one row per card (ids in cells A2:A50):

=IMPORTDATA("https://www.shinyhits.com/api/v1/prices.csv?ids="&TEXTJOIN(",",TRUE,A2:A50)&"&header=0")

Columns: card_id, name, number, set, us_usd, us_date, eu_eur, eu_date, nl_eur, nl_date, nl_trusted, url. Sheets refreshes IMPORTDATA about once an hour.