Skip to content

Tenants & context

Storefront requests also carry their current origin: browsers supply Origin; SSR and backend transports forward x-storefront-origin. Domains selects Live or Sandbox data automatically, including token-only calls. Missing or conflicting context is rejected, with no Live fallback. See storefront data selection.

cartonium is multi-tenant from the ground up. A tenant is one merchant's store — its catalog, inventory, orders, memberships, and settings. Tenant-facing commerce operations are scoped to one organization. Global metadata, signup, and the staff session's membership list have different requirements; do not assume every API request takes a tenant header.

How context is resolved

Tenant context is usually carried in the x-organization-slug header — the slug of the store you're acting on. Authentication and tenant selection are separate: the slug selects a store but grants no membership or customer access.

x-organization-slug: your-store
  • Anonymous public catalog/content uses the header without a privileged credential. OrgContextGuard returns 400 for a missing header and the same neutral 404 for an unknown or inactive store.
  • Tenant-scoped merchant operations use the header plus a Supabase staff JWT. The membership guard checks the selected tenant; a missing/unknown slug or absent membership returns the same 403. The operation may also require a permission policy.
  • Customer account operations use the header plus the customer's opaque session. This is separate from a merchant JWT. Invalid, expired, revoked, and cross-tenant sessions receive the same neutral 401 after tenant resolution.
  • Tokenized actions follow their own credential contract. Emailed GET /customer/actions/:token and POST /customer/actions/:token use the action token without a customer session, but still require the tenant header. The public GET /public/orders/token/:token status read also needs that header; an opaque token does not universally replace tenant context.
  • Checkout payment handoff is an explicit exception: POST /public/checkout/sessions/:token/payment-session resolves the tenant from the checkout token and does not require x-organization-slug.
  • Server-to-server catalog reads use the server-side API key to resolve their tenant, without the slug header. That separate storefront surface is implemented on staging while full API-key productization remains in development; see API keys.
  • Org-agnostic operations include public schema metadata. GET /public/api-schema needs no tenant header. GET /merchant/auth/session needs a staff JWT but no selected tenant, so it can return the caller's memberships.

An authenticated request must satisfy both its credential and tenant boundary; supplying another store's slug does not grant access to its private data. Use the API reference for each operation's exact requirements. The API deployment is separate from Live/Sandbox commerce mode. For storefront calls, Domains selects the mode from the current request origin; it is not an extra integration setting. See Environments & schema identity.