Authentication
Protect merchant endpoints with scoped bearer tokens while keeping public storefront reads easy.
Bearer auth on merchant endpoints — scope-to-route mapping, workspace scoping, idempotency.
Public storefront endpoints (/stores/*, /carts/*, /search) do not require auth. Merchant endpoints (/merchant/*) require a bearer token bound to the workspace that owns the site.
Public storefront
Anyone can read published catalog and run a guest checkout. CORS is wide open on GET endpoints; POST endpoints accept JSON bodies from the same headers as UCP.
# No auth required:curl https://aly.store/api/storefront/v1/stores/acme/productsMerchant endpoints
Send Authorization: Bearer aly_... (API key) or Authorization: Bearer aly_oauth_...(OAuth token). Both carry a workspace id, a user id (for audit), and a granted scope set. The server checks every request against the route's required scope and the resource's workspace.
curl https://aly.store/api/storefront/v1/merchant/orders \ -H "Authorization: Bearer aly_a8d9...e3c7"Scope mapping
Which scope governs which endpoint family:
| Endpoint family | Read scope | Write scope |
|---|---|---|
/merchant/products | read:content | write:content |
/merchant/orders | read:orders | write:orders |
/merchant/customers | read:customers | write:customers |
/merchant/customer-groups | read:customers | write:customers |
/merchant/analytics | read:analytics | — |
/merchant/webhooks | read:sites | write:sites |
/merchant/price-lists | read:content | write:content |
/merchant/media/assets | read:media | write:media |
See Authentication for the full scope catalog and OAuth flow, and Operator vs storefront scopes for guidance on which scope set to request.
Workspace scoping
Tokens are bound to one workspace at issue time. Every request the server checks that the targeted resource (the site behind a product, an order's site, etc.) lives in the token's workspace. A request for a resource in a different workspace returns 403 forbidden_workspace.
Idempotency
State-changing endpoints accept (and recommend) an Idempotency-Key header. Replays with the same key return the original response; mismatched bodies under the same key return 409.
Was this page helpful?