Skip to content

API keys

Tenant API keys authenticate server-to-server calls from an external / BYO storefront's backend — a server talking to litecommerce without a logged-in staff member. They are server-side only: the secret is a bearer credential and must never appear in browser JavaScript, a storefront client bundle, or a public env var. (Anything a shopper's browser touches uses the anonymous /public/* surface with x-organization-slug — see Tenants & context.)

Rolling out. The inbound x-api-key flow is in active development and serves the external-storefront server-to-server surface (/api/v1/storefront/*). The live surface includes storefront context plus server-side catalog reads for items and collections. Merchant requests in the admin app still authenticate with the Supabase staff JWT (see Auth & roles), and the self-serve key-management experience is still coming — see What's still coming.

How it works

  • Key storage + management — a public key plus a hashed secret, with scopes, a lastUsedAt timestamp, and rotation/revocation. Keys are tenant-scoped, so a key can only ever act within its own tenant.
  • Inbound x-api-key auth — a verification guard resolves the key, enforces the route's scopes, records lastUsedAt, and rate-limits per key. The tenant is resolved from the key itself (no spoofable slug header).

Authenticating

Send the key — the publicKey joined to its secret with a single . — as the x-api-key header:

x-api-key: <publicKey>.<secret>     # e.g. lcp_….lck_…

The publicKey (safe to log) identifies the key; the secret is verified server-side. The secret is shown once at creation — store it where only your server can read it, never in client code. Keys are server-side only.

Scopes

A key carries scopes, and a route requires every scope it declares (AND):

  • storefront:read — read a tenant's storefront catalog/context.
  • checkout:write — create/advance a checkout on the tenant's behalf.

A request whose key lacks a required scope is rejected with 403 and the error code API_KEY_SCOPE_INSUFFICIENT; the response details.missingScopes array names exactly which scopes to add.

Server-to-server storefront reads

Use x-api-key only from your storefront backend. The tenant comes from the key, so these routes do not use x-organization-slug:

  • GET /api/v1/storefront/context
  • GET /api/v1/storefront/items
  • GET /api/v1/storefront/items/search
  • GET /api/v1/storefront/items/{slug}
  • GET /api/v1/storefront/collections
  • GET /api/v1/storefront/collections/{slug}
  • GET /api/v1/storefront/collections/{slug}/items

Catalog responses reuse the same public-safe item and collection projections as the browser /public/* catalog routes and only return active, non-archived catalog records. The optional server-to-server checkout bridge is tracked separately and should not be assumed live.

What's still coming

Full self-serve productization belongs to E6: API & Developer Platform, currently scheduled in M8 (GitHub milestone #8), and has not shipped: the merchant self-service key-management UI, SDKs / generated clients, a public developer portal, a rich scope editor, and usage analytics/billing. Until then, key issuance is operator-assisted and the supported surface is the server-to-server endpoints above. Don't present API keys as a full self-serve product yet.

Tenant outbound webhooks are a separate E17: Tenant Webhooks & Event Delivery boundary and are not currently scheduled. API-key delivery does not imply that an outbound event-delivery contract is available.