{"openapi":"3.1.0","info":{"title":"TCG API","version":"1.0.0","description":"Catalogue public de cartes et impressions TCG. Les traductions de noms et les langues imprimées sont distinctes. La couverture est celle des sources actuellement importées, consultable dans /v1/catalog/status."},"servers":[{"url":"https://api.erpclimax.fr"}],"tags":[{"name":"Catalogue"},{"name":"Cartes"},{"name":"Images"},{"name":"Démonstration"},{"name":"Compte"},{"name":"Clés"},{"name":"Agents"},{"name":"Service"}],"paths":{"/health":{"get":{"operationId":"health","tags":["Service"],"summary":"État du service","responses":{"200":{"description":"Service chargé","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"version":{"type":"string"}}}}}}}}},"/v1/catalog/status":{"get":{"operationId":"catalogStatus","tags":["Catalogue"],"summary":"Couverture réelle et sources importées","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/CatalogStatus"}}}}}},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"string"},"description":"Délai en secondes avant un nouvel essai."}}},"503":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/games":{"get":{"operationId":"listGames","tags":["Catalogue"],"summary":"Jeux et collections disponibles","responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Game"}}}}}}},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"string"},"description":"Délai en secondes avant un nouvel essai."}}},"503":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/sets":{"get":{"operationId":"listSets","tags":["Catalogue"],"summary":"Extensions disponibles","parameters":[{"name":"q","in":"query","schema":{"type":"string","maxLength":200},"description":"Recherche par nom traduit, numéro ou variante."},{"name":"game","in":"query","schema":{"type":"string","maxLength":200},"description":"Identifiant du jeu fourni par /v1/games."},{"name":"language","in":"query","schema":{"type":"string","maxLength":200},"description":"Langue imprimée (ja, en, fr…) ; inconnue si null. Ce filtre ne porte pas sur la langue des noms."},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":2048},"description":"Curseur opaque nextCursor du résultat précédent, à utiliser avec les mêmes filtres."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":24}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Set"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"string"},"description":"Délai en secondes avant un nouvel essai."}}},"503":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/demo/cards":{"get":{"operationId":"demoCards","tags":["Démonstration"],"summary":"Recherche gratuite limitée à 12 résultats/page et 30 appels/minute/IP","parameters":[{"name":"q","in":"query","schema":{"type":"string","maxLength":200},"description":"Recherche par nom traduit, numéro ou variante."},{"name":"game","in":"query","schema":{"type":"string","maxLength":200},"description":"Identifiant du jeu fourni par /v1/games."},{"name":"language","in":"query","schema":{"type":"string","maxLength":200},"description":"Langue imprimée (ja, en, fr…) ; inconnue si null. Ce filtre ne porte pas sur la langue des noms."},{"name":"set","in":"query","schema":{"type":"string","maxLength":200},"description":"Identifiant stable du set."},{"name":"rarity","in":"query","schema":{"type":"string","maxLength":200},"description":"Rareté telle que renseignée par la source."},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":2048},"description":"Curseur opaque nextCursor du résultat précédent, à utiliser avec les mêmes filtres."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":12,"default":12}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Card"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"string"},"description":"Délai en secondes avant un nouvel essai."}}},"503":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/demo/cards/{id}":{"get":{"operationId":"demoCard","tags":["Démonstration"],"summary":"Fiche publique pour explorer le catalogue ; limitée par IP","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Card"}}}}}},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"string"},"description":"Délai en secondes avant un nouvel essai."}}},"503":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/cards":{"get":{"operationId":"searchCards","tags":["Cartes"],"summary":"Rechercher les impressions de cartes","security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","schema":{"type":"string","maxLength":200},"description":"Recherche par nom traduit, numéro ou variante."},{"name":"game","in":"query","schema":{"type":"string","maxLength":200},"description":"Identifiant du jeu fourni par /v1/games."},{"name":"language","in":"query","schema":{"type":"string","maxLength":200},"description":"Langue imprimée (ja, en, fr…) ; inconnue si null. Ce filtre ne porte pas sur la langue des noms."},{"name":"set","in":"query","schema":{"type":"string","maxLength":200},"description":"Identifiant stable du set."},{"name":"rarity","in":"query","schema":{"type":"string","maxLength":200},"description":"Rareté telle que renseignée par la source."},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":2048},"description":"Curseur opaque nextCursor du résultat précédent, à utiliser avec les mêmes filtres."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":24}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Card"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"string"},"description":"Délai en secondes avant un nouvel essai."}}},"503":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/cards/{id}":{"get":{"operationId":"getCard","tags":["Cartes"],"summary":"Lire une impression précise par son ID stable","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Succès","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Card"}}}}}},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"string"},"description":"Délai en secondes avant un nouvel essai."}}},"503":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/images/{id}":{"get":{"operationId":"cardImage","tags":["Images"],"summary":"Image publique associée à une carte","description":"Aucun paramètre URL libre. Cache public et ETag. Les droits et attributions restent ceux des sources.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"face","in":"query","schema":{"type":"string","enum":["front","back"],"default":"front"}}],"responses":{"200":{"description":"Image originale disponible","content":{"image/webp":{"schema":{"type":"string","contentEncoding":"binary"}},"image/jpeg":{"schema":{"type":"string","contentEncoding":"binary"}},"image/png":{"schema":{"type":"string","contentEncoding":"binary"}}}},"304":{"description":"Image inchangée"},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/signup":{"post":{"operationId":"signup","tags":["Compte"],"summary":"Créer un compte gratuit et ouvrir une session","description":"Origin doit être l’origine du portail. Content-Type: application/json. Limité à 5 inscriptions/heure/IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","maxLength":254},"password":{"type":"string","minLength":12,"maxLength":256}},"additionalProperties":false}}}},"responses":{"200":{"description":"Session ouverte via cookie HttpOnly.","content":{"application/json":{"schema":{"type":"object","properties":{"account":{"$ref":"#/components/schemas/Account"}}}}}},"201":{"description":"Compte créé et session ouverte","content":{"application/json":{"schema":{"type":"object","properties":{"account":{"$ref":"#/components/schemas/Account"}}}}}},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/login":{"post":{"operationId":"login","tags":["Compte"],"summary":"Ouvrir une session développeur","description":"Origin doit être l’origine du portail. Ne pas envoyer de clé API.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","maxLength":254},"password":{"type":"string","minLength":12,"maxLength":256}},"additionalProperties":false}}}},"responses":{"200":{"description":"Session ouverte via cookie HttpOnly.","content":{"application/json":{"schema":{"type":"object","properties":{"account":{"$ref":"#/components/schemas/Account"}}}}}},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/logout":{"post":{"operationId":"logout","tags":["Compte"],"summary":"Fermer la session","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Session fermée","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"401":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/me":{"get":{"operationId":"accountProfile","tags":["Compte"],"summary":"Compte et consommation du jour UTC","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Profil développeur","content":{"application/json":{"schema":{"type":"object","properties":{"account":{"$ref":"#/components/schemas/Account"},"usage":{"type":"object","properties":{"usedToday":{"type":"integer"},"limitToday":{"type":"integer"}}},"limits":{"type":"object","properties":{"minute":{"type":"integer"},"day":{"type":"integer"},"activeKeys":{"type":"integer"}}}}}}}},"401":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/keys":{"get":{"operationId":"listKeys","tags":["Clés"],"summary":"Lister les clés sans leurs secrets","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Clés du compte","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Key"}}}}}}},"401":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createKey","tags":["Clés"],"summary":"Créer une clé ; le secret est renvoyé une seule fois","security":[{"sessionCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":80}}}}}},"responses":{"201":{"description":"Clé créée","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/Key"},"secret":{"type":"string","description":"Secret Bearer à enregistrer dans un gestionnaire de secrets. Ne sera plus consultable."}}}}}},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/keys/{id}":{"delete":{"operationId":"revokeKey","tags":["Clés"],"summary":"Révoquer immédiatement sa propre clé","security":[{"sessionCookie":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Clé révoquée","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"401":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/mcp":{"post":{"operationId":"mcpRequest","tags":["Agents"],"summary":"Endpoint MCP Streamable HTTP stateless","description":"JSON-RPC 2.0, protocoles négociés : 2025-03-26, 2025-06-18, 2025-11-25. Bearer requis. Accept: application/json, text/event-stream. Outils search_cards/get_card/list_sets. Quota partagé avec REST, y compris les requêtes protocole.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["jsonrpc","method"],"properties":{"jsonrpc":{"const":"2.0"},"id":{"type":["string","number"]},"method":{"type":"string"},"params":{"type":"object"}}}}}},"responses":{"200":{"description":"Réponse JSON-RPC","content":{"application/json":{"schema":{"type":"object"}}}},"202":{"description":"Notification acceptée"},"400":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"406":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Erreur structurée ; quota dépassé : Retry-After en secondes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"tcg_live_*"},"sessionCookie":{"type":"apiKey","in":"cookie","name":"tcg_session"}},"schemas":{"Error":{"type":"object","required":["error","requestId"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}},"requestId":{"type":"string"}}},"Pagination":{"type":"object","required":["limit","nextCursor","total"],"properties":{"limit":{"type":"integer"},"nextCursor":{"type":["string","null"]},"total":{"type":"integer"}}},"Card":{"type":"object","required":["id","game","language","images"],"properties":{"id":{"type":"string"},"franchise":{"type":"string"},"game":{"type":"string"},"setId":{"type":["string","null"]},"number":{"type":"string"},"language":{"type":["string","null"],"description":"Langue imprimée vérifiée ; null si non renseignée."},"names":{"type":"object","additionalProperties":{"type":["string","null"]}},"rarity":{"type":["string","null"]},"variant":{"type":["string","null"]},"images":{"type":"object","properties":{"front":{"type":["string","null"]},"back":{"type":["string","null"]}}},"sources":{"type":"array","items":{"type":"object"}},"updatedAt":{"type":["string","null"]},"attributes":{"type":"object"}}},"Set":{"type":"object","properties":{"id":{"type":"string"},"game":{"type":"string"},"name":{"type":"string"},"code":{"type":"string"},"language":{"type":["string","null"]},"cardCount":{"type":"integer"}}},"Game":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"franchise":{"type":"string"},"languages":{"type":"array","items":{"type":["string","null"]}},"cardCount":{"type":"integer"},"setCount":{"type":"integer"}}},"CatalogStatus":{"type":"object","description":"Comptes effectifs, sources et avertissements sur la couverture. Aucun état privé ERP."},"Account":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"plan":{"type":"string"},"createdAt":{"type":"string"}}},"Key":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string"},"createdAt":{"type":"string"},"revokedAt":{"type":["string","null"]}}}}}}