{"openapi":"3.1.0","info":{"title":"ExBurst Partner API","version":"1.0.0","description":"Card catalogs, translations, and tightly scoped opt-in account sync for ExBurst. Requires an API key issued by the ExBurst creator."},"servers":[{"url":"https://partner-api.exburst.dev"}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-Api-Key"}}},"paths":{"/health":{"get":{"summary":"Liveness probe","description":"No key needed. Returns { ok, env }.","security":[],"responses":{"200":{"description":"OK"}}}},"/stats.json":{"get":{"summary":"Catalog and translation coverage stats","description":"No key needed. Per-game card counts and per-language translation coverage (official/community); 1 h edge cache. Human-readable twin: /stats.","security":[],"responses":{"200":{"description":"OK"}}}},"/v1/games":{"get":{"summary":"List supported games","description":"List supported games. Costs 1 rate-limit unit per call.","security":[{"ApiKeyAuth":[]}],"parameters":[],"responses":{"200":{"description":"OK"},"401":{"description":"Missing or unknown API key"},"429":{"description":"Rate limit exceeded (see X-RateLimit-* headers)"}}}},"/v1/{game}/cards":{"get":{"summary":"List cards (cursor paginated)","description":"List cards (cursor paginated). Costs 1 rate-limit unit per call.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string","enum":["ua","uaen","opcg","gundam","naruto","nrtb","riftbound","cyberpunk"]},"description":"Game identifier."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from meta.nextCursor."},{"name":"series","in":"query","schema":{"type":"string"},"description":"Filter by set / series code (or scope code for opcg)."},{"name":"search","in":"query","schema":{"type":"string"},"description":"Case-insensitive name search."}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing or unknown API key"},"429":{"description":"Rate limit exceeded (see X-RateLimit-* headers)"}}}},"/v1/{game}/cards/all":{"get":{"summary":"Full card catalog (bulk)","description":"The whole catalog in one response. Heavily cached; intended for daily sync jobs, not per-user calls. Costs 20 rate-limit units per call.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string","enum":["ua","uaen","opcg","gundam","naruto","nrtb","riftbound","cyberpunk"]},"description":"Game identifier."}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing or unknown API key"},"429":{"description":"Rate limit exceeded (see X-RateLimit-* headers)"}}}},"/v1/{game}/cards/{cardno}":{"get":{"summary":"Single card by card number","description":"Single card by card number. Costs 1 rate-limit unit per call.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string","enum":["ua","uaen","opcg","gundam","naruto","nrtb","riftbound","cyberpunk"]},"description":"Game identifier."},{"name":"cardno","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing or unknown API key"},"429":{"description":"Rate limit exceeded (see X-RateLimit-* headers)"}}}},"/v1/{game}/translations":{"get":{"summary":"Batch card translations","description":"Batch card translations. Costs 2 rate-limit units per call.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string","enum":["ua","uaen","opcg","gundam","naruto","nrtb","riftbound","cyberpunk"]},"description":"Game identifier."},{"name":"lang","in":"query","required":true,"schema":{"type":"string"},"description":"Language code; discover valid codes via /v1/{game}/translations/languages."},{"name":"ids","in":"query","required":true,"schema":{"type":"string"},"description":"Comma-separated bare card numbers, max 120 (deduplicated). For more, use the manifest."}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing or unknown API key"},"429":{"description":"Rate limit exceeded (see X-RateLimit-* headers)"}}}},"/v1/{game}/archetypes":{"get":{"summary":"Archetype catalog (valid opponent keys)","description":"Every archetype key for the game (key, name, icon, color, block, series), the vocabulary of result opponentArchetypes and of synced decklists archetypes. meta.maxOpponentArchetypes = keys allowed per result. 1 h edge cache. Costs 3 rate-limit units per call.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string","enum":["ua","uaen","opcg","gundam","naruto","nrtb","riftbound","cyberpunk"]},"description":"Game identifier."}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing or unknown API key"},"429":{"description":"Rate limit exceeded (see X-RateLimit-* headers)"}}}},"/v1/{game}/sync":{"get":{"summary":"User profile + decklists via sync token","description":"User profile + decklists via sync token. Costs 2 rate-limit units per call.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string","enum":["ua","uaen","opcg","gundam","naruto","nrtb","riftbound","cyberpunk"]},"description":"Game identifier."},{"name":"token","in":"query","required":true,"schema":{"type":"string"},"description":"The user's personal sync token (generated on their ExBurst profile). One call per user per 30 s; 429 + Retry-After inside the window."}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing or unknown API key"},"429":{"description":"Rate limit exceeded (see X-RateLimit-* headers)"}}}},"/v1/{game}/sync/result":{"post":{"summary":"Report a game result for a synced deck","description":"Adds one win/loss/draw row to the synced deck: the same rows the player's ExBurst Match Log, deck W/L tab and My decks record show. Body (strict, unknown fields 400): { token, deckId, result: win|loss|draw (aliases W/L/T/tie), matchId? (idempotency, recommended), opponentArchetypes? (keys from /v1/{game}/archetypes, at most meta.maxOpponentArchetypes), opponentArchetype? (single-key shorthand), opponentCardno? (leader/legend cardno, resolved to its key), wonDice?, note? (max 280), playedAt? }. Unknown archetype key or non-archetype cardno = 400. One report per user per 30 s (429 + Retry-After); a repeated matchId is acknowledged as duplicate without double-counting. Costs 5 rate-limit units.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string","enum":["ua","uaen","opcg","gundam","naruto","nrtb","riftbound","cyberpunk"]},"description":"Game identifier."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token","deckId","result"]}}}},"responses":{"200":{"description":"Recorded (or duplicate-acknowledged); data.record + data.totals"},"400":{"description":"Invalid body, unknown archetype key, or too many opponent archetypes"},"403":{"description":"Locked deck or official starter list"},"404":{"description":"Unknown sync token, or deck not owned by that user"},"429":{"description":"Cooldown or budget exceeded"}}}},"/v1/{game}/sync/decks/{deckId}":{"put":{"summary":"Update a user's deck via sync token","description":"Pushes a deck edit back onto ExBurst through the site's own save pipeline (full validation, auto archetypes, derived colors). Body: { token, name?, description?, slots?, sideboardSlots?, selectedItems? } — slots round-trip the shape read from /v1/{game}/sync. Visibility/locks/folders are never writable. One update per user per 30 s. Costs 5 units.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string","enum":["ua","uaen","opcg","gundam","naruto","nrtb","riftbound","cyberpunk"]},"description":"Game identifier."},{"name":"deckId","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"]}}}},"responses":{"200":{"description":"Updated deck (site's Deck shape)"},"400":{"description":"Deck content failed validation (message says why)"},"403":{"description":"Locked deck or official starter list"},"404":{"description":"Unknown sync token, or deck not owned by that user"},"429":{"description":"Cooldown or budget exceeded"}}}},"/v1/{game}/translations/languages":{"get":{"summary":"Available translation languages","description":"Languages that exist for this game, with approved-translation counts and the latest update stamp. Costs 3 rate-limit units per call.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string","enum":["ua","uaen","opcg","gundam","naruto","nrtb","riftbound","cyberpunk"]},"description":"Game identifier."}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing or unknown API key"},"429":{"description":"Rate limit exceeded (see X-RateLimit-* headers)"}}}},"/v1/{game}/translations/manifest":{"get":{"summary":"Translation manifest (all cards, one language)","description":"Every translation for one game and language (official + top-voted community proposals merged, official precedence; items carry source and communityScore), with updatedAt stamps for delta sync. Costs 10 rate-limit units per call.","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string","enum":["ua","uaen","opcg","gundam","naruto","nrtb","riftbound","cyberpunk"]},"description":"Game identifier."},{"name":"lang","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing or unknown API key"},"429":{"description":"Rate limit exceeded (see X-RateLimit-* headers)"}}}}}}