docs/developer/core-concepts/stores.mdx
The Store is the top-level tenant in Spree. Every resource — products, orders, channels, markets, taxonomies — belongs to exactly one store. A store owns its channels (online, POS, wholesale, …), its markets (region/currency/locale), and its product catalog.
| Attribute | Description |
|---|---|
name | Store name, displayed in the browser title and throughout the site |
code | Unique identifier for the store |
url | Primary URL of the store |
meta_description | SEO description |
meta_keywords | SEO keywords |
seo_title | Custom SEO title |
customer_support_email | Email for customer support inquiries |
mail_from_address | Sender address for transactional emails |
logo_url | URL to the store's logo |
facebook, twitter, instagram | Social media links |
storefront_access | Store-wide default for anonymous storefront access gating (public, prices_hidden, login_required). Each channel can override it |
guest_checkout | Store-wide default for whether orders can be placed without an account. Each channel can override it |
Store configuration is exposed through the Admin API. Use the store endpoint to read the current store's settings — name, URL, branding, and email addresses:
<CodeGroup>const store = await adminClient.store.get()
// {
// name: "My Store",
// url: "https://mystore.com",
// logo_url: "https://cdn.mystore.com/logo.png",
// mailer_logo_url: "https://cdn.mystore.com/mailer-logo.png",
// customer_support_email: "[email protected]",
// ...
// }
curl 'https://api.mystore.com/api/v3/admin/store' \
-H 'X-Spree-API-Key: sk_xxx'
This is an admin endpoint, so it requires a secret API key (sk_xxx) or a Bearer JWT — a publishable key cannot reach it.
Two different ways to split a store, often confused:
A single Online Store channel can serve multiple markets (one storefront → many regions). Conversely, POS and Online channels can share the same market (same currency/locale, different selling surfaces).
The store sets the fallback for storefront access gating — whether anonymous visitors may browse, see prices, or must sign in first — via storefront_access (public, prices_hidden, login_required) and the companion guest_checkout control. Each channel inherits these unless it sets its own value, so you can gate a whole store or just one channel (e.g. a login_required wholesale channel on an otherwise public store). The full behavior of each mode and how the Store API enforces it lives in Channels → Storefront Access Gating.
Each store owns its own resources. Products, orders, channels, markets, and taxonomies in one store are independent from another.
| Resource | Relationship |
|---|---|
| Channels | A store has many channels (Online Store, POS, Wholesale, …). One is the default. |
| Markets | A store has many markets, each defining a geographic region with its own currency and locale |
| Orders | An order belongs to one store and one channel |
| Products | A product belongs to one store. Its visibility across channels is controlled by publications. |
| Categories | A category belongs to one store |
| Payment Methods | A payment method belongs to one store |
| Shipping Methods | A shipping method belongs to one store |
| Promotions | A promotion belongs to one store |
If you need one Spree backend to serve multiple distinct merchant brands — different domains, different catalogs — there are two patterns: