{"openapi":"3.0.0","paths":{"/collections":{"get":{"operationId":"CollectionsController_findAll","parameters":[{"name":"search","required":false,"in":"query","schema":{"type":"string"}},{"name":"sortOrder","required":false,"in":"query","schema":{"enum":["asc","desc"],"type":"string"}},{"name":"sortBy","required":false,"in":"query","schema":{"enum":["name","createdAt","updatedAt","cardCount","totalValue"],"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Items per page (default: 20, max: 50)","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","description":"Page number (default: 1)","schema":{"type":"number"}}],"responses":{"200":{"description":"Collections retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"isDefault":{"type":"boolean"},"cardCount":{"type":"integer"},"totalValue":{"type":"number","nullable":true},"totalValueEur":{"type":"number","nullable":true},"valueCurrency":{"type":"string","nullable":true},"valueCalculatedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"},"hasNextPage":{"type":"boolean"},"nextCursor":{"type":"string","nullable":true}},"additionalProperties":true}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized"}},"security":[{"apiKey":[]},{"oauth2":["collection:read"]}],"summary":"List all collections for the authenticated user","tags":["Collections"],"description":"Required scope: `collection:read`."}},"/collections/{id}":{"get":{"operationId":"CollectionsController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Collection ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Collection retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"isDefault":{"type":"boolean"},"cardCount":{"type":"integer"},"totalValue":{"type":"number","nullable":true},"totalValueEur":{"type":"number","nullable":true},"valueCurrency":{"type":"string","nullable":true},"valueCalculatedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"uniqueCardCount":{"type":"integer"},"binderCount":{"type":"integer"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Collection not found"}},"security":[{"apiKey":[]},{"oauth2":["collection:read"]}],"summary":"Get a collection by ID with detailed stats","tags":["Collections"],"description":"Required scope: `collection:read`."}},"/collections/{id}/cards/search":{"get":{"description":"Search for cards within the user's collection. Returns matching cards with location info (binder/deck) and quantities.\n\nRequired scope: `collection:read`.","operationId":"CollectionsController_searchCards","parameters":[{"name":"id","required":true,"in":"path","description":"Collection ID","schema":{"type":"string"}},{"name":"rarities","required":false,"in":"query","description":"Comma-separated rarities","schema":{"type":"string"}},{"name":"cmcMax","required":false,"in":"query","schema":{"type":"number"}},{"name":"cmcMin","required":false,"in":"query","schema":{"type":"number"}},{"name":"cmcValue","required":false,"in":"query","schema":{"type":"number"}},{"name":"cmcOp","required":false,"in":"query","schema":{"enum":["eq","lt","lte","gt","gte","between"],"type":"string"}},{"name":"typesLogic","required":false,"in":"query","schema":{"enum":["and","or"],"type":"string"}},{"name":"typesMode","required":false,"in":"query","schema":{"enum":["with","without"],"type":"string"}},{"name":"types","required":false,"in":"query","description":"Comma-separated card types","schema":{"type":"string"}},{"name":"colorIdentityMode","required":false,"in":"query","schema":{"enum":["exact","include","at_most","identity"],"type":"string"}},{"name":"colorIdentity","required":false,"in":"query","schema":{"type":"string"}},{"name":"colorsMode","required":false,"in":"query","schema":{"enum":["exact","include","at_most","identity"],"type":"string"}},{"name":"colors","required":false,"in":"query","description":"Comma-separated colors","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Maximum results to return (default: 50, max: 100)","schema":{"type":"number"}},{"name":"includeInDecks","required":false,"in":"query","description":"Include cards that are in collection decks (default: false)","schema":{"type":"boolean"}},{"name":"q","required":false,"in":"query","description":"Search query (min 2 characters). Optional when advanced attribute filters are supplied.","schema":{"type":"string"}}],"responses":{"200":{"description":"Search results returned successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"name":{"type":"string"},"setCode":{"type":"string"},"setName":{"type":"string"},"collectorNumber":{"type":"string"},"quantity":{"type":"integer"},"totalQuantity":{"type":"integer"},"locationType":{"type":"string"},"locationName":{"type":"string","nullable":true},"foil":{"type":"boolean"},"condition":{"type":"string"},"language":{"type":"string"}},"additionalProperties":true}},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid search query"},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Collection not found"}},"security":[{"apiKey":[]},{"oauth2":["collection:read"]}],"summary":"Search cards in a collection by name","tags":["Collections"]}},"/collections/{id}/cards":{"get":{"operationId":"CollectionsController_findCards","parameters":[{"name":"id","required":true,"in":"path","description":"Collection ID","schema":{"type":"string"}},{"name":"maxPrice","required":false,"in":"query","schema":{"type":"number"}},{"name":"minPrice","required":false,"in":"query","schema":{"type":"number"}},{"name":"maxQuantity","required":false,"in":"query","schema":{"type":"number"}},{"name":"minQuantity","required":false,"in":"query","schema":{"type":"number"}},{"name":"language","required":false,"in":"query","schema":{"type":"string"}},{"name":"condition","required":false,"in":"query","schema":{"enum":["MINT","NEAR_MINT","EXCELLENT","GOOD","LIGHT_PLAYED","PLAYED","POOR"],"type":"string"}},{"name":"foil","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"binderId","required":false,"in":"query","schema":{"type":"string"}},{"name":"search","required":false,"in":"query","schema":{"type":"string"}},{"name":"sortOrder","required":false,"in":"query","schema":{"enum":["asc","desc"],"type":"string"}},{"name":"sortBy","required":false,"in":"query","schema":{"enum":["name","addedAt","updatedAt","quantity","condition","purchasePrice","value"],"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"Cards retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer"},"foil":{"type":"boolean"},"condition":{"type":"string"},"language":{"type":"string"},"purchasePrice":{"type":"number","nullable":true},"purchaseCurrency":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"binderId":{"type":"string","format":"uuid","nullable":true},"isProxy":{"type":"boolean"},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"binderName":{"type":"string","nullable":true},"deckId":{"type":"string","format":"uuid","nullable":true},"deckName":{"type":"string","nullable":true},"name":{"type":"string"},"setCode":{"type":"string"},"setName":{"type":"string"},"collectorNumber":{"type":"string"},"rarity":{"type":"string"},"typeLine":{"type":"string"},"manaCost":{"type":"string","nullable":true},"colorIdentity":{"type":"array","items":{"type":"string"}},"prices":{"type":"object","properties":{"usd":{"type":"number","nullable":true},"usdFoil":{"type":"number","nullable":true},"eur":{"type":"number","nullable":true},"eurFoil":{"type":"number","nullable":true}},"additionalProperties":true}},"additionalProperties":true}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"},"hasNextPage":{"type":"boolean"},"nextCursor":{"type":"string","nullable":true}},"additionalProperties":true}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Collection not found"}},"security":[{"apiKey":[]},{"oauth2":["collection:read"]}],"summary":"List cards in a collection with pagination and filters","tags":["Collections"],"description":"Required scope: `collection:read`."},"post":{"operationId":"CollectionsController_addCard","parameters":[{"name":"id","required":true,"in":"path","description":"Collection ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["scryfallId"],"properties":{"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer","minimum":1,"default":1},"foil":{"type":"boolean","default":false},"condition":{"type":"string","enum":["MINT","NEAR_MINT","EXCELLENT","GOOD","LIGHT_PLAYED","PLAYED","POOR"],"default":"NEAR_MINT"},"language":{"type":"string","default":"en"},"purchasePrice":{"type":"number","nullable":true},"purchaseDate":{"type":"string","format":"date-time","nullable":true},"notes":{"type":"string","maxLength":1000,"nullable":true},"location":{"type":"string","maxLength":200,"nullable":true},"binderId":{"type":"string","format":"uuid","nullable":true}}}}}},"responses":{"201":{"description":"Card added successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer"},"foil":{"type":"boolean"},"condition":{"type":"string"},"language":{"type":"string"},"purchasePrice":{"type":"number","nullable":true},"purchaseCurrency":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"binderId":{"type":"string","format":"uuid","nullable":true},"isProxy":{"type":"boolean"},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Collection or binder not found"}},"security":[{"apiKey":[]},{"oauth2":["collection:write"]}],"summary":"Add a card to a collection","tags":["Collections"],"description":"Required scope: `collection:write`."}},"/collections/{id}/cards/bulk":{"post":{"operationId":"CollectionsController_addCardsBulk","parameters":[{"name":"id","required":true,"in":"path","description":"Collection ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["cards"],"properties":{"cards":{"type":"array","items":{"type":"object","required":["scryfallId"],"properties":{"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer","minimum":1,"default":1},"foil":{"type":"boolean","default":false},"condition":{"type":"string","enum":["MINT","NEAR_MINT","EXCELLENT","GOOD","LIGHT_PLAYED","PLAYED","POOR"],"default":"NEAR_MINT"},"language":{"type":"string","default":"en"},"purchasePrice":{"type":"number","nullable":true},"purchaseDate":{"type":"string","format":"date-time","nullable":true},"notes":{"type":"string","maxLength":1000,"nullable":true},"location":{"type":"string","maxLength":200,"nullable":true},"binderId":{"type":"string","format":"uuid","nullable":true}}},"minItems":1,"maxItems":1000}}}}}},"responses":{"201":{"description":"Cards added successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"added":{"type":"integer"},"updated":{"type":"integer"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Collection or binder not found"}},"security":[{"apiKey":[]},{"oauth2":["collection:write"]}],"summary":"Bulk add cards to a collection","tags":["Collections"],"description":"Required scope: `collection:write`."}},"/collections/{id}/cards/{cardId}":{"patch":{"operationId":"CollectionsController_updateCard","parameters":[{"name":"id","required":true,"in":"path","description":"Collection ID","schema":{"type":"string"}},{"name":"cardId","required":true,"in":"path","description":"Card ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quantity":{"type":"integer","minimum":1},"foil":{"type":"boolean"},"condition":{"type":"string","enum":["MINT","NEAR_MINT","EXCELLENT","GOOD","LIGHT_PLAYED","PLAYED","POOR"]},"language":{"type":"string"},"purchasePrice":{"type":"number","nullable":true},"purchaseDate":{"type":"string","format":"date-time","nullable":true},"notes":{"type":"string","maxLength":1000,"nullable":true},"location":{"type":"string","maxLength":200,"nullable":true},"binderId":{"type":"string","format":"uuid","nullable":true}}}}}},"responses":{"200":{"description":"Card updated successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer"},"foil":{"type":"boolean"},"condition":{"type":"string"},"language":{"type":"string"},"purchasePrice":{"type":"number","nullable":true},"purchaseCurrency":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"binderId":{"type":"string","format":"uuid","nullable":true},"isProxy":{"type":"boolean"},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Collection or card not found"},"409":{"description":"Card variant already exists"}},"security":[{"apiKey":[]},{"oauth2":["collection:write"]}],"summary":"Update a card in a collection","tags":["Collections"],"description":"Required scope: `collection:write`."}},"/wishlists":{"get":{"operationId":"WishlistsController_listWishlists","parameters":[{"name":"containsCardName","required":false,"in":"query","description":"Only lists holding a card whose name matches (min 2 chars)","schema":{"type":"string"}}],"responses":{"200":{"description":"Wishlists retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"priority":{"type":"string"},"targetBudget":{"type":"number","nullable":true},"budgetCurrency":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"cardCount":{"type":"integer"},"totalValue":{"type":"number"},"valueCurrency":{"type":"string"}},"additionalProperties":true}},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized"}},"security":[{"apiKey":[]},{"oauth2":["wishlist:read"]}],"summary":"List all wishlists for the current user","tags":["Wishlists"],"description":"Required scope: `wishlist:read`."},"post":{"operationId":"WishlistsController_createWishlist","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":100},"description":{"type":"string","maxLength":500,"nullable":true},"priority":{"type":"integer","minimum":0,"default":0},"targetBudget":{"type":"number","minimum":0,"nullable":true},"budgetCurrency":{"type":"string","enum":["USD","EUR"],"nullable":true},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","nullable":true,"description":"Hex color code"},"coverCardId":{"type":"string","format":"uuid","nullable":true,"description":"Scryfall ID for cover image"}}}}}},"responses":{"201":{"description":"Wishlist created successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"priority":{"type":"string"},"targetBudget":{"type":"number","nullable":true},"budgetCurrency":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"409":{"description":"Wishlist name already exists"}},"security":[{"apiKey":[]},{"oauth2":["wishlist:write"]}],"summary":"Create a new wishlist","tags":["Wishlists"],"description":"Required scope: `wishlist:write`."}},"/wishlists/{id}":{"get":{"operationId":"WishlistsController_getWishlist","parameters":[{"name":"id","required":true,"in":"path","description":"Wishlist ID","schema":{"type":"string"}},{"name":"countProxies","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Wishlist retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"priority":{"type":"string"},"targetBudget":{"type":"number","nullable":true},"budgetCurrency":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"cards":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"wishlistId":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"language":{"type":"string"},"quantity":{"type":"integer"},"foil":{"type":"boolean"},"targetPrice":{"type":"number","nullable":true},"currency":{"type":"string","nullable":true},"priority":{"type":"string"},"notes":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}},"cardCount":{"type":"integer"},"totalCurrentValue":{"type":"number"},"totalTargetValue":{"type":"number","nullable":true}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Wishlist not found"}},"security":[{"apiKey":[]},{"oauth2":["wishlist:read"]}],"summary":"Get a wishlist with cards and current prices","tags":["Wishlists"],"description":"Required scope: `wishlist:read`."},"patch":{"operationId":"WishlistsController_updateWishlist","parameters":[{"name":"id","required":true,"in":"path","description":"Wishlist ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":100},"description":{"type":"string","maxLength":500,"nullable":true},"priority":{"type":"integer","minimum":0},"targetBudget":{"type":"number","minimum":0,"nullable":true},"budgetCurrency":{"type":"string","enum":["USD","EUR"],"nullable":true},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","nullable":true,"description":"Hex color code"},"coverCardId":{"type":"string","format":"uuid","nullable":true,"description":"Scryfall ID for cover image"}}}}}},"responses":{"200":{"description":"Wishlist updated successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"priority":{"type":"string"},"targetBudget":{"type":"number","nullable":true},"budgetCurrency":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Wishlist not found"},"409":{"description":"Wishlist name already exists"}},"security":[{"apiKey":[]},{"oauth2":["wishlist:write"]}],"summary":"Update a wishlist","tags":["Wishlists"],"description":"Required scope: `wishlist:write`."}},"/wishlists/{id}/cards":{"get":{"operationId":"WishlistsController_getWishlistCards","parameters":[{"name":"id","required":true,"in":"path","description":"Wishlist ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Cards retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"wishlistId":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"language":{"type":"string"},"quantity":{"type":"integer"},"foil":{"type":"boolean"},"targetPrice":{"type":"number","nullable":true},"currency":{"type":"string","nullable":true},"priority":{"type":"string"},"notes":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"cardData":{"type":"object","properties":{},"additionalProperties":true},"currentPrice":{"type":"number","nullable":true},"priceDifference":{"type":"number","nullable":true},"pricePercentDiff":{"type":"number","nullable":true}},"additionalProperties":true}},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Wishlist not found"}},"security":[{"apiKey":[]},{"oauth2":["wishlist:read"]}],"summary":"Get cards in a wishlist with current prices","tags":["Wishlists"],"description":"Required scope: `wishlist:read`."},"post":{"operationId":"WishlistsController_addCardToWishlist","parameters":[{"name":"id","required":true,"in":"path","description":"Wishlist ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["scryfallId"],"properties":{"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer","minimum":1,"default":1},"foil":{"type":"boolean","default":false},"targetPrice":{"type":"number","minimum":0,"nullable":true},"currency":{"type":"string","enum":["USD","EUR"],"nullable":true},"priority":{"type":"integer","minimum":0,"default":0},"notes":{"type":"string","maxLength":500,"nullable":true}}}}}},"responses":{"201":{"description":"Card added to wishlist successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"wishlistId":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"language":{"type":"string"},"quantity":{"type":"integer"},"foil":{"type":"boolean"},"targetPrice":{"type":"number","nullable":true},"currency":{"type":"string","nullable":true},"priority":{"type":"string"},"notes":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Wishlist not found"},"409":{"description":"Card already in wishlist"}},"security":[{"apiKey":[]},{"oauth2":["wishlist:write"]}],"summary":"Add a card to a wishlist","tags":["Wishlists"],"description":"Required scope: `wishlist:write`."}},"/wishlists/{id}/cards/{cardId}":{"patch":{"operationId":"WishlistsController_updateWishlistCard","parameters":[{"name":"id","required":true,"in":"path","description":"Wishlist ID","schema":{"type":"string"}},{"name":"cardId","required":true,"in":"path","description":"Wishlist Card ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer","minimum":1},"foil":{"type":"boolean"},"targetPrice":{"type":"number","minimum":0,"nullable":true},"currency":{"type":"string","enum":["USD","EUR"],"nullable":true},"priority":{"type":"integer","minimum":0},"notes":{"type":"string","maxLength":500,"nullable":true}}}}}},"responses":{"200":{"description":"Card updated successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"wishlistId":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"language":{"type":"string"},"quantity":{"type":"integer"},"foil":{"type":"boolean"},"targetPrice":{"type":"number","nullable":true},"currency":{"type":"string","nullable":true},"priority":{"type":"string"},"notes":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"403":{"description":"Access denied"},"404":{"description":"Wishlist or card not found"}},"security":[{"apiKey":[]},{"oauth2":["wishlist:write"]}],"summary":"Update a card in a wishlist","tags":["Wishlists"],"description":"Required scope: `wishlist:write`."}},"/cards/search":{"get":{"description":"Search for cards with various filters. Results are paginated.\n\nRequired scope: `cards:read`.","operationId":"CardsController_searchCards","parameters":[{"name":"q","required":false,"in":"query","description":"Search query string","schema":{"type":"string"}},{"name":"colors","required":false,"in":"query","description":"Filter by colors (e.g., \"WU\", \"BRG\")","schema":{"type":"string"}},{"name":"colorIdentity","required":false,"in":"query","description":"Filter by color identity","schema":{"type":"string"}},{"name":"type","required":false,"in":"query","description":"Filter by type line","schema":{"type":"string"}},{"name":"rarity","required":false,"in":"query","description":"Filter by rarity","schema":{"type":"string","enum":["common","uncommon","rare","mythic"]}},{"name":"set","required":false,"in":"query","description":"Filter by set code","schema":{"type":"string"}},{"name":"format","required":false,"in":"query","description":"Filter by format legality","schema":{"type":"string"}},{"name":"cmc","required":false,"in":"query","description":"Filter by converted mana cost","schema":{"type":"string"}},{"name":"sort","required":false,"in":"query","schema":{"type":"string","enum":["name","cmc","price","edhrec","released","rarity","priceChange","collector_number"]}},{"name":"order","required":false,"in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"cursor","required":false,"in":"query","description":"Cursor for keyset pagination (from nextCursor in previous response)","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Results per page","schema":{"default":20,"type":"number"}},{"name":"isToken","required":false,"in":"query","description":"Include tokens","schema":{"type":"boolean"}},{"name":"isEmblem","required":false,"in":"query","description":"Include emblems","schema":{"type":"boolean"}},{"name":"excludeDigital","required":false,"in":"query","description":"Exclude digital-only cards","schema":{"type":"boolean"}},{"name":"excludeTokens","required":false,"in":"query","description":"Exclude token/emblem cards (omitted behaves like true)","schema":{"type":"boolean"}},{"name":"excludePromos","required":false,"in":"query","description":"Exclude printings from promo sets","schema":{"type":"boolean"}},{"name":"excludeArtSeries","required":false,"in":"query","description":"Exclude art series cards","schema":{"type":"boolean"}},{"name":"excludeOversized","required":false,"in":"query","description":"Exclude oversized / minigame cards","schema":{"type":"boolean"}},{"name":"fields","required":false,"in":"query","description":"Response projection. \"lean\" omits fields no browse client maps (purchaseUris, legalities, oracleText, flavorText, scryfallUpdatedAt), roughly halving the payload. Omit for the full response.","schema":{"type":"string","enum":["lean"]}},{"name":"releasedBefore","required":false,"in":"query","description":"Only cards released before this ISO date","schema":{"type":"string"}},{"name":"releasedAfter","required":false,"in":"query","description":"Only cards released after this ISO date","schema":{"type":"string"}},{"name":"producedMana","required":false,"in":"query","description":"Filter to cards producing ANY of these colours","schema":{"example":["W","B"],"type":"array","items":{"type":"string"}}},{"name":"priceChangePeriod","required":false,"in":"query","description":"Period for priceChange sort","schema":{"type":"string","enum":["7d","30d","90d"]}},{"name":"priceSource","required":false,"in":"query","description":"Price source for price/priceChange sort (defaults to TCGPLAYER)","schema":{"type":"string","enum":["TCGPLAYER","CARDMARKET"]}},{"name":"priceCurrency","required":false,"in":"query","description":"Currency for price/priceChange sort (defaults to USD)","schema":{"type":"string","enum":["USD","EUR","GBP","CAD","AUD","NZD","JPY","CHF","SEK","NOK","DKK","PLN","MXN","BRL","CNY","KRW","SGD","HKD"]}},{"name":"priceChangeSortBy","required":false,"in":"query","description":"Sort metric for priceChange sort","schema":{"type":"string","enum":["percent","absolute"]}}],"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchCardsResponseDto"}}}}},"security":[{"apiKey":[]},{"oauth2":["cards:read"]}],"summary":"Search cards","tags":["Cards"]}},"/cards/autocomplete":{"get":{"description":"Returns card name suggestions based on partial input.\n\nRequired scope: `cards:read`.","operationId":"CardsController_autocomplete","parameters":[{"name":"q","required":true,"in":"query","description":"Search query (min 2 characters)","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Maximum number of suggestions","schema":{"default":10,"type":"number"}},{"name":"excludeDigital","required":false,"in":"query","description":"Exclude digital-only cards (arena/mtgo only)","schema":{"type":"boolean"}},{"name":"excludeTokens","required":false,"in":"query","description":"Exclude token/emblem cards (omitted behaves like true)","schema":{"type":"boolean"}},{"name":"excludeOversized","required":false,"in":"query","description":"Exclude oversized / minigame cards","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Autocomplete suggestions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutocompleteResponseDto"}}}}},"security":[{"apiKey":[]},{"oauth2":["cards:read"]}],"summary":"Autocomplete card names","tags":["Cards"]}},"/cards/name/{name}":{"get":{"description":"Retrieves a card by its name using fuzzy matching.\n\nRequired scope: `cards:read`.","operationId":"CardsController_getCardByName","parameters":[{"name":"name","required":true,"in":"path","description":"Card name","schema":{"type":"string"}}],"responses":{"200":{"description":"Card found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardResponseDto"}}}},"404":{"description":"Card not found"}},"security":[{"apiKey":[]},{"oauth2":["cards:read"]}],"summary":"Get card by name","tags":["Cards"]}},"/cards/batch":{"post":{"description":"Retrieves multiple cards by Scryfall IDs or Oracle IDs.\n\nRequired scope: `cards:read`.","operationId":"CardsController_getCardsBatch","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCardsDto"}}}},"responses":{"200":{"description":"Cards found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCardsResponseDto"}}}}},"security":[{"apiKey":[]},{"oauth2":["cards:read"]}],"summary":"Get multiple cards by IDs","tags":["Cards"]}},"/cards/{id}/prints":{"get":{"description":"Retrieves all printings of a card by its Oracle ID.\n\nRequired scope: `cards:read`.","operationId":"CardsController_getCardPrints","parameters":[{"name":"id","required":true,"in":"path","description":"Oracle ID of the card","schema":{"type":"string"}},{"name":"language","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Prints found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardPrintsResponseDto"}}}}},"security":[{"apiKey":[]},{"oauth2":["cards:read"]}],"summary":"Get all prints for a card","tags":["Cards"]}},"/cards/{id}/rulings":{"get":{"description":"Retrieves official rulings for a card by its Scryfall ID.\n\nRequired scope: `cards:read`.","operationId":"CardsController_getCardRulings","parameters":[{"name":"id","required":true,"in":"path","description":"Scryfall ID of the card","schema":{"type":"string"}}],"responses":{"200":{"description":"Rulings found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardRulingsResponseDto"}}}}},"security":[{"apiKey":[]},{"oauth2":["cards:read"]}],"summary":"Get rulings for a card","tags":["Cards"]}},"/cards/mtg-sets":{"get":{"description":"Returns rich set data from Scryfall cache. Public endpoint for SEO.\n\nRequired scope: `cards:read`.","operationId":"CardsController_getMtgSets","parameters":[{"name":"offset","required":false,"in":"query","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"excludeDigital","required":false,"in":"query","description":"Exclude digital-only sets","schema":{}},{"name":"setType","required":false,"in":"query","description":"Filter by set type","schema":{}},{"name":"search","required":false,"in":"query","description":"Filter by set name or code","schema":{}}],"responses":{"200":{"description":"List of MTG sets","content":{"application/json":{"schema":{"type":"object","properties":{"sets":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"setType":{"type":"string"},"releasedAt":{"type":"string"},"cardCount":{"type":"integer"},"digital":{"type":"boolean"},"iconSvgUri":{"type":"string"}},"additionalProperties":true}},"total":{"type":"integer"}},"additionalProperties":true}}}}},"security":[{"apiKey":[]},{"oauth2":["cards:read"]}],"summary":"Get MTG sets (public)","tags":["Cards"]}},"/cards/mtg-sets/{code}":{"get":{"description":"Returns a single set by code.\n\nRequired scope: `cards:read`.","operationId":"CardsController_getMtgSetByCode","parameters":[{"name":"code","required":true,"in":"path","description":"Set code (e.g., \"dom\")","schema":{"type":"string"}}],"responses":{"200":{"description":"Set details","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"setType":{"type":"string"},"releasedAt":{"type":"string"},"cardCount":{"type":"integer"},"digital":{"type":"boolean"},"iconSvgUri":{"type":"string"}},"additionalProperties":true}}}},"404":{"description":"Set not found"}},"security":[{"apiKey":[]},{"oauth2":["cards:read"]}],"summary":"Get MTG set by code (public)","tags":["Cards"]}},"/cards/{id}":{"get":{"description":"Retrieves a card by its Scryfall UUID.\n\nRequired scope: `cards:read`.","operationId":"CardsController_getCardById","parameters":[{"name":"id","required":true,"in":"path","description":"Scryfall card UUID","schema":{"type":"string"}}],"responses":{"200":{"description":"Card found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardResponseDto"}}}},"404":{"description":"Card not found"}},"security":[{"apiKey":[]},{"oauth2":["cards:read"]}],"summary":"Get card by Scryfall ID","tags":["Cards"]}},"/decks":{"get":{"operationId":"DecksController_listDecks","parameters":[{"name":"sortOrder","required":false,"in":"query","schema":{"type":"string"}},{"name":"sortBy","required":false,"in":"query","schema":{"type":"string"}},{"name":"containsCardName","required":false,"in":"query","description":"Filter decks containing a card whose name matches (min 2 chars)","schema":{"type":"string"}},{"name":"containsCard","required":false,"in":"query","description":"Filter decks containing a card by oracle/scryfall ID","schema":{"type":"string"}},{"name":"isArchived","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"search","required":false,"in":"query","schema":{"type":"string"}},{"name":"visibility","required":false,"in":"query","schema":{"type":"string"}},{"name":"format","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"List of decks","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"format":{"type":"string"},"commanderIds":{"type":"array","items":{"type":"string"}},"colorIdentity":{"type":"array","items":{"type":"string"}},"cardCount":{"type":"integer"},"mainboardCount":{"type":"integer"},"sideboardCount":{"type":"integer"},"maybeboardCount":{"type":"integer"},"visibility":{"type":"string"},"bracket":{"type":"integer","nullable":true},"powerLevel":{"type":"number","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"},"hasNextPage":{"type":"boolean"},"nextCursor":{"type":"string","nullable":true}},"additionalProperties":true}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized"}},"security":[{"apiKey":[]},{"oauth2":["decks:read"]}],"summary":"List user decks with filtering","tags":["Decks"],"description":"Required scope: `decks:read`."},"post":{"operationId":"DecksController_createDeck","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","maxLength":1000,"nullable":true},"shortDescription":{"type":"string","maxLength":500,"nullable":true},"format":{"type":"string","enum":["STANDARD","PIONEER","MODERN","LEGACY","VINTAGE","COMMANDER","PAUPER","BRAWL","HISTORIC","ALCHEMY","EXPLORER","TIMELESS","OATHBREAKER","PREMODERN","PENNY","DUEL","OLDSCHOOL","CASUAL"],"default":"CASUAL"},"commanderIds":{"type":"array","items":{"type":"string","format":"uuid"},"default":[]},"visibility":{"type":"string","enum":["PUBLIC","FRIENDS","PRIVATE","LINK_ONLY"],"default":"PRIVATE"},"bracket":{"type":"integer","minimum":1,"exclusiveMinimum":false,"maximum":5,"exclusiveMaximum":false,"nullable":true},"coverCardId":{"type":"string","format":"uuid","nullable":true},"ideaFolderId":{"type":"string","format":"uuid","nullable":true}},"required":["name","description","shortDescription","bracket","coverCardId","ideaFolderId"]}}}},"responses":{"201":{"description":"Deck created successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"format":{"type":"string"},"commanderIds":{"type":"array","items":{"type":"string"}},"colorIdentity":{"type":"array","items":{"type":"string"}},"cardCount":{"type":"integer"},"mainboardCount":{"type":"integer"},"sideboardCount":{"type":"integer"},"maybeboardCount":{"type":"integer"},"visibility":{"type":"string"},"bracket":{"type":"integer","nullable":true},"powerLevel":{"type":"number","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"}},"security":[{"apiKey":[]},{"oauth2":["decks:write"]}],"summary":"Create a new deck","tags":["Decks"],"description":"Required scope: `decks:write`."}},"/decks/public":{"get":{"operationId":"DecksController_listPublicDecks","parameters":[{"name":"cursor","required":false,"in":"query","description":"Cursor for keyset pagination","schema":{"type":"string"}},{"name":"sortOrder","required":false,"in":"query","schema":{"enum":["asc","desc"],"type":"string"}},{"name":"sortBy","required":false,"in":"query","schema":{"enum":["newest","popular","updated","likes"],"type":"string"}},{"name":"search","required":false,"in":"query","schema":{"type":"string"}},{"name":"commander","required":false,"in":"query","schema":{"type":"string"}},{"name":"colors","required":false,"in":"query","description":"Color identity filter (W, U, B, R, G)","schema":{"type":"array","items":{"type":"string"}}},{"name":"format","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"Paginated list of public decks","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"format":{"type":"string"},"commanderIds":{"type":"array","items":{"type":"string"}},"colorIdentity":{"type":"array","items":{"type":"string"}},"cardCount":{"type":"integer"},"powerLevel":{"type":"number","nullable":true},"likeCount":{"type":"integer"},"author":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"username":{"type":"string"}},"additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"},"hasNextPage":{"type":"boolean"},"nextCursor":{"type":"string","nullable":true}},"additionalProperties":true}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}}},"security":[{"apiKey":[]},{"oauth2":["decks:read"]}],"summary":"List public decks with filtering and sorting","tags":["Decks"],"description":"Required scope: `decks:read`."}},"/decks/public/{id}":{"get":{"operationId":"DecksController_getPublicDeck","parameters":[{"name":"id","required":true,"in":"path","description":"Deck ID","schema":{"type":"string"}},{"name":"enrichCards","required":false,"in":"query","description":"Include full card data from card-cache-server","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Public deck details with cards","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"format":{"type":"string"},"commanderIds":{"type":"array","items":{"type":"string"}},"colorIdentity":{"type":"array","items":{"type":"string"}},"cardCount":{"type":"integer"},"mainboardCount":{"type":"integer"},"sideboardCount":{"type":"integer"},"maybeboardCount":{"type":"integer"},"visibility":{"type":"string"},"bracket":{"type":"integer","nullable":true},"powerLevel":{"type":"number","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"cards":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer"},"board":{"type":"string","example":"mainboard"},"categories":{"type":"array","items":{"type":"string"}},"notes":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Deck not found or not public"}},"security":[{"apiKey":[]},{"oauth2":["decks:read"]}],"summary":"Get a public deck by ID with full details","tags":["Decks"],"description":"Required scope: `decks:read`."}},"/decks/{id}":{"get":{"operationId":"DecksController_getDeck","parameters":[{"name":"id","required":true,"in":"path","description":"Deck ID","schema":{"type":"string"}},{"name":"includeCards","required":false,"in":"query","description":"Include cards in response","schema":{"type":"boolean"}},{"name":"includeStats","required":false,"in":"query","description":"Include computed stats","schema":{"type":"boolean"}},{"name":"includeTokens","required":false,"in":"query","description":"Include generated tokens","schema":{"type":"boolean"}},{"name":"enrichCards","required":false,"in":"query","description":"PERF-02: Include full card data from card-cache-server (eliminates frontend fetch)","schema":{"type":"boolean"}},{"name":"editMode","required":false,"in":"query","description":"PERF-14: Slim enrichment mode — omits heavy fields (legalities, oracleText) not needed for editing","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Deck details with cards","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"format":{"type":"string"},"commanderIds":{"type":"array","items":{"type":"string"}},"colorIdentity":{"type":"array","items":{"type":"string"}},"cardCount":{"type":"integer"},"mainboardCount":{"type":"integer"},"sideboardCount":{"type":"integer"},"maybeboardCount":{"type":"integer"},"visibility":{"type":"string"},"bracket":{"type":"integer","nullable":true},"powerLevel":{"type":"number","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"cards":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer"},"board":{"type":"string","example":"mainboard"},"categories":{"type":"array","items":{"type":"string"}},"notes":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Deck not found"}},"security":[{"apiKey":[]},{"oauth2":["decks:read"]}],"summary":"Get a deck with all cards","tags":["Decks"],"description":"Required scope: `decks:read`."},"patch":{"operationId":"DecksController_updateDeck","parameters":[{"name":"id","required":true,"in":"path","description":"Deck ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","maxLength":1000,"nullable":true},"shortDescription":{"type":"string","maxLength":500,"nullable":true},"primer":{"type":"string","nullable":true},"format":{"type":"string","enum":["STANDARD","PIONEER","MODERN","LEGACY","VINTAGE","COMMANDER","PAUPER","BRAWL","HISTORIC","ALCHEMY","EXPLORER","TIMELESS","OATHBREAKER","PREMODERN","PENNY","DUEL","OLDSCHOOL","CASUAL"]},"commanderIds":{"type":"array","items":{"type":"string","format":"uuid"}},"visibility":{"type":"string","enum":["PUBLIC","FRIENDS","PRIVATE","LINK_ONLY"]},"isFeatured":{"type":"boolean"},"isArchived":{"type":"boolean"},"bracket":{"type":"integer","minimum":1,"exclusiveMinimum":false,"maximum":5,"exclusiveMaximum":false,"nullable":true},"bracketOverride":{"type":"boolean"},"collectionFilter":{"type":"object","properties":{"onlyMissing":{"type":"boolean"},"matchExactPrint":{"type":"boolean"},"sourceType":{"type":"string","enum":["all","binders","decks"]},"selectedBinderIds":{"type":"array","items":{"type":"string"}},"selectedDeckIds":{"type":"array","items":{"type":"string"}}},"required":["onlyMissing","matchExactPrint","sourceType","selectedBinderIds","selectedDeckIds"],"nullable":true},"coverCardId":{"type":"string","format":"uuid","nullable":true},"showStats":{"type":"boolean"},"ideaFolderId":{"type":"string","format":"uuid","nullable":true},"includeInMissingWishlist":{"type":"boolean"}},"required":["description","shortDescription","primer","bracket","collectionFilter","coverCardId","ideaFolderId"]}}}},"responses":{"200":{"description":"Deck updated successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"format":{"type":"string"},"commanderIds":{"type":"array","items":{"type":"string"}},"colorIdentity":{"type":"array","items":{"type":"string"}},"cardCount":{"type":"integer"},"mainboardCount":{"type":"integer"},"sideboardCount":{"type":"integer"},"maybeboardCount":{"type":"integer"},"visibility":{"type":"string"},"bracket":{"type":"integer","nullable":true},"powerLevel":{"type":"number","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Deck not found"}},"security":[{"apiKey":[]},{"oauth2":["decks:write"]}],"summary":"Update deck metadata","tags":["Decks"],"description":"Required scope: `decks:write`."}},"/decks/{id}/validate":{"get":{"operationId":"DecksController_validateDeck","parameters":[{"name":"id","required":true,"in":"path","description":"Deck ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Validation result","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"isValid":{"type":"boolean"},"issues":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"}},"additionalProperties":true}},"stats":{"type":"object","properties":{"mainboardCount":{"type":"integer"},"sideboardCount":{"type":"integer"},"uniqueCards":{"type":"integer"},"totalCards":{"type":"integer"}},"additionalProperties":true}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Deck not found"}},"security":[{"apiKey":[]},{"oauth2":["decks:read"]}],"summary":"Validate deck against format rules","tags":["Decks"],"description":"Required scope: `decks:read`."}},"/decks/{id}/cards":{"post":{"operationId":"DecksController_addCard","parameters":[{"name":"id","required":true,"in":"path","description":"Deck ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer","minimum":1,"exclusiveMinimum":false,"maximum":99,"exclusiveMaximum":false,"default":1},"board":{"type":"string","enum":["mainboard","sideboard","maybeboard","considering","commander","companion"],"default":"mainboard"},"categories":{"type":"array","maxItems":10,"items":{"type":"string","maxLength":50},"default":[]},"notes":{"type":"string","maxLength":500,"nullable":true},"finish":{"type":"string","enum":["foil","etched","nonfoil"],"nullable":true}},"required":["scryfallId","printingId","notes"]}}}},"responses":{"201":{"description":"Card added successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer"},"board":{"type":"string","example":"mainboard"},"categories":{"type":"array","items":{"type":"string"}},"notes":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input or validation error"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Deck not found"},"409":{"description":"Card already exists in deck"}},"security":[{"apiKey":[]},{"oauth2":["decks:write"]}],"summary":"Add a card to a deck","tags":["Decks"],"description":"Required scope: `decks:write`."}},"/decks/{id}/cards/{cardId}":{"patch":{"operationId":"DecksController_updateCard","parameters":[{"name":"id","required":true,"in":"path","description":"Deck ID","schema":{"type":"string"}},{"name":"cardId","required":true,"in":"path","description":"Deck card ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quantity":{"type":"integer","minimum":1,"exclusiveMinimum":false,"maximum":99,"exclusiveMaximum":false},"board":{"type":"string","enum":["mainboard","sideboard","maybeboard","considering","commander","companion"]},"printingId":{"type":"string","format":"uuid","nullable":true},"categories":{"type":"array","maxItems":10,"items":{"type":"string","maxLength":50}},"notes":{"type":"string","maxLength":500,"nullable":true},"finish":{"type":"string","enum":["foil","etched","nonfoil"],"nullable":true}},"required":["printingId","notes"]}}}},"responses":{"200":{"description":"Card updated successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer"},"board":{"type":"string","example":"mainboard"},"categories":{"type":"array","items":{"type":"string"}},"notes":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Deck or card not found"}},"security":[{"apiKey":[]},{"oauth2":["decks:write"]}],"summary":"Update a card in a deck","tags":["Decks"],"description":"Required scope: `decks:write`."}},"/decks/{id}/cards/bulk":{"post":{"operationId":"DecksController_addCardsBulk","parameters":[{"name":"id","required":true,"in":"path","description":"Deck ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"cards":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","properties":{"scryfallId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1},"quantity":{"type":"integer","minimum":1,"exclusiveMinimum":false,"maximum":99,"exclusiveMaximum":false,"default":1},"board":{"type":"string","enum":["mainboard","sideboard","maybeboard","considering","commander","companion"],"default":"mainboard"},"setCode":{"type":"string","maxLength":10,"nullable":true},"collectorNumber":{"type":"string","maxLength":10,"nullable":true},"foil":{"type":"boolean","default":false}},"required":["name","setCode","collectorNumber"]}},"skipUnrecognized":{"type":"boolean","default":false},"matchPreference":{"type":"string","enum":["exact","latest","cheapest"],"default":"latest"},"preferCollectionPrintings":{"type":"boolean","default":false},"collectionId":{"type":"string","format":"uuid","nullable":true},"excludeDecks":{"type":"boolean","default":true},"provider":{"type":"string"},"tier":{"type":"string"}},"required":["cards","collectionId"]}}}},"responses":{"201":{"description":"Cards added successfully","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"addedCards":{"type":"integer"},"skippedCards":{"type":"integer"},"errors":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"message":{"type":"string"}},"additionalProperties":true}},"cards":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scryfallId":{"type":"string","format":"uuid"},"printingId":{"type":"string","format":"uuid","nullable":true},"quantity":{"type":"integer"},"board":{"type":"string","example":"mainboard"},"categories":{"type":"array","items":{"type":"string"}},"notes":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"additionalProperties":true},"timestamp":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid input"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Deck not found"}},"security":[{"apiKey":[]},{"oauth2":["decks:write"]}],"summary":"Add multiple cards to a deck at once","tags":["Decks"],"description":"Required scope: `decks:write`."}},"/decks/{id}/categories":{"get":{"operationId":"DecksController_getCategories","parameters":[{"name":"id","required":true,"in":"path","description":"Deck ID","schema":{"type":"string"}}],"responses":{"200":{"description":"List of categories","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deckId":{"type":"string","format":"uuid"},"name":{"type":"string"},"color":{"type":"string","nullable":true},"sortOrder":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}},"timestamp":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Deck not found"}},"security":[{"apiKey":[]},{"oauth2":["decks:read"]}],"summary":"Get all categories for a deck","tags":["Decks"],"description":"Required scope: `decks:read`."}}},"info":{"title":"Grimoria API","description":"Read and manage a Grimoria user's Magic: The Gathering collection, decks and wishlists, and look up card data. Authenticate with a personal API key or an OAuth 2.1 access token (authorization code + PKCE). Guide: https://grimoria.app/developers","version":"1.0","contact":{"name":"Grimoria","url":"https://grimoria.app/developers","email":""}},"tags":[{"name":"Cards"},{"name":"Collections"},{"name":"Decks"},{"name":"Wishlists"}],"servers":[{"url":"https://grimoria.app/api/v1"}],"components":{"securitySchemes":{"apiKey":{"scheme":"bearer","bearerFormat":"gma_…","type":"http","description":"Personal API key or OAuth access token, sent as `Authorization: Bearer gma_…`."},"oauth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://grimoria.app/oauth/authorize","tokenUrl":"https://grimoria.app/api/v1/oauth/token","refreshUrl":"https://grimoria.app/api/v1/oauth/token","scopes":{"cards:read":"Read card and set data","collection:read":"Read the user's collections and the cards in them","collection:write":"Add and edit cards in the user's collections","decks:read":"Read the user's decks and public decks","decks:write":"Create decks and add or edit their cards","wishlist:read":"Read the user's wishlists","wishlist:write":"Create wishlists and add or edit their cards"}}},"description":"Authorization code flow with PKCE (S256 only)."}},"schemas":{"AutocompleteResponseDto":{"type":"object","properties":{"suggestions":{"type":"array","items":{"$ref":"#/components/schemas/AutocompleteSuggestion"}}},"required":["suggestions"]},"AutocompleteSuggestion":{"type":"object","properties":{"name":{"type":"string"},"oracleId":{"type":"string"},"scryfallId":{"type":"string"},"setCode":{"type":"string"}},"required":["name","oracleId"]},"BatchCardsDto":{"type":"object","properties":{"scryfallIds":{"description":"Array of Scryfall IDs","type":"array","items":{"type":"string"}},"oracleIds":{"description":"Array of Oracle IDs","type":"array","items":{"type":"string"}}}},"BatchCardsResponseDto":{"type":"object","properties":{"cards":{"type":"array","items":{"$ref":"#/components/schemas/CardResponseDto"}},"notFound":{"type":"array","items":{"type":"string"}}},"required":["cards","notFound"]},"CardAllPricesDto":{"type":"object","properties":{"providers":{"type":"array","items":{"$ref":"#/components/schemas/CardAllPricesProviderDto"}}},"required":["providers"]},"CardAllPricesProviderDto":{"type":"object","properties":{"provider":{"type":"string"},"currency":{"type":"string"},"tiers":{"type":"object","description":"Prices keyed by tier (e.g. \"market\", \"low\", \"average\", \"trend\")"}},"required":["provider","currency","tiers"]},"CardPricesDto":{"type":"object","properties":{"usd":{"type":"number"},"usdFoil":{"type":"number"},"eur":{"type":"number"},"eurFoil":{"type":"number"}}},"CardPrintDto":{"type":"object","properties":{"scryfallId":{"type":"string"},"setCode":{"type":"string"},"setName":{"type":"string"},"collectorNumber":{"type":"string"},"rarity":{"type":"string"},"setType":{"type":"string"},"layout":{"type":"string"},"language":{"type":"string"},"releasedAt":{"type":"object"},"imageUris":{"type":"object"},"foilAvailable":{"type":"boolean"},"nonfoilAvailable":{"type":"boolean"},"finishes":{"type":"array","items":{"type":"string"}},"promoTypes":{"type":"array","items":{"type":"string"}},"prices":{"$ref":"#/components/schemas/CardPricesDto"},"allPrices":{"$ref":"#/components/schemas/CardAllPricesDto"}},"required":["scryfallId","setCode","setName","collectorNumber","rarity","language","foilAvailable","nonfoilAvailable"]},"CardPrintsResponseDto":{"type":"object","properties":{"prints":{"type":"array","items":{"$ref":"#/components/schemas/CardPrintDto"}}},"required":["prints"]},"CardResponseDto":{"type":"object","properties":{"id":{"type":"string"},"oracleId":{"type":"string"},"name":{"type":"string"},"manaCost":{"type":"string"},"cmc":{"type":"number"},"typeLine":{"type":"string"},"oracleText":{"type":"string"},"power":{"type":"string"},"toughness":{"type":"string"},"loyalty":{"type":"string"},"defense":{"type":"string"},"colors":{"type":"array","items":{"type":"string"}},"colorIdentity":{"type":"array","items":{"type":"string"}},"keywords":{"type":"array","items":{"type":"string"}},"legalities":{"type":"object"},"setCode":{"type":"string"},"setName":{"type":"string"},"collectorNumber":{"type":"string"},"rarity":{"type":"string"},"artist":{"type":"string","description":"Illustrator name"},"flavorName":{"type":"string"},"printedName":{"type":"string","description":"Localized printed name of a non-English printing"},"alternateNames":{"type":"string","description":"\" | \"-joined UB flavor / face alternate names of the oracle card"},"flavorText":{"type":"string"},"imageUri":{"type":"string"},"imageUris":{"type":"object"},"cardFaces":{"type":"array","items":{"type":"string"}},"layout":{"type":"string","description":"Scryfall layout (transform, adventure, split…)"},"prices":{"$ref":"#/components/schemas/CardPricesDto"},"edhrecRank":{"type":"number"},"isToken":{"type":"boolean"},"isEmblem":{"type":"boolean"},"isBasicLand":{"type":"boolean"},"reservedList":{"type":"boolean","description":"Whether the card is on the Reserved List"},"gameChanger":{"type":"boolean","description":"Whether the card is on the Commander Game Changers list"},"producedMana":{"description":"Colours this card can produce (mana-fixing); colourless \"C\" is filtered out","type":"array","items":{"type":"string"}},"promoTypes":{"description":"Scryfall promo_types of this printing (e.g. \"surgefoil\") — special foil treatments","type":"array","items":{"type":"string"}},"releasedAt":{"type":"string"},"scryfallUpdatedAt":{"type":"string"},"availableLanguages":{"type":"array","items":{"type":"string"}}},"required":["id","oracleId","name","cmc","typeLine","colors","colorIdentity","keywords","legalities","setCode","setName","collectorNumber","rarity","isToken","isEmblem","isBasicLand","scryfallUpdatedAt"]},"CardRulingDto":{"type":"object","properties":{"source":{"type":"string"},"published_at":{"type":"string"},"comment":{"type":"string"}},"required":["source","published_at","comment"]},"CardRulingsResponseDto":{"type":"object","properties":{"rulings":{"type":"array","items":{"$ref":"#/components/schemas/CardRulingDto"}}},"required":["rulings"]},"SearchCardsResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CardResponseDto"}},"meta":{"type":"object"}},"required":["data","meta"]}}}}