Accounts & markets
The two top-level entities of multi-tenancy.
Accounts
An account is one e-shop. Every domain entity (product, order, customer, ...) lives under exactly one account. RLS isolates them in Postgres — even a bug in application code can't leak across tenants.
{
"account": {
"id": "308...",
"workspace_id": "uuid-...",
"handle": "my-shop",
"name": "My Shop",
"default_currency": "CZK",
"default_locale": "cs-CZ",
"default_timezone": "Europe/Prague",
"status": "active",
"version": 1
}
}
The handle is globally unique (across all accounts on the
platform). It's used in admin URLs:
/admin/2026-01/{handle}/products.json
Update with PUT /admin/2026-01/accounts/{handle}.json (requires
expected_version for optimistic concurrency). Soft-delete with
DELETE (archived_at set; rows persist for audit).
Markets
A market is one regional surface within an account: a unique combination of currency, locale, country, optional domain. Multiple markets per account let you sell in CZ + EU + US with different prices, languages, and tax rules from the same product catalog.
{
"market": {
"id": "308...",
"handle": "cz",
"name": "Česká republika",
"currency": "CZK",
"locale": "cs-CZ",
"country_code": "CZ",
"domain": null,
"prices_include_tax": true,
"status": "active"
}
}
prices_include_tax flips the storefront display behavior (gross
vs net pricing). Czech B2C is true, German B2B might be false.
Per-variant pricing rows (variant_pricing) are keyed by
(variant, market) — explicit prices per region, no auto-FX.
Cart and checkout always carry a market
Every cart and checkout pins a single market_id. This decides:
- Which currency the line prices are charged in
- Which tax rates apply (per
tax_ratesrows for that market) - Which shipping zones / methods are eligible
- Which locale is used for emails (unless overridden)
Trying to add a variant without pricing in the cart's market returns
409 (multi-currency cart reject — design decision Q8).
Relevant endpoints
| Verb | Path | Description |
|---|---|---|
| POST | /admin/2026-01/accounts.json | Create account |
| GET | /admin/2026-01/accounts.json | List accounts (workspace-filtered) |
| GET | /admin/2026-01/accounts/{id_or_handle}.json | Get account |
| PUT | /admin/2026-01/accounts/{id_or_handle}.json | Update (optimistic version) |
| DELETE | /admin/2026-01/accounts/{id_or_handle}.json | Soft-delete |
| POST | /admin/2026-01/{handle}/markets.json | Create market |
| GET | /admin/2026-01/{handle}/markets.json | List markets |
Next: Products & variants.