{"openapi":"3.1.0","info":{"title":"Snuset Storefront API","version":"1.0.0","summary":"Machine-readable access to the Snuset snus store.","description":"Snuset (snuset.se) is a Swedish online snus and nicotine-pouch store.\n\nThis document describes the parts of snuset.se that are meant to be\nconsumed by programs rather than browsers:\n\n- **Discovery** — `/llms.txt`, `/sitemap.xml`, `/robots.txt` and this document.\n- **Markdown content negotiation** — every page on the site returns\n  `text/markdown` when requested with `Accept: text/markdown`\n  (see https://acceptmarkdown.com).\n- **Product search** — a read-only JSON search over the catalogue.\n- **Cart and checkout** — the Vendure Shop GraphQL API at\n  `https://api.snuset.se/shop-api`, which also backs the `snuset` CLI.\n\nProducts on this site are age-restricted (18+ in Sweden). Orders can be\nassembled programmatically, but payment always happens in a browser via\nthe checkout URL.","contact":{"name":"Snuset","url":"https://www.snuset.se/developers/"},"license":{"name":"Proprietary","identifier":"LicenseRef-Proprietary"}},"externalDocs":{"description":"Snuset developer and agent documentation","url":"https://www.snuset.se/developers/"},"servers":[{"url":"https://www.snuset.se","description":"Snuset storefront"}],"tags":[{"name":"Discovery","description":"Machine-readable descriptions of the site."},{"name":"Content","description":"Page content for agents."},{"name":"Catalogue","description":"Read-only product data."},{"name":"Commerce","description":"Cart, customer and checkout operations."}],"paths":{"/llms.txt":{"get":{"tags":["Discovery"],"operationId":"getLlmsTxt","summary":"Agent-oriented index of the site","description":"An llms.txt document (https://llmstxt.org) listing the site's key sections and developer resources.","responses":{"200":{"description":"The llms.txt document.","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/openapi.json":{"get":{"tags":["Discovery"],"operationId":"getOpenApiDocument","summary":"This OpenAPI document","responses":{"200":{"description":"The OpenAPI description of the Snuset storefront API.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/sitemap.xml":{"get":{"tags":["Discovery"],"operationId":"getSitemap","summary":"Every indexable URL on the storefront","responses":{"200":{"description":"A urlset sitemap.","content":{"application/xml":{"schema":{"type":"string"}}}}}}},"/robots.txt":{"get":{"tags":["Discovery"],"operationId":"getRobotsTxt","summary":"Crawling rules","responses":{"200":{"description":"The robots.txt document.","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/{path}":{"get":{"tags":["Content"],"operationId":"getPageAsMarkdown","summary":"Any storefront page, as Markdown or HTML","description":"Every page URL on snuset.se serves two representations of the same\nresource. Send `Accept: text/markdown` to get clean Markdown with the\nnavigation, scripts and layout stripped out; send `Accept: text/html`\n(or nothing) to get the page as a browser sees it.\n\nResponses set `Vary: Accept`. A request whose `Accept` header excludes\nboth media types is answered with `406 Not Acceptable`.\n\nUse `/sitemap.xml` to enumerate valid paths. Unknown paths return a\nreal `404` whose body points back at the sitemap and this document.","parameters":[{"name":"path","in":"path","required":true,"description":"A storefront path, without the leading slash — for example `produkter/snus/` or `produkt/general-white-portion/`.","schema":{"type":"string"},"example":"produkter/snus/"},{"name":"Accept","in":"header","required":false,"description":"Preferred representation. Honours q-values.","schema":{"type":"string","enum":["text/markdown","text/html"],"default":"text/html"}}],"responses":{"200":{"description":"The page.","headers":{"Vary":{"description":"Always includes `Accept`.","schema":{"type":"string"}},"Link":{"description":"Advertises the Markdown representation as `rel=\"alternate\"`.","schema":{"type":"string"}}},"content":{"text/markdown":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"404":{"description":"No such page. The body lists the sitemap, llms.txt and this document so an agent can recover.","content":{"text/markdown":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"406":{"description":"The `Accept` header rules out both `text/html` and `text/markdown`.","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/api/search-suggestions/":{"get":{"tags":["Catalogue"],"operationId":"searchProducts","summary":"Search the product catalogue","description":"Full-text search over the sellable catalogue, returning up to eight\nproduct variants. Age-restricted classifications that may not be\nadvertised (smoking and vape products) are excluded.\n\nUse `productVariantId` from a hit as the `productVariantId` argument to\nthe Shop API's `addItemToOrder` mutation.","parameters":[{"name":"q","in":"query","required":true,"description":"Free-text query, e.g. a brand, flavour or product name.","schema":{"type":"string"},"example":"general white"}],"responses":{"200":{"description":"Matching product variants, most relevant first. An empty `q` returns an empty array.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProductHit"}}}}}}}},"/shop-api":{"post":{"tags":["Commerce"],"operationId":"shopApiGraphql","summary":"Vendure Shop GraphQL API","description":"The storefront's commerce API: catalogue queries, cart mutations,\ncustomer accounts and checkout. It is a standard Vendure Shop API.\n\nEvery request must send the channel token header `vendure-token: sweden_webshop`.\nAuthenticated sessions use the `vendure-auth-token` bearer token returned\nby the `authenticate` mutation.\n\nIntrospect the schema with a standard GraphQL introspection query. The\n`snuset` CLI (`npx snuset`) wraps the common flows and is usually the\nfaster path for an agent.","servers":[{"url":"https://api.snuset.se","description":"Snuset Shop API"}],"security":[{"channelToken":[]},{"channelToken":[],"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GraphQLRequest"}}}},"responses":{"200":{"description":"A GraphQL response. GraphQL errors are reported in `errors` with a 200 status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GraphQLResponse"}}}}}}}},"components":{"securitySchemes":{"channelToken":{"type":"apiKey","in":"header","name":"vendure-token","description":"Vendure channel token. Always `sweden_webshop` for this storefront."},"bearerAuth":{"type":"http","scheme":"bearer","description":"Session token returned in the `vendure-auth-token` response header after `authenticate`."}},"schemas":{"Money":{"type":"object","description":"An amount in minor units of `currencyCode` (öre for SEK).","properties":{"price":{"type":"integer","description":"Price excluding VAT."},"priceInclTax":{"type":"integer","description":"Price including VAT."},"priceExclTax":{"type":"integer","description":"Price excluding VAT."},"currencyCode":{"type":"string","example":"SEK"}}},"PackSize":{"type":"object","description":"A multi-can bundle a variant can be bought as.","properties":{"id":{"type":"string"},"name":{"type":"string","example":"5-pack"},"quantity":{"type":"integer","example":5},"isDefault":{"type":"boolean"},"price":{"type":"integer","description":"Bundle price in minor units."}}},"Facet":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"}}},"ProductHit":{"type":"object","description":"A product variant in the search index.","properties":{"id":{"type":"string"},"objectID":{"type":"string"},"productId":{"type":"string"},"productVariantId":{"type":"string","description":"Pass to `addItemToOrder` on the Shop API."},"name":{"type":"string"},"slug":{"type":"string","description":"Product page slug; the page lives at `/produkt/{slug}/`."},"image":{"type":"string","format":"uri"},"classification":{"type":"string","description":"Top-level category, e.g. `snus` or `nicotine-pouches`."},"availability":{"type":"string","description":"Stock state, e.g. `IN_STOCK` or `OUT_OF_STOCK`."},"inStock":{"type":"boolean"},"amount":{"$ref":"#/components/schemas/Money"},"facets":{"type":"object","description":"Facet values keyed by facet code (`brand`, `strength`, `flavor`, …).","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/Facet"}}},"pack_sizes":{"type":"array","items":{"$ref":"#/components/schemas/PackSize"}}}},"GraphQLRequest":{"type":"object","required":["query"],"properties":{"query":{"type":"string"},"operationName":{"type":"string"},"variables":{"type":"object","additionalProperties":true}}},"GraphQLResponse":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true},"errors":{"type":"array","items":{"type":"object","properties":{"message":{"type":"string"}}}}}}}}}