Docs
Dashboard
View as Markdown
On this page
  1. Base URL
  2. Keys
  3. Buyers
  4. CORS
  5. Caching
  6. Errors
  7. Retries
  8. Limits
  9. Stability

Storefront API

Keys, CORS, caching, errors and limits for the public Storefront API.

The Storefront API is what your own storefront, app or agent uses to read your catalog and sell: products with live stock, collections and categories, search, carts with discount codes and gift cards, checkout, buyer accounts with their orders, keys and downloads, and support tickets. Every operation runs the same code as your ShopFast store, so prices, stock, taxes, discounts and fraud checks always match.

curl https://api.shopfa.st/v1/shops/your-store/products?limit=12 \
  -H "ShopFast-Storefront-Key: sfpk_live_…"

The reference lists every operation. The JavaScript SDK wraps them with types.

Base URL

https://api.shopfa.st/v1/shops/{shop}, where {shop} is your store’s handle (your-store) or its st_ id. The store is part of the URL so a shared cache can never mix two stores up.

Keys

Create keys in Settings → Headless & MCP → Storefront keys.

Publishable sfpk_… Private sfsk_…
Where Browsers, mobile apps, anywhere public Your server only (Next.js server components, a backend)
Seen Any time in the dashboard: it is public by design Once, when you create it
Origins Optionally limited to your sites Refused from browsers
Buyer address The caller’s Your server can pass ShopFast-Buyer-IP

Send the key in ShopFast-Storefront-Key (or Authorization: Bearer sfpk_…). A key works only with its own store. Revoking a key stops it within a minute everywhere.

Why private keys pass the buyer’s address: limits and fraud checks are per buyer. Without ShopFast-Buyer-IP, every buyer of a server-rendered site would look like your server.

A key’s allowed origins also register your sites, for either kind of key: checkout sends buyers back only to them (a cart’s returnUrl and cancelUrl), and the embedded checkout opens only on them. See Headless checkout.

Buyers

Sign a buyer in with an emailed code (POST /customer/code, then POST /customer/session) and send their token in ShopFast-Customer-Token on later calls. Read Buyer accounts.

CORS

Browsers may call the API from any origin with a publishable key, or only from the origins you list on the key. Answers that are the same for everyone carry Access-Control-Allow-Origin: *; personal answers (carts, accounts, orders) name your origin. No cookies are involved: credentials are always headers.

Caching

Catalog reads are made to be cached:

  • Cache-Control: public, max-age=0, s-maxage=60, stale-while-revalidate=600
  • ETag: send it back in If-None-Match and get 304 Not Modified with no body.
  • Cache-Tag: the same tags your store’s pages use (s:<store>, p:<product>, c:<store>:<collection>, pg:<store>:<page>). When you change something, ShopFast drops exactly those.

Catalog answers are served from ShopFast’s edge, close to your buyers, and refresh within seconds of a change. They are the same for every caller, like your store’s own pages, so the edge does not check the key again for an answer it already holds.

Live stock (GET /products/{handle}/availability) is never cached. Carts, buyer accounts, orders and tickets are private, no-store, and so is everything while your store is closed, in maintenance or behind a store password.

To keep your own cache fresh, subscribe to the storefront.updated webhook.

Errors

Every error is RFC 9457 problem JSON:

{ "type": "https://shopfa.st/problems/origin-not-allowed", "title": "Origin not allowed", "status": 403, "detail": "This key only works from https://shop.example.com.", "fields": [] }
Status When
401 No key, an unknown or revoked key, or a key from another store
403 A private key from a browser, or an origin the key does not allow
404 No such product, collection, category or page (a renamed product answers 301 to its new handle)
422 The input failed validation; fields says where
429 Too many requests; wait Retry-After seconds

Retries

Send Idempotency-Key with a write (a cart, a code, a checkout, a ticket) and a retry after a timeout runs it once: the same request with the same key gets the first answer again, with Idempotent-Replayed: true. Keys are kept 24 hours per storefront key and signed-in buyer. See Idempotency for the rules.

curl -X POST https://api.shopfa.st/v1/shops/your-store/carts \
  -H "ShopFast-Storefront-Key: sfpk_live_…" -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9b2f0c4e-cart" \
  -d '{"lines":[{"productId":"prd_…","quantity":1}]}'

Limits

600 reads and 120 writes a minute per key and buyer address, on top of the store’s own limits on sign-in codes, discount codes and checkouts.

Stability

Operations under /v1 only ever gain fields and operations. A change that would break you gets a new version. The SDK’s schema snapshot is checked on every change to ShopFast, so a breaking change cannot slip in.

Was this page helpful?