{"openapi":"3.1.0","info":{"title":"QoQa offers for AI agents","version":"1.0.0","description":"The live offers of QoQa, a Swiss flash-sale shop, and the content of each offer. Prices are in CHF. The MCP server https://mcp.qoqa.ch gives the same data."},"servers":[{"url":"https://api.qoqa.ch/v2/agents"}],"paths":{"/offers":{"get":{"operationId":"getCurrentOffers","summary":"List the live offers","parameters":[{"name":"locale","in":"query","required":false,"description":"The locale of the content.","schema":{"type":"string","enum":["fr","de"],"default":"fr"}}],"responses":{"200":{"description":"The live offers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentOffers"}}},"headers":{"Link":{"description":"The URL of the JSON Schema of the response, with rel=\"describedby\"","schema":{"type":"string"}}}},"400":{"description":"The locale is not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests from this IP address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"description":"The number of seconds to wait before the next request","schema":{"type":"integer"}}}}}}},"/offers/{id}":{"get":{"operationId":"getOfferContent","summary":"Show the content of one offer: prices, status, its products, and the description in Markdown","parameters":[{"name":"id","in":"path","required":true,"description":"The numeric id of the offer, from getCurrentOffers.","schema":{"type":"string","pattern":"^[0-9]+$"}},{"name":"locale","in":"query","required":false,"description":"The locale of the content. Use fr only if url_fr is not null in getCurrentOffers, and de only if url_de is not null.","schema":{"type":"string","enum":["fr","de"],"default":"fr"}}],"responses":{"200":{"description":"The content of the offer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferContent"}}},"headers":{"Link":{"description":"The URL of the JSON Schema of the response, with rel=\"describedby\"","schema":{"type":"string"}}}},"400":{"description":"The locale is not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The id is not valid, or the offer does not exist, is hidden, or is not sold in the locale","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests from this IP address","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"description":"The number of seconds to wait before the next request","schema":{"type":"integer"}}}}}}}},"components":{"schemas":{"CurrentOffers":{"$schema":"https://json-schema.org/draft/2020-12/schema","title":"QoQa current offers","description":"The offers that are live on QoQa at this time. QoQa sells each offer for a short time (flash sale). Prices are in CHF.","type":"object","required":["offers","count"],"properties":{"offers":{"type":"array","items":{"type":"object","required":["id","public_identifier","name","universe","sub_universes","price_range_min","price_range_max","currency","started_at","ends_at","remaining_stock_percent","discount","url_fr","url_de","forum_stats"],"properties":{"id":{"description":"The numeric id of the offer, as a string.","type":"string"},"public_identifier":{"description":"The UUID of the offer, or null. Prefer id to get the offer content.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"description":"The title and the subtitle of the offer, in the locale of the content.","type":"string"},"universe":{"description":"The name of the main universe (category) of the offer.","anyOf":[{"type":"string"},{"type":"null"}]},"sub_universes":{"description":"The names of the sub-universes of the offer.","type":"array","items":{"type":"string"}},"price_range_min":{"description":"The lowest price of the offer, in CHF. null if the price is not public.","anyOf":[{"type":"number"},{"type":"null"}]},"price_range_max":{"description":"The highest price of the offer, in CHF. null if the price is not public.","anyOf":[{"type":"number"},{"type":"null"}]},"currency":{"description":"The ISO 4217 code of the currency of the prices, for example CHF.","type":"string"},"started_at":{"description":"The start of the sale, in RFC 3339 with the offset, for example 2026-10-05T10:00:00.000+02:00.","type":"string","format":"date-time"},"ends_at":{"description":"The end of the sale, in RFC 3339 with the offset.","type":"string","format":"date-time"},"remaining_stock_percent":{"description":"The remaining stock of the offer, from 0 to 100.","type":"integer","minimum":0,"maximum":100},"discount":{"description":"The discount as display text in the locale of the content, for example \"-49%\". Do not parse it. null if there is no discount to show.","anyOf":[{"type":"string"},{"type":"null"}]},"url_fr":{"description":"The URL of the French page of the offer. null if the offer is not sold in French.","anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"url_de":{"description":"The URL of the German page of the offer. null if the offer is not sold in German.","anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"forum_stats":{"description":"The number of forum comments for each locale. A count is null if the offer is not sold in that locale.","type":"object","required":["comments_fr_count","comments_de_count"],"properties":{"comments_fr_count":{"anyOf":[{"type":"integer"},{"type":"null"}]},"comments_de_count":{"anyOf":[{"type":"integer"},{"type":"null"}]}}}}}},"count":{"description":"The number of offers.","type":"integer"}},"$id":"https://api.qoqa.ch/v2/agents/schemas/v1/current_offers.schema.json"},"OfferContent":{"$schema":"https://json-schema.org/draft/2020-12/schema","title":"QoQa offer content","description":"The content of one QoQa offer in one locale: prices, status, its products, and the description in Markdown. Prices are in CHF.","type":"object","required":["id","public_identifier","name","locale","universe","sub_universes","price_range_min","price_range_max","currency","status","started_at","ends_at","remaining_stock_percent","discount","url","content_markdown","products"],"properties":{"id":{"description":"The numeric id of the offer, as a string.","type":"string"},"public_identifier":{"description":"The UUID of the offer.","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"description":"The title and the subtitle of the offer, in the locale of the content.","type":"string"},"locale":{"description":"The locale of the content.","type":"string","enum":["fr","de"]},"universe":{"description":"The name of the main universe (category) of the offer.","anyOf":[{"type":"string"},{"type":"null"}]},"sub_universes":{"description":"The names of the sub-universes of the offer.","type":"array","items":{"type":"string"}},"price_range_min":{"description":"The lowest price of the offer, in CHF. null if the price is not public.","anyOf":[{"type":"number"},{"type":"null"}]},"price_range_max":{"description":"The highest price of the offer, in CHF. null if the price is not public.","anyOf":[{"type":"number"},{"type":"null"}]},"currency":{"description":"The ISO 4217 code of the currency of the prices, for example CHF.","type":"string"},"status":{"description":"The status of the offer. ready: published, the sale has not started. live: on sale. soldout: no stock. over: the sale is over. Other values can appear later.","type":"string"},"started_at":{"description":"The start of the sale, in RFC 3339 with the offset, for example 2026-10-05T10:00:00.000+02:00.","anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"ends_at":{"description":"The end of the sale, in RFC 3339 with the offset.","anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"remaining_stock_percent":{"description":"The remaining stock of the offer, from 0 to 100. null if the offer is over.","anyOf":[{"type":"integer","minimum":0,"maximum":100},{"type":"null"}]},"discount":{"description":"The discount as display text in the locale of the content, for example \"-49%\". Do not parse it. null if there is no discount to show.","anyOf":[{"type":"string"},{"type":"null"}]},"url":{"description":"The page of the offer in this locale.","type":"string","format":"uri"},"content_markdown":{"description":"The title, the description and the delivery information of the offer, in Markdown. The products are in products. Its sections can change. Do not parse it.","type":"string"},"products":{"description":"The products of the offer, in the order of the site.","type":"array","items":{"type":"object","required":["id","name","collection","url","variants","content_markdown"],"properties":{"id":{"description":"The id of the product.","type":"string"},"name":{"description":"The name of the product, in the locale of the content. null if the product has no name.","anyOf":[{"type":"string"},{"type":"null"}]},"collection":{"description":"The title of the collection of the product. null if the product has no collection.","anyOf":[{"type":"string"},{"type":"null"}]},"url":{"description":"The page of the product. null if the product has no page.","anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"variants":{"description":"The variants of the product that a customer can buy, in the order of the site.","type":"array","minItems":1,"items":{"type":"object","required":["id","name","price","regular_price","stock_status"],"properties":{"id":{"description":"The UUID of the variant.","type":"string","format":"uuid"},"name":{"description":"The name of the variant, in the locale of the content. null if the variant has no name.","anyOf":[{"type":"string"},{"type":"null"}]},"price":{"description":"The price of the variant, in CHF. null if the price is not public.","anyOf":[{"type":"number"},{"type":"null"}]},"regular_price":{"description":"The lowest reference price of the variant, in CHF. null if there is no reference price to show.","anyOf":[{"type":"number"},{"type":"null"}]},"stock_status":{"description":"available, reserved (in the carts of other customers), or sold_out. The value can be some minutes old. Other values can appear later.","type":"string"}}}},"content_markdown":{"description":"The content of the product, in Markdown. Do not parse it. Empty when the product has no content, or when the offer or an earlier product already gives it.","type":"string"}}}}},"$id":"https://api.qoqa.ch/v2/agents/schemas/v1/offer_content.schema.json"},"Error":{"type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","required":["code","title","detail","meta"],"properties":{"code":{"type":"integer","description":"1: unknown route or schema, 2: unknown offer, 7: invalid parameter, 110: too many requests"},"title":{"type":"string","description":"What went wrong, in English"},"detail":{"type":"string"},"meta":{"anyOf":[{"type":"object"},{"type":"null"}]}}}}}}}}}