Authentication
The three identities, JWT sessions, and scoped API keys.
An integration acts as one of two identities. Which one you are determines what you can touch.
| Principal | Who | Logs in at |
|---|---|---|
| Tenant (store owner) | The merchant | POST /api/v1/auth/tenant/login |
| Customer (shopper) | A store’s shopper | POST /api/v1/auth/customer/login |
Interactive sessions use JWTs (with a silent refresh). Integrations don’t log in — they use API keys.
API keys
An API key authenticates a machine and pins it to one store. Send it as a Bearer token on every request:
Authorization: Bearer sk_xxxxxxxxxxxx
A key carries permissions — the same permission set that scopes a staff member’s role. So a key is exactly as capable as the permissions it was granted, and no more.
Scoped by design
- A key granted
orderscan read/act on orders but not touch themes. - A Theme Access key is scoped to
themes— it can edit and publish theme code but cannot activate a theme, buy a paid theme, or delete a theme. Those are owner-only and return403for any key. See Theme development.
This split means a merchant can hand a freelancer a Theme Access key without handing over the store.
Lifecycle
Keys have an optional expiry and can be revoked at any time; a revoked or expired
key returns 401. Rotate keys by issuing a new one and revoking the old. See
API keys.
Which identity should an integration use?
- A backend integration / CI → an API key (no account, revocable, scoped).
- A real person on your team → a staff account with a role (real identity and audit trail).
Treat keys like passwords
A sk_ key is a bearer credential — anyone holding it can act as its
permissions allow. Store it in a secret manager, never in client-side code or a
repo, and scope it to the minimum it needs.