Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Valo.Data Games API
summary: 'Trading card catalogue and market prices: Cardmarket, US market, eBay sales, graded prices, populations.'
description: 'Catalogue and price data for trading card games (Pokémon, One Piece, Yu-Gi-Oh!, Magic, Lorcana and more):
Cardmarket and US market prices, eBay sold prices, graded prices, PSA/CCC populations and price history. ## Français
**Authentification.** Chaque requête porte une clé API : `Authorization: Bearer vd_live_…`. Les clés se créent dans
le portail développeur et ne sont affichées qu''une fois. `vd_test_` et
`vd_live_` sont une étiquette choisie à la création pour séparer préproduction et production : mêmes données, mêmes
crédits, mêmes quotas. Une clé peut porter une date d''expiration (`401 api_key_expired`), une liste d''adresses IP ou
de blocs CIDR autorisés (`403 ip_not_allowed`) et un plafond mensuel de crédits (`429 key_credit_cap_reached`). Le Sandbox
sert les mêmes prix que les forfaits payants, sans les cotes gradées ni les populations. Les
identifiants et les liens Cardmarket et marché US (`cardmarket_product_id`, `tcgplayer_product_id`, `cardmarket_url`,
`tcgplayer_url`) sont inclus à partir de Growth : ils valent `null` en Sandbox et en Starter. **Crédits.** Chaque forfait inclut des crédits mensuels (barème ci-dessous). Les réponses en erreur ne sont jamais
facturées. Une fois les crédits épuisés, l''API répond `429 quota_exceeded` jusqu''au renouvellement (`resets_at`). Le Sandbox
lit au plus 250 cartes et produits scellés distincts par mois, toutes routes confondues ; une fiche déjà lue
reste disponible, une nouvelle au-delà répond `429 catalog_limit_reached`. Il envoie au plus 100 requêtes facturées
par jour (UTC) : au-delà, `429 daily_limit_reached` jusqu''à minuit UTC (`resets_at`). **Débit.** Les requêtes sont limitées par organisation et par minute selon le forfait : `429 rate_limited`, à rejouer après
`Retry-After` secondes. **Prix.** Chaque source garde sa devise native, sans conversion. `amount` vaut `null` (jamais `0`) dès que `status`
n''est pas `available`. `observed_at` est la date d''observation par la source ; `computed_at` celle du dernier calcul. Les ventes eBay sont collectées au mieux (`collection: best_effort`). **Analyses.** Les routes `/data/v1/analysis/*` répondent prêt à afficher : identification d''une carte à partir d''un texte libre, prix recommandé, fiabilité et variations sur 7, 30 et 90 jours, plus fortes hausses et baisses, comparaison, synthèse d''une édition. `recommended` est le prix qu''affiche l''app ValoTCG, toujours en EUR : le marché US y est converti au dernier taux BCE (`fx_rate`), alors que `prices[]` garde la devise native. **Pagination.** Les listes renvoient `next_cursor` ; passez-le en `cursor` pour la page suivante (`page_size` ≤ 100). **Attribution.** Affichez « Données : ValoTCG » à proximité des données affichées. Voir les
conditions de l''API. ## English
**Authentication.** Every request carries an API key: `Authorization: Bearer vd_live_…`. Keys are created in the
developer portal and shown once. `vd_test_` and `vd_live_` are a label
chosen at creation to separate staging from production: same data, same credits, same quotas. A key may carry an
expiry date (`401 api_key_expired`), a list of allowed IP addresses or CIDR blocks (`403 ip_not_allowed`) and a
monthly credit cap (`429 key_credit_cap_reached`). The Sandbox serves the same prices as paid plans, without graded prices
and populations. Cardmarket and US market ids and links
(`cardmarket_product_id`, `tcgplayer_product_id`, `cardmarket_url`, `tcgplayer_url`) are included from Growth up:
they are `null` on Sandbox and Starter. **Credits.** Each plan includes monthly credits (scale below). Error responses are never billed. Once credits are
exhausted, the API answers `429 quota_exceeded` until renewal (`resets_at`). The Sandbox reads at most 250
distinct cards and sealed products per month across all routes; an item already read stays available, a new one
beyond the cap answers `429 catalog_limit_reached`.'
termsOfService: https://valotcg.com/developers/terms
contact:
name: ValoTCG
url: https://valotcg.com/developers
email: contact@valotcg.com
version: 1.0.0
servers:
- url: https://api.valotcg.com
description: Production
- url: https://api.preprod.valotcg.com
description: Preproduction
tags:
- name: Games
description: Games, card languages, per source coverage and rarity codes. Free.
paths:
/data/v1/games:
get:
tags:
- Games
summary: List games (0 credit)
operationId: get_games_data_v1_games_get
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GamesResponse'
'401':
description: '`invalid_api_key`, `api_key_expired`'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: '`insufficient_scope`, `subscription_inactive`, `plan_feature_unavailable`, `ip_not_allowed`'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: '`game_not_found`, `card_not_found`, `sealed_not_found`, `edition_not_found`'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: '`invalid_request`, `invalid_cursor`, `range_exceeds_plan`'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'429':
description: '`rate_limited` (see `Retry-After`), `quota_exceeded`, `key_credit_cap_reached` (key credit cap), `catalog_limit_reached` or `daily_limit_reached` (Sandbox)'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'503':
description: '`quota_unavailable`'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
security:
- ApiKey: []
/data/v1/games/{game}/rarities:
get:
tags:
- Games
summary: List rarity codes of a game (0 credit)
description: 'Canonical rarity codes of a game: the values of `rarity_code` on cards, accepted by the `rarity` filter of
`GET /data/v1/cards`. Every code of the game is listed, including codes no card carries yet.'
operationId: get_game_rarities_data_v1_games__game__rarities_get
security:
- ApiKey: []
parameters:
- name: game
in: path
required: true
schema:
type: string
description: Game slug from GET /data/v1/games.
title: Game
description: Game slug from GET /data/v1/games.
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GameRarities'
'401':
description: '`invalid_api_key`, `api_key_expired`'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: '`insufficient_scope`, `subscription_inactive`, `plan_feature_unavailable`, `ip_not_allowed`'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: '`game_not_found`, `card_not_found`, `sealed_not_found`, `edition_not_found`'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: '`invalid_request`, `invalid_cursor`, `range_exceeds_plan`'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'429':
description: '`rate_limited` (see `Retry-After`), `quota_exceeded`, `key_credit_cap_reached` (key credit cap), `catalog_limit_reached` or `daily_limit_reached` (Sandbox)'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'503':
description: '`quota_unavailable`'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
schemas:
ErrorDetail:
properties:
code:
type: string
title: Code
description: Stable snake_case error code, e.g. `card_not_found`, `quota_exceeded`.
message:
type: string
title: Message
description: Human readable explanation.
request_id:
type: string
title: Request Id
description: Identifier of the request, also returned in the `X-Request-Id` header.
docs_url:
type: string
title: Docs Url
description: Documentation of this error code.
additionalProperties: true
type: object
required:
- code
- message
- request_id
- docs_url
title: ErrorDetail
GameInfo:
properties:
slug:
type: string
title: Slug
description: Game slug used by every `game` parameter.
name:
type: string
title: Name
languages:
items:
type: string
enum:
- fr
- en
- ja
- zh
- de
- es
- it
- pt
type: array
title: Languages
description: Card languages available for this game.
coverage:
additionalProperties:
$ref: '#/components/schemas/schemas__games__SourceCoverage'
type: object
title: Coverage
description: 'Per source coverage: cardmarket, us_market, ebay_raw, ebay_graded, gcc (Graded Card Center completed sales, last 90 days), psa_population, ccc_population, sealed_cardmarket, sealed_us_market (US market price), sealed_ebay, sealed_gcc (Graded Card Center completed sales, last 90 days).'
vision:
type: string
enum:
- available
- unavailable
title: Vision
description: 'Valo.Vision status: `available` once at least one language of the game is open to `POST /vision/v1/scans`. Recognition opens per game/language pair after its qualification; the other pairs answer 403 `vision_not_available`.'
vision_languages:
items:
type: string
enum:
- fr
- en
- ja
- zh
- de
- es
- it
- pt
type: array
title: Vision Languages
description: Languages open to Valo.Vision for this game (public codes, e.g. `["fr"]`); empty when `vision` is `unavailable`. Any other language of the game answers 403 `vision_not_available` on `POST /vision/v1/scans`.
type: object
required:
- slug
- name
- languages
- coverage
- vision
- vision_languages
title: GameInfo
GameRarities:
properties:
game:
type: string
title: Game
description: Game slug.
rarities:
items:
$ref: '#/components/schemas/RarityInfo'
type: array
title: Rarities
description: Every rarity code of the game, by `rank` then `code`.
type: object
required:
- game
- rarities
title: GameRarities
GamesResponse:
properties:
items:
items:
$ref: '#/components/schemas/GameInfo'
type: array
title: Items
type: object
required:
- items
title: GamesResponse
ErrorResponse:
properties:
error:
$ref: '#/components/schemas/ErrorDetail'
type: object
required:
- error
title: ErrorResponse
schemas__games__SourceCoverage:
properties:
status:
type: string
enum:
- available
- stale
- missing
title: Status
description: '`available`: values observed within 2 days (Cardmarket, US market), 7 days (eBay, Graded Card Center completed sales) or 8 days (weekly PSA/CCC population reads). `stale`: values exist but are older. `missing`: no value.'
refs_total:
type: integer
title: Refs Total
description: Cards (or sealed products for `sealed_*` sources) of the game.
refs_with_value:
type: integer
title: Refs With Value
description: References carrying a value for this source.
latest_observed_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Latest Observed At
description: Most recent observation day.
type: object
required:
- status
- refs_total
- refs_with_value
title: SourceCoverage
RarityInfo:
properties:
code:
type: string
title: Code
description: Canonical rarity code, the `rarity_code` of cards and a value of the `rarity` filter.
name_en:
type: string
title: Name En
description: English name of the rarity.
name_fr:
type: string
title: Name Fr
description: French name of the rarity.
rank:
type: integer
title: Rank
description: 'Sort order within the game: lower is more common.'
languages:
items:
type: string
enum:
- fr
- en
- ja
- zh
- de
- es
- it
- pt
type: array
title: Languages
description: Card languages carrying this code; empty when no card has it yet.
card_count:
type: integer
title: Card Count
description: Cards of the game carrying this code, all languages.
type: object
required:
- code
- name_en
- name_fr
- rank
- languages
- card_count
title: RarityInfo
securitySchemes:
ApiKey:
type: http
description: '`Authorization: Bearer vd_live_…` (or `vd_test_…`). Keys are shown once at creation.'
scheme: bearer