Canonical mapping of OAuth-style scopes (on the seller API key) to route groups. Keys with null or empty scopes receive 403 INSUFFICIENT_SCOPE — always create keys with the scopes you need.
Authoritative sellable list: GET /allocations (sellable: true) — not /products or /catalog/snapshot alone.
Console base scopes#
Keys created in Settings → Integrations → API Keys pre-select exactly these base scopes (from BASE_SELLER_API_KEY_SCOPES):
| Scope | Default |
|---|---|
seller:products:read | On |
seller:orders:preview | On |
seller:keys:pull | On |
seller:keys:write | On |
seller:refunds:read | On |
seller:refunds:write | On |
seller:promotions:read | On |
seller:promotions:respond | On |
seller:webhooks:read | On |
seller:webhooks:write | On |
Opt-in (not in the base set): seller:finance:read (finance summary / api-sales / invoices), seller:orders:manage (fulfilment revoke / regenerate) and seller:account:manage (read and change your selling footprint). Deselect anything your service does not need: least privilege per key.
seller:account:manage is the only scope a legacy key does not receive. Keys issued before scoping existed were backfilled with everything available at the time; that reasoning does not extend to a surface added afterwards, and this one changes the footprint your sales are settled against. Issue a key with the scope explicitly if you need it.
Endpoint matrix#
| Scope | Used for |
|---|---|
| (any scope) | GET /whoami, POST /geo/attest — require an authenticated key holding at least one seller scope; no specific scope is checked. |
seller:products:read | GET /partners, GET /products, GET /products/{id}, GET /products/{id}/pricing, GET /products/{id}/media/download, GET /platforms, GET /regions, GET /regions/{code}, GET /catalog/snapshot, GET /catalog/checksum, GET /catalog/changes, POST /catalog/exports, GET /catalog/exports/{exportId}, GET /availability, GET /availability/{skuCode}, GET /allocations, GET /allocations/requests, GET /requests/{requestId}, GET /integration/status, GET /usage, GET /activity. Legacy: still accepted for GET /transactions / GET /orders (prefer seller:orders:read). |
seller:orders:read | Preferred scope name for order reads: GET /orders, GET /orders/{orderId}, GET /transactions. seller:orders:write implies read; legacy seller:products:read / seller:keys:pull keys keep working indefinitely. |
seller:orders:write | Preferred scope name for order fulfilment — grants everything seller:keys:pull grants (see below), plus preview and order reads. Prefer this on new keys; legacy seller:keys:pull keys keep working indefinitely. |
seller:orders:preview | POST /orders/preview only (read-only checkout estimate; no inventory mutation) |
seller:keys:pull | POST /orders, POST /orders/bulk, POST /orders/cancel, POST /orders/reserve, POST /orders/commit, POST /orders/hold, DELETE /orders/hold, POST /orders/{orderId}/extend, POST /orders/{orderId}/fulfill, POST /keys/pull, POST /keys/export, POST /allocations/requests. Also grants POST /orders/preview if seller:orders:preview is absent. Legacy: still accepted for POST /keys/return, POST /refunds, POST /chargebacks/resolve, and GET /refunds (prefer dedicated refund scopes); superseded by seller:orders:write as the preferred name. |
seller:orders:fulfill | POST /orders/{orderId}/fulfill — reveal keys for a ready durable preorder or backorder. v1 also accepts seller:keys:pull and seller:orders:write. |
seller:orders:manage | POST /orders/fulfillments/{fulfillmentId}/revoke, POST /orders/fulfillments/{fulfillmentId}/regenerate (keyless hosted redemption / fulfilment management; opt-in at key creation) |
seller:refunds:write | POST /refunds, POST /keys/return, POST /chargebacks/resolve — storefront refund/chargeback callback, explicit key return, and chargeback resolution (all can quarantine keys and reverse settlement; does not refund your PSP). Preferred over seller:keys:pull for refund-only keys. |
seller:refunds:read | GET /refunds, GET /refunds/{refundId} — refund/chargeback status (pending / completed / chargeback states). Also accepted: seller:refunds:write, seller:finance:read, or legacy seller:keys:pull. |
seller:keys:write | GET /keys, POST /keys, DELETE /keys/{id}, PATCH /keys/{id}/allowed-ips, POST /keys/{id}/rotate |
seller:account:manage | GET /me/footprint, PUT /me/footprint: the countries and currencies you sell in. Your footprint narrows what your agreements grant and never widens it, and orders into a country you have not declared are refused with FOOTPRINT_COUNTRY_NOT_DECLARED. Not granted to legacy keys. |
seller:webhooks:read | GET /webhooks, GET /webhooks/event-types, GET /webhooks/{id}/deliveries, GET /events |
seller:webhooks:write | POST /webhooks, PATCH /webhooks/{id}, DELETE /webhooks/{id}, POST /webhooks/{id}/test, POST /webhooks/{id}/enable, POST /webhooks/{id}/deliveries/{deliveryId}/retry, POST /webhooks/{id}/deliveries/replay |
seller:promotions:read | GET /promotions/summary, GET /promotions/calendar, GET /promotions/shares, GET /promotions/shares/{id}, GET /promotions/shares/{id}/discounts, GET /promotions/deals, GET /promotions/deals/{id} |
seller:promotions:respond | POST /promotions/shares/{id}/accept, decline, POST /promotions/deals/{id}/respond |
seller:finance:read | GET /api/seller/v1/finance/summary, GET /api/seller/v1/finance/api-sales, GET /api/seller/v1/finance/invoices, GET /api/seller/v1/finance/statements. Unversioned /api/seller/finance/... redirects to /v1/. See Partner runbook for finance reads and reconciliation. |
Unauthenticated endpoints: GET /api/seller/v1/whoami-ip (echoes the
request's client IP), GET /api/seller/v1/health (auth optional),
GET /api/seller/v1/webhooks/egress-ips, POST /api/seller/oauth/token
(client credentials, no Bearer), the buyer-side geo attestation callbacks
POST /geo/attest/{attestId}/complete / GET /geo/attest/{attestId}/pixel
(secured by the attestation id, called from the checkout page), and
GET /api/seller/v1/openapi / /docs are intentionally key-free. Everything
else requires a Bearer key holding the scope listed above.
An IP allowlist is optional: a key with no
allowed_ips entries accepts requests from any source IP. Once you configure
entries, requests from other addresses are rejected with 403 IP_NOT_ALLOWED.
Finance base path: Canonical /api/seller/v1/finance/.... Same host and Authorization: Bearer as the rest of the Seller API. Unversioned /api/seller/finance/... redirects to /v1/.
Key lifecycle (expiry, create-then-retire vs in-place rotate, ~60s revocation): Authentication.
See also Integration recipes and Sandbox for 403 triage.
Related#
- Quickstart — create a key with the right scopes before your first order
- Authentication — credentials, expiry, rotation
- IP allowlist — optional egress IP restrictions (enforced only when configured)
- Integration recipes — scopes and call order per flow
- Error playbook —
INSUFFICIENT_SCOPE,IP_NOT_ALLOWED, and recovery actions