Appearance
Authentication & keys
Every request carries a merchant-scoped API key as a bearer token:
Authorization: Bearer hk_live_pub_xxxxxxxxxxxxDon't have a key yet? Mint one on the admin API keys screen:
Get your API keysThe merchant is resolved from the key - you never send a tenant_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 + initiating shopper auth |
| Secret | hk_*_sec_… | ❌ never | Everything publishable does plus customer-scoped reads, checkout, webhooks |
The split is law: a publishable key presented against a customer-scoped or webhook route is always 403, never a silent downgrade. Keep your secret key server-side only.
Smoke-test a key against GET /v1/ping - it echoes the resolved tenant_id, key_kind, granted scopes, and mode without touching any data:
bash
curl -s https://api.harmon.example/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; Harmon auto-scopes every order, invoice, and credit read to that customer. A shopper token whose merchant differs from the key's merchant 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