Skip to content
DocsAPI reference

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

MethodPathPurpose
GET/api/admin/channelsList channels
GET/api/admin/channels/:idRead channel
POST/api/admin/channelsCreate a channel
PATCH/api/admin/channels/:idUpdate configuration
POST/api/admin/channels/:id/set-defaultChoose the active default channel
DELETE/api/admin/channels/:idDelete 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:

  1. A configured active channel matching the request's Origin hostname, falling back to Referer.
  2. An active channel matching a path prefix such as /en/api/store/products.
  3. 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:

json
{
  "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.

json
{
  "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:

json
{
  "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:

json
{
  "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.

Source reviewed Checked against kernel c2e229b.

Found something unclear? Let us know

Start exploring

NavigateOpenEscClose