{"openapi":"3.0.3","info":{"title":"Renaiss OS Index — Public API","version":"1.0.0","description":"JSON over the Renaiss OS Index data. Every **data read** is a `GET`; the\nfour write/upload endpoints are `POST`s — the public forms\n`/v1/partners/apply` and `/v1/report` (JSON bodies), and the photo searches\n`/v1/search/by-image` and `/v1/graded/by-image` (`multipart/form-data`).\nResponses carry permissive CORS, so you can call any of them straight from\nthe browser via **Try it out** below.\n\n### Rate limits\n\n| Tier | Limit |\n| --- | --- |\n| Anonymous (no key) | **10 requests / day** per IP |\n| API key (partner) | **10,000 requests / day** per key |\n| The Renaiss index website | unlimited (exempt) |\n\nEvery response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and\n`X-RateLimit-Reset` (unix seconds). Going over returns `429` with a\n`Retry-After` header.\n\n### Authentication (optional)\n\nThe API is public — no key is needed to try it. To lift the anonymous daily\nlimit, send your key as two headers: `X-Api-Key` (the `rk_…` id) and\n`X-Api-Secret` (the `rsk_…` secret). Keys are self-serve: sign in with\nRenaiss on the index site and, once your email or wallet is whitelisted,\ncreate up to 3 keys under **Settings → API access**.\n\n**Finding card slugs:** start at `/v1/search?q=...`. Each result includes an\n`href` of the form `/card/{game}/{set}/{card}` — feed those three segments\ninto the `/v1/cards/{game}/{set}/{card}` endpoints."},"servers":[{"url":"/","description":"This host"}],"security":[{},{"ApiKeyId":[],"ApiKeySecret":[]}],"tags":[{"name":"Indices","description":"Game-level index tiles and drill-downs."},{"name":"Cards","description":"Card detail, trades, price series, and featured movers."},{"name":"Sets","description":"Per-set card listings."},{"name":"Trades","description":"Cross-card live trade feed."},{"name":"Search","description":"Card lookup."},{"name":"Graded","description":"Graded-cert (PSA/CGC/BGS) lookup with on-demand valuation."},{"name":"Forms","description":"Public intake: partner applications and data-issue reports."},{"name":"System","description":"Health and service metadata."}],"paths":{"/v1/partners/apply":{"post":{"tags":["Forms"],"summary":"Apply to become a partner","description":"Submit a shop intake application. Rate-limited per IP. Persists a partner_application row.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerApplicationInput"}}}},"responses":{"201":{"description":"Application received.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitResponse"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited — too many submissions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/report":{"post":{"tags":["Forms"],"summary":"Report a data issue","description":"Flag a price/trade that looks wrong. Rate-limited per IP. Persists a data_issue_report row.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataIssueReportInput"}}}},"responses":{"201":{"description":"Report received.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitResponse"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited — too many submissions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/health":{"get":{"tags":["System"],"summary":"Service health (root)","description":"Root-level liveness probe for load balancers / uptime checks. Never cached.","responses":{"200":{"description":"Service is up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/v1/health":{"get":{"tags":["System"],"summary":"Service health","description":"Liveness probe. Never cached.","responses":{"200":{"description":"Service is up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/v1/indices":{"get":{"tags":["Indices"],"summary":"Index tiles","description":"Pokémon & One Piece index tiles: value, deltas, sparkline, and top movers.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndicesResponse"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/indices/{game}":{"get":{"tags":["Indices"],"summary":"Index drill-down","description":"Full index detail for one game, including its ranked constituents.","parameters":[{"name":"game","in":"path","required":true,"description":"Game slug.","schema":{"type":"string","enum":["pokemon","one-piece","sports"]},"example":"pokemon"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexDetail"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/indices/{game}/series":{"get":{"tags":["Indices"],"summary":"Index value series","description":"The game index's daily value line over a display window (base 10000), plus that day's game-wide completed-sale turnover and count for the chart's volume pane. Each point also carries the rotation trace (`rebalanced`, `membersAdded`, `membersRemoved`) that drives the chart's rebalance markers — drill into one with `/v1/indices/{game}/rebalance/{date}`.","parameters":[{"name":"game","in":"path","required":true,"description":"Game slug.","schema":{"type":"string","enum":["pokemon","one-piece","sports"]},"example":"pokemon"},{"name":"window","in":"query","required":false,"description":"Window in days (1095 = 3y, 36500 = all-time / full history). Other values fall back to 30.","schema":{"type":"integer","enum":[30,90,365,1095,36500],"default":30}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexSeriesResponse"}}}},"401":{"description":"Both `X-Api-Key` and `X-Api-Secret` were sent but the pair did not verify. Omit them entirely to call anonymously.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Over the daily budget — the anonymous per-IP allowance, or the key’s own per-key budget. Carries `Retry-After` and `X-RateLimit-*`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/indices/{game}/rebalance/{date}":{"get":{"tags":["Indices"],"summary":"Index rebalance drill-down","description":"The basket behind one rotation point on the index chart: the full membership persisted for that snapshot day (by rank), plus which cards rotated in and out versus the previous snapshot. Read straight from the traceability tables, so any historical day answers without a recompute. Rotated-out members carry `rank: null` and `weight: null` — their `prevRank` is the \"was #N\" they left from. Find eligible days via the `rebalanced` flag on `/v1/indices/{game}/series` points.","parameters":[{"name":"game","in":"path","required":true,"description":"Game slug.","schema":{"type":"string","enum":["pokemon","one-piece","sports"]},"example":"pokemon"},{"name":"date","in":"path","required":true,"description":"Snapshot day as `YYYY-MM-DD` (UTC). Any other shape 404s before the database is touched.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"example":"2026-07-01"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexRebalanceResponse"}}}},"401":{"description":"Both `X-Api-Key` and `X-Api-Secret` were sent but the pair did not verify. Omit them entirely to call anonymously.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Unknown game, a `date` that is not `YYYY-MM-DD`, or no snapshot on that day.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Over the daily budget — the anonymous per-IP allowance, or the key’s own per-key budget. Carries `Retry-After` and `X-RateLimit-*`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/featured":{"get":{"tags":["Cards"],"summary":"Featured movers","description":"Top-mover card tiles across the indexed games — cards with the largest 7-day price move (average completed-sale price vs the prior 30 days). Always fills to `limit` when the catalog has enough priced cards: gate-qualified movers rank first, then the list tops up with the most-traded priced cards — so a quiet market still returns a full grid.","parameters":[{"name":"limit","in":"query","required":false,"description":"Number of cards to return (max 48 — the ranked pool size).","schema":{"type":"integer","minimum":1,"maximum":48,"default":48}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeaturedResponse"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/summaries":{"get":{"tags":["Cards"],"summary":"Batch card summaries","description":"Compact tiles for a list of catalog card ids in ONE round-trip — the watchlist / portfolio read, replacing N full card-detail fetches. Ids that are not well-formed UUIDs, and ids with no catalog match, are dropped silently: the response is a filtered list, never an error, so one bad id cannot fail the batch.\n\n**Caching:** like every other read here, the response ships `Cache-Control: public, s-maxage=300, stale-while-revalidate=1200`, so a shared cache may serve a given `?ids=…&grades=…` URL for up to 5 minutes (and a stale copy for 20 more while it refreshes). The cache key is the full query string, so one caller’s watchlist is never served to another — but prices in it can be up to 5 minutes old. Polling faster than that returns the cached body; bypass it with a cache-busting query parameter if you need every tick.","parameters":[{"name":"ids","in":"query","required":false,"description":"Comma-separated catalog card ids (`items.id`). Anything past the first 300 is ignored. Omitted or empty returns an empty list.","schema":{"type":"string"},"example":"01262ac6-2b79-468f-922f-f6c38b18f089,4f2b0f9e-6f8f-4a9b-9d0d-2c7a1b3e5d41"},{"name":"grades","in":"query","required":false,"description":"Comma-separated grade labels, POSITIONAL against `ids` (the Nth grade applies to the Nth id). Leave an entry empty to use that card's representative grade.","schema":{"type":"string"},"example":"PSA 10,,BGS 9.5"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeaturedResponse"}}}},"401":{"description":"Both `X-Api-Key` and `X-Api-Secret` were sent but the pair did not verify. Omit them entirely to call anonymously.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Over the daily budget — the anonymous per-IP allowance, or the key’s own per-key budget. Carries `Retry-After` and `X-RateLimit-*`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/{game}/{set}/{card}":{"get":{"tags":["Cards"],"summary":"Card detail","description":"Price, confidence, source breakdown, other grades, and similar cards for one card.","parameters":[{"name":"game","in":"path","required":true,"description":"Game slug.","schema":{"type":"string","enum":["pokemon","one-piece","sports"]},"example":"pokemon"},{"name":"set","in":"path","required":true,"description":"Set slug — the 2nd path segment of a card `href` returned by `/v1/search` (`/card/{game}/{set}/{card}`).","schema":{"type":"string"},"example":"shiny-star-v"},{"name":"card","in":"path","required":true,"description":"Card slug — the final path segment of a card `href` (`{number}-{name}-{company}-{grade}`).","schema":{"type":"string"},"example":"307-charizard-psa-10"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardDetail"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/{game}/{set}/{card}/similar":{"get":{"tags":["Cards"],"summary":"More from this set","description":"Other cards in this card's set (the card page's \"More from this set\" grid), highest-confidence priced first. Split from the card detail so the page can load it lazily.","parameters":[{"name":"game","in":"path","required":true,"description":"Game slug.","schema":{"type":"string","enum":["pokemon","one-piece","sports"]},"example":"pokemon"},{"name":"set","in":"path","required":true,"description":"Set slug — the 2nd path segment of a card `href` returned by `/v1/search` (`/card/{game}/{set}/{card}`).","schema":{"type":"string"},"example":"shiny-star-v"},{"name":"card","in":"path","required":true,"description":"Card slug — the final path segment of a card `href` (`{number}-{name}-{company}-{grade}`).","schema":{"type":"string"},"example":"307-charizard-psa-10"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardSimilarResponse"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/{game}/{set}/{card}/trades":{"get":{"tags":["Cards"],"summary":"Card trade history","description":"Listings and completed sales for a card, with optional filters.","parameters":[{"name":"game","in":"path","required":true,"description":"Game slug.","schema":{"type":"string","enum":["pokemon","one-piece","sports"]},"example":"pokemon"},{"name":"set","in":"path","required":true,"description":"Set slug — the 2nd path segment of a card `href` returned by `/v1/search` (`/card/{game}/{set}/{card}`).","schema":{"type":"string"},"example":"shiny-star-v"},{"name":"card","in":"path","required":true,"description":"Card slug — the final path segment of a card `href` (`{number}-{name}-{company}-{grade}`).","schema":{"type":"string"},"example":"307-charizard-psa-10"},{"name":"source","in":"query","required":false,"description":"Restrict to a single data source.","schema":{"type":"string","enum":["snkrdunk","alt_xyz","mercari","yahoo","ebay_jp","cardladder","psa","renaiss","renaissos_index","collector_crypt","courtyard","renaiss_market","hk_card_shop","yuyu_tei"]}},{"name":"window","in":"query","required":false,"description":"Trailing window in days.","schema":{"type":"integer","minimum":1}},{"name":"scope","in":"query","required":false,"description":"`grade` (default) limits to the card's own grade; `all` returns every grade.","schema":{"type":"string","enum":["grade","all"],"default":"grade"}},{"name":"limit","in":"query","required":false,"description":"Max rows to return (max 200).","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradesResponse"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/{game}/{set}/{card}/series":{"get":{"tags":["Cards"],"summary":"Card price series","description":"Daily-average price points (split into completed sales vs active listings) over a window.","parameters":[{"name":"game","in":"path","required":true,"description":"Game slug.","schema":{"type":"string","enum":["pokemon","one-piece","sports"]},"example":"pokemon"},{"name":"set","in":"path","required":true,"description":"Set slug — the 2nd path segment of a card `href` returned by `/v1/search` (`/card/{game}/{set}/{card}`).","schema":{"type":"string"},"example":"shiny-star-v"},{"name":"card","in":"path","required":true,"description":"Card slug — the final path segment of a card `href` (`{number}-{name}-{company}-{grade}`).","schema":{"type":"string"},"example":"307-charizard-psa-10"},{"name":"window","in":"query","required":false,"description":"Window in days. Other values fall back to 30.","schema":{"type":"integer","enum":[7,30,90,365],"default":30}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesResponse"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/{game}/{set}/{card}/fmv-series":{"get":{"tags":["Cards"],"summary":"Card daily FMV series","description":"The card's daily fair-market value — the reference-price methodology (mean of completed sales over a trailing window) evaluated once per day (the chart line) — plus, for each day, that day's sales broken down by source (count + that day's mean), for the chart's hover. Powers the card price chart.","parameters":[{"name":"game","in":"path","required":true,"description":"Game slug.","schema":{"type":"string","enum":["pokemon","one-piece","sports"]},"example":"pokemon"},{"name":"set","in":"path","required":true,"description":"Set slug — the 2nd path segment of a card `href` returned by `/v1/search` (`/card/{game}/{set}/{card}`).","schema":{"type":"string"},"example":"shiny-star-v"},{"name":"card","in":"path","required":true,"description":"Card slug — the final path segment of a card `href` (`{number}-{name}-{company}-{grade}`).","schema":{"type":"string"},"example":"307-charizard-psa-10"},{"name":"window","in":"query","required":false,"description":"Display window in days. Other values fall back to 30.","schema":{"type":"integer","enum":[7,30,90,365],"default":30}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FmvSeriesResponse"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/trades/recent":{"get":{"tags":["Trades"],"summary":"Recent trades","description":"Cross-card live trade feed, newest first.","parameters":[{"name":"limit","in":"query","required":false,"description":"Number of trades to return (max 50).","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecentTradesResponse"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/search":{"get":{"tags":["Search"],"summary":"Card search","description":"Free-text card search. Queries shorter than 2 characters return no results —\nunless `character` is set, which can carry the search on its own.\n\nPass `character` to filter to cards showing one roster character (\"every\nCharizard\"). Cards whose headline (primary) character matches rank first, then\nthe usual text-relevance order. An unknown character — or a game whose roster\nis not seeded yet — degrades to the plain text search of `q`, never an error\nand never an artificial zero-result page.","parameters":[{"name":"q","in":"query","required":false,"description":"Search query (min 2 characters unless `character` is set).","schema":{"type":"string","maxLength":80},"example":"charizard"},{"name":"limit","in":"query","required":false,"description":"Number of results to return (max 30).","schema":{"type":"integer","minimum":1,"maximum":30,"default":12}},{"name":"character","in":"query","required":false,"description":"Roster character to filter by — canonical slug or alias (e.g. `monkey-d-luffy`, `kaido`). Free text is tolerated and slugified server-side (\"Monkey D. Luffy\" works). Unresolvable values degrade to plain text search of `q`.","schema":{"type":"string","maxLength":120},"example":"monkey-d-luffy"},{"name":"game","in":"query","required":false,"description":"Scope the `character` roster lookup to one game. Has no effect without `character`. Values outside the game list are a `400`.","schema":{"type":"string","enum":["pokemon","one-piece","sports","digimon","riftbound","mtg","yugioh","lorcana","gundam","others"]},"example":"one-piece"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"400":{"description":"Unknown `game`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/search/by-image":{"post":{"tags":["Search"],"summary":"Card search by photo","description":"The photo sibling of the text `/v1/search`: upload a card image and get back the\ncatalog ids of the most visually similar cards, best match first. Feed an id into\n`/v1/cards/by-id/{id}` for the full card payload.\n\nRead `confidence` before you trust `ids` — a `low` or `none` band means the match\nis weak, so prompt the user to confirm instead of auto-navigating.\n\nPhotograph a graded SLAB and the label OCR may also read its certification\nnumber, returned as the OPTIONAL `cert` field. The field is **omitted entirely**\n(not `null`) whenever no cert was read — which is every non-slab photo — so treat\nits absence as normal and only offer `/v1/graded/{cert}` when it is present.\n\nEvery call is a genuine GPU embed (there is no cache key for an arbitrary photo),\nso it is rate-limited even for the index website; send an API key\n(`X-Api-Key` + `X-Api-Secret`) for a higher ceiling.","parameters":[{"name":"limit","in":"query","required":false,"description":"Number of matches to return. **Clamped, never rejected:** a value below 1 becomes 1, above 30 becomes 30, and anything unparseable (`abc`, empty) falls back to 12 — an out-of-range `limit` is never a `400`.","schema":{"type":"integer","minimum":1,"maximum":30,"default":12}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"The card photo, ≤ 15 MB. Accepted when EITHER its content-type starts with `image/` (any image subtype, including ones the pipeline may not decode) OR its filename ends in `.jpg` / `.jpeg` / `.png` / `.webp` / `.avif` / `.gif` / `.bmp` / `.tif` / `.tiff` / `.heic` / `.heif` — the extension fallback is what lets a browser that sends no content-type through. HEIC/HEIF is transcoded and EXIF orientation corrected server-side. An accepted content-type the decoder cannot actually read passes this check and fails later as a `502`, not a `400`."}}}}}},"responses":{"200":{"description":"Ranked matches — inspect `confidence`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchByImageResponse"}}}},"400":{"description":"Bad upload — not multipart/form-data, missing \"file\" part, not an image, or larger than 15 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Both `X-Api-Key` and `X-Api-Secret` were sent but the pair did not verify. Omit them entirely to call anonymously.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Over the daily budget — the anonymous per-IP allowance, or the key’s own per-key budget. Carries `Retry-After` and `X-RateLimit-*`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"The image-search backend failed or was unreachable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/{game}/{set}/{card}/overview":{"get":{"tags":["Cards"],"summary":"Card overview (all grades)","description":"Grade-agnostic view of a card: its identity plus every grading company / grade we track for it. Here `card` is the grade-less slug (`{number}-{name}`) — drop the `-{company}-{grade}` suffix from a card `href`.","parameters":[{"name":"game","in":"path","required":true,"description":"Game slug.","schema":{"type":"string","enum":["pokemon","one-piece","sports"]},"example":"pokemon"},{"name":"set","in":"path","required":true,"description":"Set slug — the 2nd path segment of a card `href` returned by `/v1/search` (`/card/{game}/{set}/{card}`).","schema":{"type":"string"},"example":"shiny-star-v"},{"name":"card","in":"path","required":true,"description":"Grade-less card slug (`{number}-{name}`) — a card `href`'s final segment with the `-{company}-{grade}` suffix removed.","schema":{"type":"string"},"example":"307-charizard"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardOverview"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/by-id/{id}":{"get":{"tags":["Cards"],"summary":"Card detail by id","description":"Same as `/v1/cards/{game}/{set}/{card}` but keyed by the catalog `items.id` — resolves the id to its slug and a representative grade (PSA 10 when available).","parameters":[{"name":"id","in":"path","required":true,"description":"Catalog card id (the `items.id` UUID). Resolves to the card with a representative grade (PSA 10 when available, else the top-priced grade).","schema":{"type":"string","format":"uuid"},"example":"01262ac6-2b79-468f-922f-f6c38b18f089"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardDetail"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/by-id/{id}/overview":{"get":{"tags":["Cards"],"summary":"Card overview by id (all grades)","description":"Grade-agnostic overview of the card with this `items.id`.","parameters":[{"name":"id","in":"path","required":true,"description":"Catalog card id (the `items.id` UUID). Resolves to the card with a representative grade (PSA 10 when available, else the top-priced grade).","schema":{"type":"string","format":"uuid"},"example":"01262ac6-2b79-468f-922f-f6c38b18f089"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardOverview"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/by-id/{id}/trades":{"get":{"tags":["Cards"],"summary":"Card trade history by id","description":"Listings and completed sales for the card with this `items.id`.","parameters":[{"name":"id","in":"path","required":true,"description":"Catalog card id (the `items.id` UUID). Resolves to the card with a representative grade (PSA 10 when available, else the top-priced grade).","schema":{"type":"string","format":"uuid"},"example":"01262ac6-2b79-468f-922f-f6c38b18f089"},{"name":"source","in":"query","required":false,"description":"Restrict to a single data source.","schema":{"type":"string","enum":["snkrdunk","alt_xyz","mercari","yahoo","ebay_jp","cardladder","psa","renaiss","renaissos_index","collector_crypt","courtyard","renaiss_market","hk_card_shop","yuyu_tei"]}},{"name":"window","in":"query","required":false,"description":"Trailing window in days.","schema":{"type":"integer","minimum":1}},{"name":"scope","in":"query","required":false,"description":"`grade` (default) limits to the card's own grade; `all` returns every grade.","schema":{"type":"string","enum":["grade","all"],"default":"grade"}},{"name":"limit","in":"query","required":false,"description":"Max rows to return (max 200).","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradesResponse"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/by-id/{id}/series":{"get":{"tags":["Cards"],"summary":"Card price series by id","description":"Daily-average price points for the card with this `items.id`.","parameters":[{"name":"id","in":"path","required":true,"description":"Catalog card id (the `items.id` UUID). Resolves to the card with a representative grade (PSA 10 when available, else the top-priced grade).","schema":{"type":"string","format":"uuid"},"example":"01262ac6-2b79-468f-922f-f6c38b18f089"},{"name":"window","in":"query","required":false,"description":"Window in days (1095 = 3y, 36500 = all-time). Other values fall back to 30.","schema":{"type":"integer","enum":[30,90,365,1095,36500],"default":30}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesResponse"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/by-id/{id}/fmv-series":{"get":{"tags":["Cards"],"summary":"Card daily FMV series by id","description":"The daily fair-market-value series for the card with this `items.id`.","parameters":[{"name":"id","in":"path","required":true,"description":"Catalog card id (the `items.id` UUID). Resolves to the card with a representative grade (PSA 10 when available, else the top-priced grade).","schema":{"type":"string","format":"uuid"},"example":"01262ac6-2b79-468f-922f-f6c38b18f089"},{"name":"window","in":"query","required":false,"description":"Window in days (1095 = 3y, 36500 = all-time). Other values fall back to 30.","schema":{"type":"integer","enum":[30,90,365,1095,36500],"default":30}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FmvSeriesResponse"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/by-renaiss-id/{rid}":{"get":{"tags":["Cards"],"summary":"Card detail by Renaiss item id","description":"Same as `/v1/cards/by-id/{id}` but keyed by the upstream `items.renaiss_item_id` — resolves to the card with a representative grade (PSA 10 when available).","parameters":[{"name":"rid","in":"path","required":true,"description":"Upstream Renaiss item id (`items.renaiss_item_id`). Resolves to the same card payload as the catalog-id routes, with a representative grade (PSA 10 when available).","schema":{"type":"string"},"example":"12670e6b-f07a-4a56-bc37-4f5e42edc6a8"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardDetail"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/by-renaiss-id/{rid}/overview":{"get":{"tags":["Cards"],"summary":"Card overview by Renaiss item id (all grades)","description":"Grade-agnostic overview of the card with this `items.renaiss_item_id`.","parameters":[{"name":"rid","in":"path","required":true,"description":"Upstream Renaiss item id (`items.renaiss_item_id`). Resolves to the same card payload as the catalog-id routes, with a representative grade (PSA 10 when available).","schema":{"type":"string"},"example":"12670e6b-f07a-4a56-bc37-4f5e42edc6a8"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardOverview"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/by-renaiss-id/{rid}/trades":{"get":{"tags":["Cards"],"summary":"Card trade history by Renaiss item id","description":"Listings and completed sales for the card with this `items.renaiss_item_id`.","parameters":[{"name":"rid","in":"path","required":true,"description":"Upstream Renaiss item id (`items.renaiss_item_id`). Resolves to the same card payload as the catalog-id routes, with a representative grade (PSA 10 when available).","schema":{"type":"string"},"example":"12670e6b-f07a-4a56-bc37-4f5e42edc6a8"},{"name":"source","in":"query","required":false,"description":"Restrict to a single data source.","schema":{"type":"string","enum":["snkrdunk","alt_xyz","mercari","yahoo","ebay_jp","cardladder","psa","renaiss","renaissos_index","collector_crypt","courtyard","renaiss_market","hk_card_shop","yuyu_tei"]}},{"name":"window","in":"query","required":false,"description":"Trailing window in days.","schema":{"type":"integer","minimum":1}},{"name":"scope","in":"query","required":false,"description":"`grade` (default) limits to the card's own grade; `all` returns every grade.","schema":{"type":"string","enum":["grade","all"],"default":"grade"}},{"name":"limit","in":"query","required":false,"description":"Max rows to return (max 200).","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradesResponse"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/by-renaiss-id/{rid}/series":{"get":{"tags":["Cards"],"summary":"Card price series by Renaiss item id","description":"Daily-average price points for the card with this `items.renaiss_item_id`.","parameters":[{"name":"rid","in":"path","required":true,"description":"Upstream Renaiss item id (`items.renaiss_item_id`). Resolves to the same card payload as the catalog-id routes, with a representative grade (PSA 10 when available).","schema":{"type":"string"},"example":"12670e6b-f07a-4a56-bc37-4f5e42edc6a8"},{"name":"window","in":"query","required":false,"description":"Window in days (1095 = 3y, 36500 = all-time). Other values fall back to 30.","schema":{"type":"integer","enum":[30,90,365,1095,36500],"default":30}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesResponse"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/cards/by-renaiss-id/{rid}/fmv-series":{"get":{"tags":["Cards"],"summary":"Card daily FMV series by Renaiss item id","description":"The daily fair-market-value series for the card with this `items.renaiss_item_id`.","parameters":[{"name":"rid","in":"path","required":true,"description":"Upstream Renaiss item id (`items.renaiss_item_id`). Resolves to the same card payload as the catalog-id routes, with a representative grade (PSA 10 when available).","schema":{"type":"string"},"example":"12670e6b-f07a-4a56-bc37-4f5e42edc6a8"},{"name":"window","in":"query","required":false,"description":"Window in days (1095 = 3y, 36500 = all-time). Other values fall back to 30.","schema":{"type":"integer","enum":[30,90,365,1095,36500],"default":30}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FmvSeriesResponse"}}}},"404":{"description":"Unknown game, or card/index not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/items/by-renaiss-id/{rid}":{"get":{"tags":["Cards"],"summary":"Resolve a Renaiss item id to its card page","description":"Resolve an upstream Renaiss item id (`items.renaiss_item_id`) to the card it\nrefers to. The returned `href` is a **site-relative URL for the Renaiss index\nwebsite** — `/card/{game}/{set}/{card}` — NOT an API path: link a user straight\nto it, or split its three segments into the `/v1/cards/{game}/{set}/{card}`\nendpoints to fetch the data. It backs the `/item/{renaissId}` deep-link.\n\nWant the card payload rather than a link? Use `/v1/cards/by-renaiss-id/{rid}`,\nwhich takes the same id and returns the full card detail directly.","parameters":[{"name":"rid","in":"path","required":true,"description":"Upstream Renaiss item id (`items.renaiss_item_id`) to resolve. URL-encode it if it contains reserved characters.","schema":{"type":"string"},"example":"12670e6b-f07a-4a56-bc37-4f5e42edc6a8"}],"responses":{"200":{"description":"The resolved website path for this item.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemRefResponse"}}}},"401":{"description":"Both `X-Api-Key` and `X-Api-Secret` were sent but the pair did not verify. Omit them entirely to call anonymously.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No catalog item with this Renaiss item id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Over the daily budget — the anonymous per-IP allowance, or the key’s own per-key budget. Carries `Retry-After` and `X-RateLimit-*`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/sets/{game}/{set}":{"get":{"tags":["Sets"],"summary":"Set listing","description":"Every card we track in a set, keyed by the set slug (the 2nd path segment of a card `href`).","parameters":[{"name":"game","in":"path","required":true,"description":"Game slug.","schema":{"type":"string","enum":["pokemon","one-piece","sports"]},"example":"pokemon"},{"name":"set","in":"path","required":true,"description":"Set slug — the 2nd path segment of a card `href` returned by `/v1/search` (`/card/{game}/{set}/{card}`).","schema":{"type":"string"},"example":"shiny-star-v"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetResponse"}}}},"404":{"description":"Unknown game, or set not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/graded/{cert}":{"get":{"tags":["Graded"],"summary":"Graded cert lookup","description":"Look up a graded card by certification number (PSA / CGC / BGS). Cached-first: returns the card plus the FMV for the cert's grade. On a cache miss it runs a live on-demand valuation — available to all callers (a cache hit is free; only a genuine miss runs the pipeline). The per-IP rate limit bounds how often any one caller triggers a miss; send an API key (`X-Api-Key` + `X-Api-Secret`) for a higher ceiling. Always returns 200 for a parseable cert — inspect `found`.","parameters":[{"name":"cert","in":"path","required":true,"description":"Certification number, optionally prefixed by the grader. E.g. `PSA149595098`, `149595098`, `CGC1234567`.","schema":{"type":"string"},"example":"PSA149595098"}],"responses":{"200":{"description":"Lookup result — inspect `found`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GradedLookup"}}}},"400":{"description":"Could not parse a cert number from the input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/graded/{cert}/stream":{"get":{"tags":["Graded"],"summary":"Graded cert lookup — live progress (SSE)","description":"Server-Sent Events variant of `/v1/graded/{cert}`. Streams the on-demand\nvaluation as it runs, so a client can show live progress instead of blocking\non the full pipeline. Consume with `EventSource`.\n\nThe `text/event-stream` body carries named events:\n- `event: progress` — a `PipelineProgress` object as each stage begins\n  (`cert_lookup` → `identify` → `enrich` → `find_item` → `cache_check` →\n  `match` → `crawl` → `fmv` → `done`).\n- `event: result` — the terminal `GradedLookup` (inspect `found`).\n- `event: failed` — `{ error, detail }` on an unparseable cert or internal error.\n\nA cache hit emits a single `result` with no `progress`. A miss runs the live\ncompute for any caller (including anonymous), bounded by the per-IP rate limit;\nsend an API key (`X-Api-Key` + `X-Api-Secret`) for a higher ceiling.","parameters":[{"name":"cert","in":"path","required":true,"description":"Certification number, optionally prefixed by the grader. E.g. `PSA149595098`, `149595098`, `CGC1234567`.","schema":{"type":"string"},"example":"PSA149595098"}],"responses":{"200":{"description":"SSE stream: `progress` events (each a `PipelineProgress`) followed by a terminal `result` (a `GradedLookup`) or `failed`.","content":{"text/event-stream":{"schema":{"type":"string","description":"Raw SSE frames. `progress` data is a PipelineProgress; `result` data is a GradedLookup."}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/graded/by-image":{"post":{"tags":["Graded"],"summary":"Graded valuation by photo (SSE)","description":"Value a graded card from a PHOTO instead of a cert number — upload the slab /\ncard image and the AI reads the card identity and grading label off it, then the\nsame FMV pipeline prices it. Streams progress over SSE exactly like\n`/v1/graded/{cert}/stream`. `EventSource` cannot POST a file, so consume the\nresponse with a fetch stream reader — or use the live tester on the /docs page,\nwhich uploads a photo and renders the event stream for you.\n\nEvery call is a live, paid pipeline run (there is no cache key for an arbitrary\nphoto), so the compute rate limit is enforced BEFORE the stream opens; send an API\nkey (`X-Api-Key` + `X-Api-Secret`) for a higher ceiling.\n\nThe `text/event-stream` body carries named events:\n- `event: progress` — a `PipelineProgress` object as each stage runs.\n- `event: result` — the terminal `GradedLookup` (inspect `found`).\n- `event: failed` — `{ error, detail }` when the image is not a readable card\n  (`image_unreadable`), the upload fails, or on an internal error.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"The card or slab photo (JPEG / PNG / WebP / AVIF / HEIC, ≤ 15 MB)."}}}}}},"responses":{"200":{"description":"SSE stream: `progress` events (each a `PipelineProgress`) followed by a terminal `result` (a `GradedLookup`) or `failed`.","content":{"text/event-stream":{"schema":{"type":"string","description":"Raw SSE frames. `progress` data is a PipelineProgress; `result` data is a GradedLookup."}}}},"400":{"description":"Bad upload — wrong content-type, missing \"file\" part, not an image, or larger than 15 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"ApiError":{"type":"object","properties":{"error":{"type":"string"},"detail":{"type":"string"}},"required":["error"],"additionalProperties":false},"Deltas":{"type":"object","properties":{"d7":{"type":"number","nullable":true},"d30":{"type":"number","nullable":true},"d365":{"type":"number","nullable":true}},"required":["d7","d30","d365"],"additionalProperties":false},"SeriesPoint":{"type":"object","properties":{"t":{"type":"string","format":"date-time"},"usdCents":{"type":"integer","minimum":0},"source":{"type":"string","nullable":true},"bucket":{"type":"string","enum":["public","renaiss","partner"],"nullable":true},"category":{"type":"string","enum":["public","blockchain","renaiss","partner","internal"],"description":"Source category (web3 grouping axis): public = crawled marketplaces, blockchain = third-party on-chain marketplaces, renaiss = Renaiss-owned sources, partner = partner shops, internal = non-marketplace origins. Additive to the legacy `bucket` field.","nullable":true},"n":{"type":"integer","minimum":0},"kind":{"type":"string","enum":["transaction","listing"],"nullable":true},"company":{"type":"string","enum":["PSA","BGS","CGC","SGC","RAW","TAG"],"nullable":true},"grade":{"type":"string","enum":["1 Poor","2 Good","3 Very Good","4 Very Good-Excellent","5 Excellent","6 Excellent-Mint","7 Near Mint","8 NM-MT","8.5 NM-MT+","9 Mint","9.5 Mint","10 Gem Mint","8 NM/Mint","8.5 NM/Mint+","9.5 Mint +","9.5 Gem Mint","10 Pristine","10 Black Label","10 Perfect","A","B","C","D"],"nullable":true},"gradeLabel":{"type":"string"}},"required":["t","usdCents"],"additionalProperties":false},"IndexMover":{"type":"object","properties":{"name":{"type":"string"},"setCode":{"type":"string","nullable":true},"cardNumber":{"type":"string","nullable":true},"grade":{"type":"string"},"href":{"type":"string"},"deltaPct":{"type":"number","nullable":true}},"required":["name","setCode","cardNumber","grade","href","deltaPct"],"additionalProperties":false},"IndexTile":{"type":"object","properties":{"game":{"type":"string","enum":["pokemon","one-piece","sports","digimon","riftbound","mtg","yugioh","lorcana","gundam","others"]},"label":{"type":"string"},"value":{"type":"number"},"base":{"type":"number"},"deltas":{"$ref":"#/components/schemas/Deltas"},"constituentCount":{"type":"integer","minimum":0},"rebalance":{"type":"string"},"sparkline":{"type":"array","items":{"$ref":"#/components/schemas/SeriesPoint"}},"topMovers":{"type":"array","items":{"$ref":"#/components/schemas/IndexMover"}},"updatedAt":{"type":"string","format":"date-time","nullable":true}},"required":["game","label","value","base","deltas","constituentCount","rebalance","sparkline","topMovers","updatedAt"],"additionalProperties":false},"IndicesResponse":{"type":"object","properties":{"indices":{"type":"array","items":{"$ref":"#/components/schemas/IndexTile"}}},"required":["indices"],"additionalProperties":false},"IndexConstituent":{"type":"object","properties":{"rank":{"type":"integer","exclusiveMinimum":true,"minimum":0},"name":{"type":"string"},"setName":{"type":"string","nullable":true},"setCode":{"type":"string","nullable":true},"cardNumber":{"type":"string","nullable":true},"grade":{"type":"string"},"imageUrl":{"type":"string","nullable":true},"imageUrlThumb":{"type":"string","nullable":true},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"deltaPct":{"type":"number","nullable":true},"lastSaleAt":{"type":"string","format":"date-time","nullable":true},"tradeCountWindow":{"type":"integer","minimum":0},"href":{"type":"string"}},"required":["rank","name","setName","setCode","cardNumber","grade","imageUrl","priceUsdCents","deltaPct","lastSaleAt","href"],"additionalProperties":false},"IndexDetail":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/IndexTile/properties/game"},"label":{"$ref":"#/components/schemas/IndexTile/properties/label"},"value":{"$ref":"#/components/schemas/IndexTile/properties/value"},"base":{"$ref":"#/components/schemas/IndexTile/properties/base"},"deltas":{"$ref":"#/components/schemas/Deltas"},"constituentCount":{"$ref":"#/components/schemas/IndexTile/properties/constituentCount"},"rebalance":{"$ref":"#/components/schemas/IndexTile/properties/rebalance"},"sparkline":{"$ref":"#/components/schemas/IndexTile/properties/sparkline"},"topMovers":{"$ref":"#/components/schemas/IndexTile/properties/topMovers"},"updatedAt":{"$ref":"#/components/schemas/IndexTile/properties/updatedAt"},"windowDays":{"type":"integer","exclusiveMinimum":true,"minimum":0},"baseDate":{"type":"string","nullable":true},"constituents":{"type":"array","items":{"$ref":"#/components/schemas/IndexConstituent"}},"sourceBreakdown":{"type":"array","items":{"$ref":"#/components/schemas/SourceBreakdownEntry"}}},"required":["game","label","value","base","deltas","constituentCount","rebalance","sparkline","topMovers","updatedAt","windowDays","baseDate","constituents"],"additionalProperties":false},"IndexSeriesPoint":{"type":"object","properties":{"t":{"type":"string","format":"date-time"},"value":{"type":"number"},"volUsdCents":{"type":"integer","minimum":0,"default":0},"n":{"type":"integer","minimum":0,"default":0},"rebalanced":{"type":"boolean","default":false},"membersAdded":{"type":"integer","minimum":0,"default":0},"membersRemoved":{"type":"integer","minimum":0,"default":0}},"required":["t","value"],"additionalProperties":false},"IndexSeriesResponse":{"type":"object","properties":{"windowDays":{"type":"integer","exclusiveMinimum":true,"minimum":0},"base":{"type":"number"},"points":{"type":"array","items":{"$ref":"#/components/schemas/IndexSeriesPoint"}}},"required":["windowDays","base","points"],"additionalProperties":false},"IndexRebalanceMember":{"type":"object","properties":{"rank":{"type":"integer","exclusiveMinimum":true,"minimum":0,"nullable":true},"prevRank":{"type":"integer","exclusiveMinimum":true,"minimum":0,"nullable":true},"name":{"type":"string"},"setCode":{"type":"string","nullable":true},"cardNumber":{"type":"string","nullable":true},"grade":{"type":"string"},"imageUrlThumb":{"type":"string","nullable":true},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"weight":{"type":"number","nullable":true},"href":{"type":"string"}},"required":["rank","name","setCode","cardNumber","grade","imageUrlThumb","priceUsdCents","weight","href"],"additionalProperties":false},"IndexRebalanceResponse":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/IndexTile/properties/game"},"date":{"type":"string"},"prevDate":{"type":"string","nullable":true},"rebalanced":{"type":"boolean"},"membersIn":{"type":"array","items":{"$ref":"#/components/schemas/IndexRebalanceMember"}},"membersOut":{"type":"array","items":{"$ref":"#/components/schemas/IndexRebalanceMember"}},"members":{"type":"array","items":{"$ref":"#/components/schemas/IndexRebalanceMember"}}},"required":["game","date","prevDate","rebalanced","membersIn","membersOut","members"],"additionalProperties":false},"ItemRefResponse":{"type":"object","properties":{"href":{"type":"string"}},"required":["href"],"additionalProperties":false},"CardSummary":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/IndexTile/properties/game"},"type":{"type":"string","enum":["POKEMON","ONE_PIECE","SPORTS","DIGIMON","RIFTBOUND","MTG","YUGIOH","LORCANA","GUNDAM","OTHERS"]},"name":{"type":"string"},"setName":{"type":"string","nullable":true},"setCode":{"type":"string","nullable":true},"cardNumber":{"type":"string","nullable":true},"variation":{"type":"string","nullable":true},"rarity":{"type":"string","nullable":true},"language":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"imageUrlThumb":{"type":"string","nullable":true},"company":{"$ref":"#/components/schemas/SeriesPoint/properties/company"},"grade":{"$ref":"#/components/schemas/SeriesPoint/properties/grade"},"gradeLabel":{"type":"string"},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"deltaPct":{"type":"number","nullable":true},"confidence":{"type":"string","enum":["prime","high","medium","low"],"nullable":true},"lastSaleAt":{"type":"string","format":"date-time","nullable":true},"spark":{"type":"array","items":{"type":"integer","minimum":0}},"href":{"type":"string"}},"required":["game","type","name","setName","setCode","cardNumber","variation","language","imageUrl","company","grade","gradeLabel","priceUsdCents","deltaPct","confidence","lastSaleAt","href"],"additionalProperties":false},"FeaturedResponse":{"type":"object","properties":{"cards":{"type":"array","items":{"$ref":"#/components/schemas/CardSummary"}}},"required":["cards"],"additionalProperties":false},"GradeRow":{"type":"object","properties":{"company":{"$ref":"#/components/schemas/SeriesPoint/properties/company"},"grade":{"$ref":"#/components/schemas/SeriesPoint/properties/grade"},"gradeLabel":{"type":"string"},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"deltaPct":{"type":"number","nullable":true},"confidence":{"allOf":[{"$ref":"#/components/schemas/CardSummary/properties/confidence"}],"nullable":true},"lastSaleAt":{"type":"string","format":"date-time","nullable":true},"href":{"type":"string"},"current":{"type":"boolean"}},"required":["company","grade","gradeLabel","priceUsdCents","deltaPct","confidence","lastSaleAt","href","current"],"additionalProperties":false},"SourceBreakdownEntry":{"type":"object","properties":{"source":{"type":"string"},"bucket":{"$ref":"#/components/schemas/SeriesPoint/properties/bucket"},"category":{"$ref":"#/components/schemas/SeriesPoint/properties/category"},"displayName":{"type":"string"},"count":{"type":"integer","minimum":0},"medianUsdCents":{"type":"integer","minimum":0,"nullable":true},"overviewUrl":{"type":"string","nullable":true}},"required":["source","bucket","category","displayName","count","medianUsdCents","overviewUrl"],"additionalProperties":false},"FmvMethodValue":{"type":"object","properties":{"method":{"type":"string","enum":["median","mean","vwap"]},"scorerVersion":{"type":"string"},"label":{"type":"string"},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"confidence":{"allOf":[{"$ref":"#/components/schemas/CardSummary/properties/confidence"}],"nullable":true},"sourceCount":{"type":"integer","minimum":0,"nullable":true},"observationCount":{"type":"integer","minimum":0,"nullable":true}},"required":["method","scorerVersion","label","priceUsdCents","confidence","sourceCount","observationCount"],"additionalProperties":false},"CardDetail":{"type":"object","properties":{"id":{"type":"string"},"game":{"$ref":"#/components/schemas/IndexTile/properties/game"},"type":{"$ref":"#/components/schemas/CardSummary/properties/type"},"name":{"type":"string"},"setName":{"type":"string","nullable":true},"setCode":{"type":"string","nullable":true},"cardNumber":{"type":"string","nullable":true},"variation":{"type":"string","nullable":true},"rarity":{"type":"string","nullable":true},"language":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"imageUrlLg":{"type":"string","nullable":true},"company":{"$ref":"#/components/schemas/SeriesPoint/properties/company"},"grade":{"$ref":"#/components/schemas/SeriesPoint/properties/grade"},"gradeLabel":{"type":"string"},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"deltas":{"$ref":"#/components/schemas/Deltas"},"confidence":{"allOf":[{"$ref":"#/components/schemas/CardSummary/properties/confidence"}],"nullable":true},"sourceCount":{"type":"integer","minimum":0,"nullable":true},"observationCount":{"type":"integer","minimum":0,"nullable":true},"observationWindowDays":{"type":"integer","minimum":0,"nullable":true},"totalObservationCount":{"type":"integer","minimum":0,"nullable":true},"updatedAt":{"type":"string","format":"date-time","nullable":true},"lastSaleAt":{"type":"string","format":"date-time","nullable":true},"refreshing":{"type":"boolean"},"sourceBreakdown":{"type":"array","items":{"$ref":"#/components/schemas/SourceBreakdownEntry"}},"sourceBreakdownAllTime":{"type":"array","items":{"$ref":"#/components/schemas/SourceBreakdownEntry"}},"trackedSources":{"type":"array","items":{"$ref":"#/components/schemas/SourceBreakdownEntry"},"default":[]},"methods":{"type":"array","items":{"$ref":"#/components/schemas/FmvMethodValue"}},"otherGrades":{"type":"array","items":{"$ref":"#/components/schemas/GradeRow"}},"lite":{"type":"boolean"},"otherLanguages":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string"},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"confidence":{"allOf":[{"$ref":"#/components/schemas/CardSummary/properties/confidence"}],"nullable":true},"href":{"type":"string"},"current":{"type":"boolean"}},"required":["language","priceUsdCents","confidence","href","current"],"additionalProperties":false},"default":[]},"otherVariants":{"type":"array","items":{"type":"object","properties":{"variation":{"type":"string","nullable":true},"rarity":{"type":"string","nullable":true},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"confidence":{"allOf":[{"$ref":"#/components/schemas/CardSummary/properties/confidence"}],"nullable":true},"href":{"type":"string"},"current":{"type":"boolean"}},"required":["variation","priceUsdCents","confidence","href","current"],"additionalProperties":false},"default":[]},"otherVersions":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string"},"variation":{"type":"string","nullable":true},"rarity":{"type":"string","nullable":true},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"confidence":{"allOf":[{"$ref":"#/components/schemas/CardSummary/properties/confidence"}],"nullable":true},"imageUrlThumb":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"href":{"type":"string"},"current":{"type":"boolean"}},"required":["language","variation","priceUsdCents","confidence","imageUrlThumb","imageUrl","href","current"],"additionalProperties":false},"default":[]},"similar":{"type":"array","items":{"$ref":"#/components/schemas/CardSummary"}},"href":{"type":"string"},"pageUrl":{"type":"string"}},"required":["id","game","type","name","setName","setCode","cardNumber","variation","language","imageUrl","imageUrlLg","company","grade","gradeLabel","priceUsdCents","deltas","confidence","sourceCount","observationCount","observationWindowDays","totalObservationCount","updatedAt","lastSaleAt","refreshing","sourceBreakdown","sourceBreakdownAllTime","methods","otherGrades","similar","href","pageUrl"],"additionalProperties":false},"CardSimilarResponse":{"type":"object","properties":{"similar":{"type":"array","items":{"$ref":"#/components/schemas/CardSummary"}}},"required":["similar"],"additionalProperties":false},"CardOverviewGrade":{"type":"object","properties":{"company":{"$ref":"#/components/schemas/SeriesPoint/properties/company"},"grade":{"$ref":"#/components/schemas/SeriesPoint/properties/grade"},"gradeLabel":{"type":"string"},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"deltaPct":{"type":"number","nullable":true},"confidence":{"allOf":[{"$ref":"#/components/schemas/CardSummary/properties/confidence"}],"nullable":true},"sourceCount":{"type":"integer","minimum":0,"nullable":true},"observationCount":{"type":"integer","minimum":0,"nullable":true},"updatedAt":{"type":"string","format":"date-time","nullable":true},"lastSaleAt":{"type":"string","format":"date-time","nullable":true},"spark":{"type":"array","items":{"type":"integer","minimum":0}},"href":{"type":"string"}},"required":["company","grade","gradeLabel","priceUsdCents","deltaPct","confidence","sourceCount","observationCount","updatedAt","lastSaleAt","href"],"additionalProperties":false},"CardOverview":{"type":"object","properties":{"id":{"type":"string"},"game":{"$ref":"#/components/schemas/IndexTile/properties/game"},"type":{"$ref":"#/components/schemas/CardSummary/properties/type"},"name":{"type":"string"},"setName":{"type":"string","nullable":true},"setCode":{"type":"string","nullable":true},"cardNumber":{"type":"string","nullable":true},"variation":{"type":"string","nullable":true},"rarity":{"type":"string","nullable":true},"language":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"imageUrlLg":{"type":"string","nullable":true},"gradeCount":{"type":"integer","minimum":0},"href":{"type":"string"},"grades":{"type":"array","items":{"$ref":"#/components/schemas/CardOverviewGrade"}}},"required":["id","game","type","name","setName","setCode","cardNumber","variation","language","imageUrl","imageUrlLg","gradeCount","href","grades"],"additionalProperties":false},"GradedLookup":{"type":"object","properties":{"cert":{"type":"string"},"certNumber":{"type":"string"},"company":{"$ref":"#/components/schemas/SeriesPoint/properties/company"},"found":{"type":"boolean"},"grade":{"allOf":[{"$ref":"#/components/schemas/SeriesPoint/properties/grade"}],"nullable":true},"gradeLabel":{"type":"string","nullable":true},"card":{"allOf":[{"$ref":"#/components/schemas/CardSummary"}],"nullable":true},"certImages":{"type":"object","properties":{"front":{"type":"string","nullable":true},"back":{"type":"string","nullable":true},"item":{"type":"string","nullable":true}},"required":["front","back","item"],"additionalProperties":false,"nullable":true},"collectible":{"type":"object","properties":{"id":{"type":"string"},"renaissItemId":{"type":"string","nullable":true},"itemId":{"type":"string","nullable":true},"cardIdentifier":{"type":"string"},"gradingCompany":{"$ref":"#/components/schemas/SeriesPoint/properties/company"},"grade":{"type":"string","nullable":true},"reviewStatus":{"type":"string"},"lookupOk":{"type":"boolean"},"inferredType":{"type":"string","nullable":true},"source":{"type":"string"},"frontImageUrl":{"type":"string","nullable":true},"backImageUrl":{"type":"string","nullable":true},"frontWithoutStandImageUrl":{"type":"string","nullable":true},"animationUrl":{"type":"string","nullable":true},"itemImageUrl":{"type":"string","nullable":true},"imageSource":{"type":"string","nullable":true},"imageSourceObservationId":{"type":"string","nullable":true},"imageFetchAttemptedAt":{"type":"string","nullable":true},"imageFetchAttempts":{"type":"number"},"subject":{"type":"string","nullable":true},"year":{"type":"number","nullable":true},"brand":{"type":"string","nullable":true},"cardNumber":{"type":"string","nullable":true},"category":{"type":"string","nullable":true},"variety":{"type":"string","nullable":true},"gradeDescription":{"type":"string","nullable":true},"specId":{"type":"number","nullable":true},"specNumber":{"type":"string","nullable":true},"labelType":{"type":"string","nullable":true},"totalPopulation":{"type":"number","nullable":true},"populationHigher":{"type":"number","nullable":true},"isPsaDna":{"type":"boolean","nullable":true},"isDualCert":{"type":"boolean","nullable":true},"reverseBarCode":{"type":"boolean","nullable":true},"rawLookup":{"nullable":true},"collectibleCreatedAt":{"type":"string","nullable":true},"collectibleUpdatedAt":{"type":"string","nullable":true},"importedAt":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","renaissItemId","itemId","cardIdentifier","gradingCompany","grade","reviewStatus","lookupOk","inferredType","source","frontImageUrl","backImageUrl","frontWithoutStandImageUrl","animationUrl","itemImageUrl","imageSource","imageSourceObservationId","imageFetchAttemptedAt","imageFetchAttempts","subject","year","brand","cardNumber","category","variety","gradeDescription","specId","specNumber","labelType","totalPopulation","populationHigher","isPsaDna","isDualCert","reverseBarCode","collectibleCreatedAt","collectibleUpdatedAt","importedAt","createdAt","updatedAt"],"additionalProperties":false,"nullable":true},"reason":{"type":"string","enum":["not_ingested","company_unsupported","compute_incomplete","no_grade_price","game_unsupported","needs_photo","deactivated"],"nullable":true},"warning":{"type":"string","nullable":true}},"required":["cert","certNumber","company","found","grade","gradeLabel","card","certImages"],"additionalProperties":false},"PipelineProgress":{"type":"object","properties":{"stage":{"type":"string","enum":["cert_lookup","identify","enrich","find_item","cache_check","match","crawl","fmv","done"]},"message":{"type":"string"},"done":{"type":"boolean"},"status":{"type":"string","enum":["running","ok","skipped","error"]},"data":{}},"required":["stage","message"],"additionalProperties":false},"TradeRow":{"type":"object","properties":{"source":{"type":"string"},"bucket":{"$ref":"#/components/schemas/SeriesPoint/properties/bucket"},"category":{"$ref":"#/components/schemas/SeriesPoint/properties/category"},"displayName":{"type":"string"},"observedAt":{"type":"string","format":"date-time"},"kind":{"type":"string","enum":["listing","transaction"]},"priceUsdCents":{"type":"integer","minimum":0,"nullable":true},"priceMinor":{"type":"integer","nullable":true},"currency":{"type":"string"},"detail":{"type":"string","nullable":true},"sourceUrl":{"type":"string","nullable":true},"company":{"allOf":[{"$ref":"#/components/schemas/SeriesPoint/properties/company"}],"nullable":true},"grade":{"allOf":[{"$ref":"#/components/schemas/SeriesPoint/properties/grade"}],"nullable":true},"gradeLabel":{"type":"string","nullable":true}},"required":["source","bucket","category","displayName","observedAt","kind","priceUsdCents","priceMinor","currency","detail","sourceUrl","company","grade","gradeLabel"],"additionalProperties":false},"TradesResponse":{"type":"object","properties":{"trades":{"type":"array","items":{"$ref":"#/components/schemas/TradeRow"}},"total":{"type":"integer","minimum":0},"sourceCounts":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"displayName":{"type":"string"},"count":{"type":"integer","minimum":0}},"required":["source","displayName","count"],"additionalProperties":false}}},"required":["trades","total"],"additionalProperties":false},"RecentTrade":{"type":"object","properties":{"source":{"$ref":"#/components/schemas/TradeRow/properties/source"},"bucket":{"$ref":"#/components/schemas/SeriesPoint/properties/bucket"},"category":{"$ref":"#/components/schemas/SeriesPoint/properties/category"},"displayName":{"$ref":"#/components/schemas/TradeRow/properties/displayName"},"observedAt":{"$ref":"#/components/schemas/TradeRow/properties/observedAt"},"kind":{"$ref":"#/components/schemas/TradeRow/properties/kind"},"priceUsdCents":{"$ref":"#/components/schemas/TradeRow/properties/priceUsdCents"},"priceMinor":{"$ref":"#/components/schemas/TradeRow/properties/priceMinor"},"currency":{"$ref":"#/components/schemas/TradeRow/properties/currency"},"detail":{"$ref":"#/components/schemas/TradeRow/properties/detail"},"sourceUrl":{"$ref":"#/components/schemas/TradeRow/properties/sourceUrl"},"company":{"$ref":"#/components/schemas/TradeRow/properties/company"},"grade":{"$ref":"#/components/schemas/TradeRow/properties/grade"},"gradeLabel":{"$ref":"#/components/schemas/TradeRow/properties/gradeLabel"},"id":{"type":"string"},"card":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/IndexTile/properties/game"},"name":{"$ref":"#/components/schemas/CardSummary/properties/name"},"grade":{"$ref":"#/components/schemas/SeriesPoint/properties/grade"},"gradeLabel":{"$ref":"#/components/schemas/CardSummary/properties/gradeLabel"},"setCode":{"$ref":"#/components/schemas/CardSummary/properties/setCode"},"cardNumber":{"$ref":"#/components/schemas/CardSummary/properties/cardNumber"},"href":{"$ref":"#/components/schemas/CardSummary/properties/href"},"imageUrl":{"$ref":"#/components/schemas/CardSummary/properties/imageUrl"}},"required":["game","name","grade","gradeLabel","setCode","cardNumber","href","imageUrl"],"additionalProperties":false}},"required":["source","bucket","category","displayName","observedAt","kind","priceUsdCents","priceMinor","currency","detail","sourceUrl","company","grade","gradeLabel","id","card"],"additionalProperties":false},"RecentTradesResponse":{"type":"object","properties":{"trades":{"type":"array","items":{"$ref":"#/components/schemas/RecentTrade"}}},"required":["trades"],"additionalProperties":false},"SeriesResponse":{"type":"object","properties":{"windowDays":{"type":"integer","exclusiveMinimum":true,"minimum":0},"points":{"type":"array","items":{"$ref":"#/components/schemas/SeriesPoint"}}},"required":["windowDays","points"],"additionalProperties":false},"FmvSourcePoint":{"type":"object","properties":{"source":{"type":"string"},"bucket":{"$ref":"#/components/schemas/SeriesPoint/properties/bucket"},"category":{"$ref":"#/components/schemas/SeriesPoint/properties/category"},"displayName":{"type":"string"},"usdCents":{"type":"integer","minimum":0},"n":{"type":"integer","minimum":0}},"required":["source","bucket","category","displayName","usdCents","n"],"additionalProperties":false},"FmvSeriesPoint":{"type":"object","properties":{"t":{"type":"string","format":"date-time"},"usdCents":{"type":"integer","minimum":0},"n":{"type":"integer","minimum":0},"bySource":{"type":"array","items":{"$ref":"#/components/schemas/FmvSourcePoint"}}},"required":["t","usdCents","n","bySource"],"additionalProperties":false},"FmvMethodLinePoint":{"type":"object","properties":{"t":{"type":"string","format":"date-time"},"usdCents":{"type":"integer","minimum":0}},"required":["t","usdCents"],"additionalProperties":false},"FmvMethodSeries":{"type":"object","properties":{"method":{"$ref":"#/components/schemas/FmvMethodValue/properties/method"},"scorerVersion":{"type":"string"},"label":{"type":"string"},"points":{"type":"array","items":{"$ref":"#/components/schemas/FmvMethodLinePoint"}}},"required":["method","scorerVersion","label","points"],"additionalProperties":false},"FmvSeriesResponse":{"type":"object","properties":{"windowDays":{"type":"integer","exclusiveMinimum":true,"minimum":0},"fmvWindowDays":{"type":"integer","exclusiveMinimum":true,"minimum":0},"gradeLabel":{"type":"string","nullable":true},"points":{"type":"array","items":{"$ref":"#/components/schemas/FmvSeriesPoint"}},"series":{"type":"array","items":{"$ref":"#/components/schemas/FmvMethodSeries"}}},"required":["windowDays","fmvWindowDays","gradeLabel","points","series"],"additionalProperties":false},"SearchResponse":{"type":"object","properties":{"query":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/CardSummary"}}},"required":["query","results"],"additionalProperties":false},"SetResponse":{"type":"object","properties":{"game":{"$ref":"#/components/schemas/IndexTile/properties/game"},"setName":{"type":"string","nullable":true},"setCode":{"type":"string","nullable":true},"language":{"type":"string","nullable":true},"setSegment":{"type":"string"},"href":{"type":"string"},"cardCount":{"type":"integer","minimum":0},"cards":{"type":"array","items":{"$ref":"#/components/schemas/CardSummary"}}},"required":["game","setName","setCode","language","setSegment","href","cardCount","cards"],"additionalProperties":false},"PartnerApplicationInput":{"type":"object","properties":{"shopName":{"type":"string","minLength":1,"maxLength":120},"region":{"type":"string","minLength":1,"maxLength":120},"salesFormat":{"type":"string","minLength":1,"maxLength":60},"contactEmail":{"type":"string","format":"email","maxLength":200},"phone":{"type":"string","maxLength":40,"pattern":"^[0-9+()\\-.\\s]+$"},"message":{"anyOf":[{"anyOf":[{"not":{}},{"type":"string","maxLength":2000}]},{"type":"string","enum":[""]}]}},"required":["shopName","region","salesFormat","contactEmail"],"additionalProperties":false},"DataIssueReportInput":{"type":"object","properties":{"message":{"type":"string","minLength":1,"maxLength":2000},"category":{"type":"string","enum":["wrong_price","wrong_card","broken_link","stale","other"]},"field":{"type":"string","enum":["name","set","card_number","variation","language","image","duplicate","wrong_link","price","stale_price","delta","missing_grade","wrong_grade","source_link","other"]},"target":{"type":"object","properties":{"company":{"type":"string","maxLength":12},"grade":{"type":"string","maxLength":40},"gradeLabel":{"type":"string","maxLength":60},"displayed":{"type":"string","maxLength":400}},"additionalProperties":false},"expected":{"anyOf":[{"anyOf":[{"not":{}},{"type":"string","maxLength":400}]},{"type":"string","enum":[""]}]},"sourceUrl":{"anyOf":[{"anyOf":[{"not":{}},{"type":"string","format":"uri","maxLength":500}]},{"type":"string","enum":[""]}]},"cardHref":{"anyOf":[{"anyOf":[{"not":{}},{"type":"string","maxLength":300}]},{"type":"string","enum":[""]}]},"itemId":{"anyOf":[{"anyOf":[{"not":{}},{"type":"string","format":"uuid"}]},{"type":"string","enum":[""]}]},"contactEmail":{"anyOf":[{"anyOf":[{"not":{}},{"type":"string","format":"email","maxLength":200}]},{"type":"string","enum":[""]}]}},"required":["message"],"additionalProperties":false},"SubmitResponse":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"id":{"type":"string","format":"uuid"}},"required":["ok","id"],"additionalProperties":false},"HealthResponse":{"type":"object","required":["ok","db","rateLimit","internalAuth"],"properties":{"ok":{"type":"boolean","description":"Always true when the service is up."},"db":{"type":"boolean","description":"Whether a database connection (DATABASE_URL) is configured."},"rateLimit":{"type":"boolean","description":"Whether a rate-limit store (Upstash) is configured. When false, all rate limiting fails open."},"internalAuth":{"type":"boolean","description":"Whether the server-only internal token is configured (the non-spoofable trust signal)."}}},"SearchByImageResponse":{"type":"object","required":["ids","confidence"],"properties":{"ids":{"type":"array","description":"Catalog card ids (`items.id`) of the most visually similar cards, best match first. Feed one into `/v1/cards/by-id/{id}`.","items":{"type":"string","format":"uuid"}},"confidence":{"type":"string","enum":["high","medium","low","none"],"description":"How strongly the photo matched. `low` / `none` mean the ids are weak guesses — prompt the user rather than auto-navigating."},"cert":{"type":"string","description":"OPTIONAL — the certification number the label OCR read off a slab photo. The property is OMITTED entirely (not null) when no cert was read, which is every non-slab photo. When present, you can offer `/v1/graded/{cert}` instead of making the user retype it.","example":"PSA149595098"}}}},"securitySchemes":{"ApiKeyId":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"Your public key id (`rk_…`). Pair with X-Api-Secret."},"ApiKeySecret":{"type":"apiKey","in":"header","name":"X-Api-Secret","description":"Your secret (`rsk_…`, shown once at creation). Pair with X-Api-Key."}}}}