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.
OrgContextGuardreturns400for a missing header and the same neutral404for 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
401after tenant resolution. - Tokenized actions follow their own credential contract. Emailed
GET /customer/actions/:tokenandPOST /customer/actions/:tokenuse the action token without a customer session, but still require the tenant header. The publicGET /public/orders/token/:tokenstatus 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-sessionresolves the tenant from the checkout token and does not requirex-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-schemaneeds no tenant header.GET /merchant/auth/sessionneeds 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.
Related
- Auth & roles — who can do what within a tenant
- API keys — the staging server-to-server contract and remaining productization
- Customer accounts & sign-in — the separate customer-session and action-token contracts