{
  "openapi": "3.1.0",
  "info": {
    "title": "Master Setter Pokémon TCG Catalog API",
    "version": "1.0.0",
    "summary": "Pokémon Trading Card Game catalog in 14 languages: 196,872 cards, 272,054 printings, 1,833 sets, including Japanese, Korean, Traditional and Simplified Chinese, Thai and Indonesian.",
    "description": "Read-only JSON API over the Master Setter Pokémon TCG catalog. It models each PRINTING (card × language × finish × set), not just each card, which is what a scanner resolves and a collector or seller tracks.\n\nLanguages (language code → cards): en English 21,795 · ja Japanese 21,495 · fr French 19,948 · it Italian 19,745 · de German 18,947 · es Spanish 16,713 · ko Korean 15,562 · pt Portuguese 14,396 · zh-tw Traditional Chinese 13,127 · id Indonesian 11,937 · th Thai 11,853 · zh-cn Simplified Chinese 8,010 · es-mx Latin American Spanish 1,758 · ru Russian 1,104 · pl Polish 254 · nl Dutch 228.\n\nIDs: sets are `<lang>-<code>` (e.g. `en-base1`, `ko-sv4a`); cards are `<set id>-<number>` (e.g. `en-base1-4`). The same bare code across languages links a card to its localized printings.\n\nGet a free key in one request: `POST /v1/keys` with `{\"email\": \"you@example.com\"}`. Free tier: 1,000 requests/month. Every response carries X-RateLimit-Limit / -Used / -Remaining headers.\n\nNot affiliated with or endorsed by The Pokémon Company, Nintendo, Creatures or GAME FREAK. Card data includes content from TCGdex (MIT).",
    "contact": { "name": "Master Setter API", "email": "support@master-setter.com", "url": "https://api.master-setter.com/" }
  },
  "servers": [{ "url": "https://api.master-setter.com" }],
  "security": [{ "bearer": [] }],
  "tags": [
    { "name": "Keys", "description": "Self-serve API keys" },
    { "name": "Sets", "description": "Expansions, promo sets and decks, per language" },
    { "name": "Cards", "description": "Cards with their printings (variants)" }
  ],
  "paths": {
    "/v1/keys": {
      "post": {
        "tags": ["Keys"], "operationId": "createKey", "security": [],
        "summary": "Get a free API key instantly",
        "description": "Returns a free-tier key (1,000 requests/month) in the response. No card, no dashboard. One active free key per email; at most 3 new keys per IP per day. The key is shown once.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": {
          "type": "object", "required": ["email"],
          "properties": { "email": { "type": "string", "format": "email" }, "source": { "type": "string", "description": "Optional: how you found us (e.g. 'chatgpt', 'claude', 'mcp', 'github')." } } } } } },
        "responses": {
          "201": { "description": "Key created", "content": { "application/json": { "schema": {
            "type": "object", "properties": { "key": { "type": "string", "example": "mst_…" }, "tier": { "type": "string" }, "monthly_limit": { "type": "integer" }, "try_it": { "type": "string" } } } } } },
          "409": { "$ref": "#/components/responses/Error" }, "429": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/sets": {
      "get": {
        "tags": ["Sets"], "operationId": "listSets",
        "summary": "List sets, or get one set with its real card count",
        "description": "Without `id`: paginated list, newest first, optionally filtered by language. With `id`: one set, including `card_count` computed from the cards actually present (not a stored total).",
        "parameters": [
          { "name": "id", "in": "query", "schema": { "type": "string" }, "example": "ko-sv4a", "description": "A set id like en-base1, ja-sv4a, ko-sv4a, th-sv1v." },
          { "$ref": "#/components/parameters/lang" },
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" }
        ],
        "responses": {
          "200": { "description": "Set or list of sets", "content": { "application/json": { "schema": { "oneOf": [
            { "$ref": "#/components/schemas/SetList" },
            { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/SetWithCount" }, "retrieved_at": { "type": "string", "format": "date-time" } } } ] } } } },
          "401": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" }, "429": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/cards": {
      "get": {
        "tags": ["Cards"], "operationId": "getCards",
        "summary": "Get one card with its printings, list a set's cards, or search by name",
        "description": "Give exactly one of `id`, `set` or `q`. Names are stored in the card's own language, so search Korean cards with a Korean name (e.g. 피카츄), Japanese with Japanese (ピカチュウ), and so on; combine with `lang` to restrict to one language. Search totals are estimates (see pagination.total_is_estimate).",
        "parameters": [
          { "name": "id", "in": "query", "schema": { "type": "string" }, "example": "en-base1-4", "description": "One card, returned with all its variants (printings)." },
          { "name": "set", "in": "query", "schema": { "type": "string" }, "example": "ja-sv4a", "description": "All cards in a set, ordered by number." },
          { "name": "q", "in": "query", "schema": { "type": "string", "minLength": 2, "maxLength": 60 }, "example": "Charizard", "description": "Case-insensitive name contains-match." },
          { "$ref": "#/components/parameters/lang" },
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" }
        ],
        "responses": {
          "200": { "description": "Card or list of cards", "content": { "application/json": { "schema": { "oneOf": [
            { "$ref": "#/components/schemas/CardList" },
            { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/CardWithVariants" }, "retrieved_at": { "type": "string", "format": "date-time" } } } ] } } } },
          "400": { "$ref": "#/components/responses/Error" }, "401": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" }, "429": { "$ref": "#/components/responses/Error" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": { "bearer": { "type": "http", "scheme": "bearer", "description": "Authorization: Bearer mst_… (get one free from POST /v1/keys)" } },
    "parameters": {
      "lang": { "name": "lang", "in": "query", "schema": { "type": "string", "enum": ["en","ja","fr","it","de","es","ko","pt","zh-tw","id","th","zh-cn","es-mx","ru","pl","nl"] },
        "description": "Language code: en English, ja Japanese, fr French, it Italian, de German, es Spanish, ko Korean, pt Portuguese, zh-tw Traditional Chinese, id Indonesian, th Thai, zh-cn Simplified Chinese, es-mx Latin American Spanish, ru Russian, pl Polish, nl Dutch." },
      "limit": { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 } },
      "offset": { "name": "offset", "in": "query", "schema": { "type": "integer", "minimum": 0, "default": 0 } }
    },
    "responses": { "Error": { "description": "Error", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" } } } } } } },
    "schemas": {
      "Pagination": { "type": "object", "properties": {
        "limit": { "type": "integer" }, "offset": { "type": "integer" }, "total": { "type": ["integer","null"] },
        "total_is_estimate": { "type": "boolean" }, "has_more": { "type": "boolean", "description": "The reliable end-of-results signal." } } },
      "Set": { "type": "object", "properties": {
        "id": { "type": "string", "example": "ko-sv4a" }, "name": { "type": "string", "description": "Name in the set's own language." },
        "name_en": { "type": ["string","null"], "description": "English name where known." }, "series": { "type": ["string","null"] },
        "release_date": { "type": ["string","null"], "format": "date" }, "total": { "type": ["integer","null"] }, "printed_total": { "type": ["integer","null"] },
        "language": { "type": "string" }, "logo_url": { "type": ["string","null"] }, "symbol_url": { "type": ["string","null"] } } },
      "SetWithCount": { "allOf": [ { "$ref": "#/components/schemas/Set" }, { "type": "object", "properties": { "card_count": { "type": "integer", "description": "Cards actually present." } } } ] },
      "SetList": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Set" } }, "pagination": { "$ref": "#/components/schemas/Pagination" }, "retrieved_at": { "type": "string", "format": "date-time" } } },
      "Card": { "type": "object", "properties": {
        "id": { "type": "string", "example": "en-base1-4" }, "set_id": { "type": "string" }, "number": { "type": ["string","null"] }, "local_id": { "type": ["string","null"] },
        "name": { "type": "string", "description": "Name in the card's own language." }, "supertype": { "type": ["string","null"] },
        "subtypes": { "type": ["array","null"], "items": { "type": "string" } }, "hp": { "type": ["string","integer","null"] },
        "types": { "type": ["array","null"], "items": { "type": "string" } }, "rarity": { "type": ["string","null"] }, "artist": { "type": ["string","null"] },
        "regulation_mark": { "type": ["string","null"] }, "image_small": { "type": ["string","null"] }, "image_large": { "type": ["string","null"] },
        "updated_at": { "type": ["string","null"], "format": "date-time" } } },
      "Variant": { "type": "object", "description": "One printing of a card (finish/edition).", "properties": {
        "variant_key": { "type": "string", "example": "holofoil" }, "variant_label": { "type": ["string","null"], "example": "Holofoil" },
        "is_default": { "type": "boolean" }, "image_small": { "type": ["string","null"] }, "image_large": { "type": ["string","null"] } } },
      "CardWithVariants": { "allOf": [ { "$ref": "#/components/schemas/Card" }, { "type": "object", "properties": { "variants": { "type": "array", "items": { "$ref": "#/components/schemas/Variant" } } } } ] },
      "CardList": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Card" } }, "pagination": { "$ref": "#/components/schemas/Pagination" }, "retrieved_at": { "type": "string", "format": "date-time" } } }
    }
  }
}
