Sales channels
Configure channel domains, product prices, countries, and payment methods.
A sales channel belongs to one shop and controls its selling context. Use the shop-admin API for configuration and the public storefront/checkout APIs for purchases.
Permissions
GET /api/admin/channels supports catalog:read and returns channels. The channel detail, configuration, domain, country, and payment-method routes require an admin session with the applicable tenant permissions. A catalog:write token can update a product's channel listing, but cannot create or reconfigure a channel.
Creating/deleting channels and choosing the default additionally require the shop owner.
Channel configuration
| Method | Path | Purpose |
|---|---|---|
GET | /api/admin/channels | List channels |
GET | /api/admin/channels/:id | Read channel |
POST | /api/admin/channels | Create a channel |
PATCH | /api/admin/channels/:id | Update configuration |
POST | /api/admin/channels/:id/set-default | Choose the active default channel |
DELETE | /api/admin/channels/:id | Delete when business-state restrictions permit |
Creation accepts name, optional slug, default_country, and a supported currency. The returned channel contains id, name, slug, is_default, is_active, currency, default_country, allocation_strategy, auto_confirm_orders, allow_unpaid_orders, and pending_payment_ttl_hours.
PATCH accepts name, activation, currency, default country, and order/allocation rules. Currency changes are restricted once commerce data depends on the channel; changing the currency is not a conversion of existing amounts. A new channel is not automatically the default.
Storefront domain resolution
Channel resolution happens within the shop selected by the publishable key, in this order:
- A configured active channel matching the request's
Originhostname, falling back toReferer. - An active channel matching a path prefix such as
/en/api/store/products. - The shop's active default channel.
Passing an arbitrary channel_id in a checkout creation body does not select a channel. Use the same origin/path context for catalog, cart, and checkout requests.
Manage domain mappings with GET or POST /api/admin/channels/:id/domains. POST accepts:
{
"domain": "console.cubora.gg"
}
GET returns domains; POST returns domain with its mapping id. Remove a mapping with DELETE /api/admin/channels/:id/domains/:domainId. A domain is unique across channel mappings; conflicts return 409.
This mapping chooses the channel. The publishable-key origin allowlist separately decides whether the request is allowed, and DNS/proxy routing separately decides which server receives it. Configure all three for a custom storefront.
Product prices and publication
GET /api/products/:id/channels returns channel listings for a product and supports catalog:read. PATCH /api/products/:id/channels/:channelId supports catalog:write, subject to write validation, or an authorized session.
{
"is_published": true,
"price_cents": 2490,
"compare_at_price_cents": 2990
}
An optional variant_id selects the variant. For a product without variants, a custom price is stored directly on its channel listing. Set price_cents to null to remove the custom channel price and fall back to the product/variant price. compare_at_price_cents can also be null.
The base product's publication state and its channel listing are separate. The storefront catalog currently returns base product prices; checkout pricing resolves applicable channel prices and currency. Use server-calculated cart/session totals for payment.
Countries and tax overrides
GET /api/admin/channels/:id/countries returns countries. Replace the channel's selection with PUT to the same path:
{
"country_codes": ["AT", "DE"]
}
An empty selection falls back to the available active country list. PATCH /api/admin/channels/:id/countries/:code accepts channel-specific name, currency, tax_rate, food_tax_rate, and books_tax_rate; null removes an override. Prefer fractional tax values such as 0.20 for 20%.
Add a missing shop-owned country using POST /api/admin/channels/:id/countries/custom with code, name, and optional currency/tax fields. Delete a shop-owned country with DELETE /api/admin/channels/:id/countries/custom/:code; removal affects its assignments across the shop. Shared countries cannot be deleted through this route.
Payment methods
GET /api/admin/channels/:id/payment-methods reads the channel selection. PUT replaces it using method_codes:
{
"method_codes": ["card", "apple_pay", "google_pay"]
}
Use codes offered by the current payment-method configuration. An empty selection inherits the tenant-wide configuration. Wallet display also depends on provider/browser eligibility; selecting a code does not guarantee a wallet button on every device. See express checkout.
Found something unclear? Let us know