{"openapi":"3.1.0","info":{"title":"KeepUp","version":"1.0.0","description":"Read-only shop search for keepupcards.com. Use findShops when you need a trading card shop by city, state, game, or name, then open the returned shop url. Do not use this API for live prices, inventory, or checkout. No API key. No SDK. No MCP server."},"servers":[{"url":"https://www.keepupcards.com"}],"paths":{"/api/v1/shops":{"get":{"operationId":"findShops","summary":"Find trading card shops","description":"Find public KeepUp shop pages. Pass at least one of state, city, game, or q. Each call returns at most 20 shops. page starts at 1 and stops at 20. 60 calls per minute per client. Open the url field. Do not guess other /api/ paths.","parameters":[{"name":"state","in":"query","required":false,"description":"US state name or abbreviation, such as California or CA. Optional when city, game, or q is set.","schema":{"type":"string","minLength":2,"maxLength":100}},{"name":"city","in":"query","required":false,"description":"City name, such as Fresno. Pair it with state when you can.","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"game","in":"query","required":false,"description":"Trading card game name or address slug, such as Pokemon or pokemon.","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"q","in":"query","required":false,"description":"At least 2 characters from the shop name, its description, or its city, such as Gameland. Do not include commas or percent signs.","schema":{"type":"string","minLength":2,"maxLength":100}},{"name":"page","in":"query","required":false,"description":"Page number from 1 to 20. Each page has 20 shops. Omit it for page 1.","schema":{"type":"integer","minimum":1,"maximum":20,"default":1}}],"responses":{"200":{"description":"A page of matching shops. An empty shops array means nothing matched.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShopSearchResult"}}}},"400":{"description":"The query is missing a filter, q is shorter than 2 characters, page is not a whole number from 1 to 20, or a filter includes a comma or percent sign.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"state or game is not one KeepUp lists.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Only GET is allowed. There is no request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"More than 60 calls in a minute. Wait for Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"The search failed for a reason other than a timeout.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The shop list could not be read. Try the same call again.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"schemas":{"Problem":{"type":"object","description":"RFC 9457 problem document. code and resolution tell an agent what to change on the next call.","additionalProperties":false,"required":["type","title","status","detail","code","resolution"],"properties":{"type":{"type":"string","description":"Problem type URI. about:blank means the title and detail carry the meaning.","enum":["about:blank"]},"title":{"type":"string","description":"Short name of this error."},"status":{"type":"integer","description":"HTTP status code. Matches the response status."},"detail":{"type":"string","description":"What went wrong on this call."},"code":{"type":"string","description":"Stable machine code, such as missing_filter or unknown_state."},"resolution":{"type":"string","description":"What to change before calling again."},"instance":{"type":"string","description":"Request path that failed."}}},"Shop":{"type":"object","description":"One public shop. Open url for the full page. This object does not include email or phone.","additionalProperties":false,"required":["name","city","state","url","games","hasOnlineStore"],"properties":{"name":{"type":"string","description":"Shop name as shown on the public page."},"city":{"type":"string","description":"City name."},"state":{"type":"string","description":"State name or abbreviation stored for the shop."},"url":{"type":"string","format":"uri","description":"Public shop page on www.keepupcards.com. Open this. Do not build a different /api/ address."},"games":{"type":"array","description":"Games the shop lists.","items":{"type":"string"}},"hasOnlineStore":{"type":"boolean","description":"True when the shop says it sells online."}}},"ShopSearchResult":{"type":"object","description":"One page of findShops results.","additionalProperties":false,"required":["shops","page","pageSize","total"],"properties":{"shops":{"type":"array","description":"Shops on this page.","items":{"$ref":"#/components/schemas/Shop"}},"page":{"type":"integer","description":"Page you asked for, starting at 1."},"pageSize":{"type":"integer","description":"Maximum shops in shops. Always 20."},"total":{"type":"integer","description":"How many shops matched the filters, not just this page."}}}}}}