Storefront API
Authentication
Publishable keys scope every request to exactly one store. They are designed to be public: shipping one in browser code is the intended use, and nothing beyond storefront reads and cart writes is reachable with it.
Sending the key
# both forms are equivalent — pick one▸ GET /storefront/v1/products▸ X-Publishable-Key: pk_live_9f2…# or▸ Authorization: Bearer pk_live_9f2…◂ 401 Unauthorized when the key is missing, malformed, or revoked{ "type": "about:blank", "title": "unauthorized", "status": 401, "detail": "publishable key required (X-Publishable-Key: pk_…)" }
Never send admin session tokens from a storefront. The storefront surface accepts only pk_… keys; admin credentials do not work here, and publishable keys do not work on admin endpoints.
Allowed origins
Each key may declare allowedOrigins. When a request arrives from a browser (it carries an Origin header), the origin must match the list — anything else is rejected. Server-to-server calls carry no origin and are unaffected. An empty list means the key works from any origin.
CORS on /storefront/v1 is open by design (wildcard origin, never credentials) — the key, not the browser, is the authorization. Everything outside /storefront/v1 stays default-deny.
Managing keys (admin surface)
Keys are managed from the Admin (Settings → Integrations → Storefront keys) or over the admin API with a staff session. The full key value is returned once, at creation — the platform stores only a SHA-256 hash.
| Body | Type | Description |
|---|---|---|
| labelreq | string | A name you will recognize later. |
| allowedOrigins | string[] | Browser origins allowed to use this key. Empty = any origin. |
Lists keys with their keyPrefix (never the full value), label, origins, and creation time.
Revokes immediately. In-flight storefront sessions lose access within the cache window (about a minute).
Rotation
Rotate without downtime:
- Create the replacement key with the same origins.
- Deploy your storefront with the new key.
- Revoke the old key.