Authentication

Commerce has two HTTP surfaces with two distinct auth models.

Admin API

Used by the dashboard, AI agents, internal scripts. Authenticated with either a staff JWT (browser session) or a Personal Access Token (headless).

Authorization: Bearer <jwt-or-pat>

JWTs are minted on staff login by core-api (HS256 with shared secret). PATs are minted in the dashboard at Settings → API keys and start with nev_pat_. They carry scopes like commerce:read, commerce:write, and (rarely) commerce:admin. See Scopes.

Per-account access is gated by a separate check: identity.account_ids must include the requested account's id. Workspace admins (role:admin on the JWT) bypass the per-account check and can drive any account in the workspace.

Storefront API

Used by browser/mobile storefronts. Two layers:

1. X-Storefront-Key header (account scoping)

X-Storefront-Key: pk_live_abc123...xyz

The key identifies the account. It's public — it ships in your JS bundle, it's visible to any browser that visits your shop. Real auth boundaries are RLS isolation + cart token + origin allowlist.

Mint a key with POST /admin/2026-01/{handle}/storefront_keys.json. Each key has:

FieldPurpose
allowed_originsIf non-empty, requests must come from a matching Origin header. Supports https://*.example.com wildcards.
scopesWhat ops the key permits. Defaults: storefront:read, storefront:cart:write, storefront:checkout:write.
rate_limit_per_minuteConfigurable cap (default 600). Counters in Redis.
expires_atOptional auto-expiration.
statusactive / revoked.

2. Cart / checkout token in URL

Mutating a specific cart or checkout requires its opaque token in the URL:

POST   /storefront/2026-01/carts/{token}/lines.json
PATCH  /storefront/2026-01/checkouts/{token}/address.json

The token is returned at create time and is the only handle the storefront knows about. Anyone with the token can mutate that one resource within the same account — no cross-cart access. Tokens are secrets.token_urlsafe(24) (~196 bits of entropy).

This means a stolen Storefront key can spam new carts but can't read or modify anyone else's existing cart. A stolen cart token can mutate that one cart but nothing else.

Admin authentication example

curl https://api.nevios.io/admin/2026-01/my-shop/products.json \
  -H "Authorization: Bearer nev_pat_..."

Storefront authentication example

curl https://api.nevios.io/storefront/2026-01/carts.json \
  -X POST \
  -H "X-Storefront-Key: pk_live_..." \
  -H "Origin: https://shop.example.com" \
  -H "Content-Type: application/json" \
  -d '{"market_id": 308...}'

If the X-Storefront-Key is missing or revoked you get 401. If the Origin doesn't match allowed_origins you get 403.

What about webhooks?

Inbound webhooks (currently just Resend) authenticate via HMAC. See Email loop.

Next: Storefront API keys — how to mint and rotate.