Authentication
The Storefront API uses two credentials: a store API key that identifies which store a request is for, and a shopper token for actions tied to a customer account. Getting this right is the difference between a working integration and 401/403 responses.
1. Store API key
Every Storefront API request must present your business's API key in the X-Periscale-Key header:
GET /api/v1/business/website/config/ HTTP/1.1
Host: storefront.periscale.app
X-Periscale-Key: sb_live_...The key is your sb_live_* business API key — the same key the chat widget and analytics tag use. The key alone determines which store is served, so there is no subdomain or tenant parameter to pass. A missing or revoked key returns 401.
Keep the key server-side
The key belongs to your storefront application, not the shopper. Bake it into your server environment and proxy browser requests through your own backend (e.g. a Next.js route handler) — never ship it in client-side JavaScript.
Sandbox and production keys are different
Use the key issued for the environment you are calling. A sandbox key against storefront.periscale.app returns 401 rather than reading the wrong store.
Anonymous visitors can browse the full catalog and content with the key alone — no shopper login required.
2. Shopper tokens
Actions tied to a shopper's account — cart, checkout, orders, wishlist, addresses, tickets, submitting a review — additionally require the shopper's JWT access token:
Authorization: Bearer <shopper_access_token>So a cart request carries both: X-Periscale-Key (which store) andAuthorization: Bearer … (which shopper).
Getting a shopper token
Shoppers register and log in through the customer auth endpoints under /api/v1/customer/auth/. These calls use the same X-Periscale-Key as everything else:
POST /api/v1/customer/auth/login/ HTTP/1.1
Host: storefront.periscale.app
X-Periscale-Key: sb_live_...
Content-Type: application/json
{ "email": "shopper@example.com", "password": "…" }The response's data contains an access_token (valid 24 h — send it as the Bearer token), a refresh_token (valid 30 days), and the customer profile. Renew the access token with POST /api/v1/customer/auth/refresh/.
See the Shopper authentication reference for register, login, OTP verification, profile, and password-reset endpoints.
Summary
| You are… | Calling… | Send |
|---|---|---|
| Storefront (anonymous read) | Config, catalog, content | X-Periscale-Key: <key> |
| Storefront (shopper action) | Cart, checkout, orders, account | X-Periscale-Key + Authorization: Bearer <shopper_token> |
| Storefront (shopper login/register) | /api/v1/customer/auth/… | X-Periscale-Key: <key> |
Errors you might hit
| Status | error_code | Usually means |
|---|---|---|
401 | unauthorized | No X-Periscale-Key header was sent. |
401 | invalid_token | The key is malformed, revoked, or from the other environment. |
404 | not_found | The key is valid but its store has no active website. |
429 | too_many_requests | Rate limit hit — retry after the Retry-After header. |