Commerce API
Keys & authentication
Two kinds of key, with different rules — and the rules are enforced, not advised.
Every request carries a key. Send it as Authorization: Bearer <key>, or as X-Mercestack-Key: <key> where the Authorization header is already spoken for by a proxy or framework.
| Publishable `pk_…` | Secret `sk_…` | |
|---|---|---|
| Where it goes | Browser code, mobile apps, anywhere | Your server, and nowhere else |
| Stored by us as | A hash and the key itself, so you can read it back | A hash only — shown once, at creation |
| Can | Read the published catalog, create and edit carts, start checkout | Whatever scopes you granted it |
| Cannot | Read orders or customers, edit a product, adjust stock, refund | Be used from a browser — we refuse the request |
Two rules worth knowing
A publishable key's capabilities are fixed in our code, not read from your key's record. Whatever a key row says, a publishable key gets the storefront set and nothing else — so a misconfiguration cannot hand a browser the ability to read orders.
A secret key sent with an `Origin` header is rejected. An Origin means a browser, which means the key is in a front-end bundle. Serving that request would let the leak continue quietly, so we refuse it instead. The SDK also throws if you pass an sk_ key to it, before any request is sent.
Scopes
Secret keys carry explicit scopes. Grant the narrowest set that does the job — a key that syncs stock has no business reading customers.
products:read products:write
inventory:read inventory:write
orders:read orders:write
customers:read customers:write
carts:write checkout:write
discounts:read discounts:write
giftcards:read giftcards:write
refunds:create webhooks:manageTest mode
pk_test_ and sk_test_ keys create carts and orders marked livemode: false. They are excluded from revenue, analytics and abandoned-cart automation, so your experiments never appear in a merchant's numbers.