Appearance
Authentication & keys
Every request carries your store's API key as a bearer token:
Authorization: Bearer hk_live_pub_xxxxxxxxxxxxDon't have a key yet? Create one on the API keys screen:
Get your API keysYour key identifies your store, so you never send a store or account id. Any tenant_id or customer_id you put in a body or query is ignored.
Publishable vs secret keys
There are two kinds of key, with a hard capability split:
| Kind | Prefix | Ship to a browser? | Authorizes |
|---|---|---|---|
| Publishable | hk_*_pub_… | ✅ yes (low-priv) | Anonymous catalog reads |
| Secret | hk_*_sec_… | ❌ never | Everything publishable does plus customer-scoped reads, checkout, webhooks |
A publishable key used on a customer-scoped or webhook route is always rejected with 403 - never silently downgraded. Keep your secret key server-side only.
Check a key against GET /v1/ping - it echoes which store the key resolves to (tenant_id), the key_kind, granted scopes, and mode, without touching any data:
bash
curl -s https://api.harmoncommerce.com/v1/ping \
-H "Authorization: Bearer hk_live_pub_xxxxxxxxxxxx"
# → {"tenant_id":"…","key_kind":"PUBLISHABLE","scopes":["storefront:catalog"],"mode":"live"}Shopper tokens (customer-scoped routes)
Customer-scoped reads and the cart → checkout path require an end-shopper to be logged in. The key authenticates the integration; the shopper token authenticates the customer. Obtain a shopper token via the auth login flow, then send it alongside the secret key:
Authorization: Bearer hk_live_sec_…
X-Storefront-Shopper-Token: <shopper jwt>The shopper token carries the customer_id; every order, invoice, and credit read is automatically scoped to that customer. A shopper token that belongs to a different store than the key is rejected (403).
CORS for publishable keys
A publishable key carries a CORS origin allowlist: a browser request from an Origin not on the key's allowlist is refused 403. Register every origin your storefront serves from when you issue the key. Secret keys are server-to-server and aren't origin-checked.
Next steps
- Sandbox vs live - build against a test key, then flip to live.
- Errors - what
401/403mean and how reads degrade. - Quickstart - get a key and make your first call.
In the API Reference
GET /v1/ping- your first authenticated call; echoes the key's modeGET /v1/me- the customer a shopper token resolves to