Workspace

API Key Scopes Reference

Every Throttle API route declares a single required scope — a resource:action string such as orders:read or payment_refunds:write. API keys are gated purely by the scopes they hold; dashboard (Clerk) users are gated by role-based permissions instead. The two systems compose — they never replace one another.

Secret vs publishable keys

API keys come in two prefixes. Secret keys (sk_) are full-power, server-side credentials — keep them on your backend and never expose them. Publishable keys (pk_) are safe to embed in browser or frontend code. Because a publishable key is application-scoped and exposed in the browser, it is restricted to a small, curated set of publishable-allowed scopes — five today: shipping_quotes:write, tax_calculations:write, storefront_scripts:read, storefront_scripts:write, and customer_accounts:write — and can never read carts, orders, customers, payment methods, or PII directly. That last scope is a deliberate exception to "publishable means stateless compute"; see the buyer plane below. (Listing available payment methods needs no key: GET /v1/payment-methods is public.) Create either type from Developers → API keys in the dashboard.

How scope checks work

On every API-key request Throttle reads the matched route's required scope and checks it against the key's granted scopes using these rules:

Implication

  • Exact match grants the scope.
  • resource:write implies resource:read on the same resource — holding a write scope lets you read it too.
  • There is no cross-resource implication: orders:write does not grant order_returns:write or payment_refunds:write. Each financial or destructive action is its own scope.
  • read never implies write.

The wildcard

  • * grants full access to every scope. It is only grantable to secret (sk_) keys.
  • Publishable (pk_) keys can never hold *.
  • Prefer the smallest set of explicit scopes; reserve * for trusted server-side keys.
Missing scope returns 403
A request whose key lacks the route's scope returns 403 with error.code = "insufficient_scopes" and a details.required field naming the missing scope.

Key types & grantable scopes

Secret keys (sk_)

  • May hold any non–staff-only scope, or the wildcard.
  • Staff-only scopes (the admin:* family) are not grantable to workspace-minted keys — those routes are gated by Throttle Staff org membership in Clerk, never by an API key. Requesting one returns 400 invalid_scope.

Publishable keys (pk_)

  • Browser-safe. May hold only the publishable-allowed subset (marked pk_ ok below) — five scopes today: the two stateless compute scopes shipping_quotes:write and tax_calculations:write; the storefront-script loader's storefront_scripts:read and storefront_scripts:write; and customer_accounts:write, which gates the buyer-auth plane rather than granting a data-reading permission — see the buyer plane below. A publishable key can never read carts, orders, customers, payment methods, or PII — those scopes are not publishable. (Listing the eligible payment methods for a session needs no key at all: GET /v1/payment-methods is public.)
  • Any non-publishable scope — or the wildcard — returns 400 invalid_scope.

The buyer plane: a publishable key is not a permission

The model this page has never stated before

A publishable key identifies an application. On the buyer plane it is not a permission. Storefront customer-account endpoints are authorised by the shopper's session, not by the key's scopes — the key only selects which application the shopper is signing in to. The one scope that gates that plane is customer_accounts:write: without it, a publishable key cannot reach customer accounts at all.

Every other publishable scope (shipping_quotes:write, tax_calculations:write, storefront_scripts:read, storefront_scripts:write) authorises a stateless compute or a public read directly off the key itself. customer_accounts:write works differently: holding it only unlocks the /v1/storefront/* route family (see Storefront Customer Auth ). Every action a buyer actually takes there — reading their orders, changing an address, removing a saved card — is authorised by their own Authorization: Bearer session token, never by the key. Two different applications' publishable keys can both hold customer_accounts:write and still never see each other's buyers; the key only decides which application a login or register request lands on.

Customer PII: redacted, not rejected

customer_pii:read gates personal fields on a customer record — email, phone, firstName, lastName, and the combined name some endpoints return. A credential that can read (or write) customers but lacks this scope does not get a 403: the request succeeds and those fields come back null, with every other field (id, externalId, company, addresses, order/subscription linkage) intact — the same "redact, not reject" pattern the picker warning on ⚠ sensitive exists to flag. This applies whether the customer came back from a read, or is the record echoed back by a create/update call. Because customer_pii:read is sensitive, an OAuth connection to an AI assistant (the MCP integration flow) can never hold it — see the MCP docs for which tools therefore always return redacted customer data. It is the one sensitive scope an automation connector (Zapier, Make — an OAuth client registered for the REST API) may be granted, and the consent screen names it. A connector without it gets the same redaction, and creating, changing or replaying a webhook endpoint returns 403 oauth_customer_pii_required, because deliveries carry the full record.

Storefront quote tokens: qt_

Shipping/tax quote tokens minted from Developers → Shipping & Tax → Tokens (or POST /api/v1/shipping-tax/quote-tokens) now start with qt_, not pk_. A quote token is a separate, narrower credential from a publishable API key — valid only for POST /api/v1/shipping-tax/quotes — even though older tokens were minted with a pk_ prefix before this split. Tokens minted before the change keep their pk_ prefix and remain valid indefinitely; the quote endpoint accepts either prefix. Presenting a qt_ token as X-API-Key on any other route returns 401 quote_token_not_api_key — a distinct code from the generic invalid-key error, naming the mix-up rather than leaving a merchant to guess why a token that works on the quotes endpoint fails everywhere else.

Scope catalog

Every scope, grouped as it appears in the dashboard picker. A scope marked ⚠ sensitive triggers a picker warning (financial, destructive, or PII); pk_ ok means a publishable key may hold it; staff only means it is unreachable by any workspace key. Unless a row lists both, the resource exposes only the action shown.

Orders

Scope Label Flags
orders:read View orders —
orders:write Manage orders —
order_cancellations:write Cancel orders —
order_returns:read View returns —
order_returns:write Process returns —
order_comps:write Comp orders (write off the balance) ⚠ sensitive
order_holds:write Freeze and unfreeze orders —

Quotes

Scope Label Flags
quotes:read View quotes —
quotes:write Manage quotes —

Imports

Scope Label Flags
imports:read View data imports —
imports:write Run and undo data imports —

Payments

Scope Label Flags
payments:read View payments —
payments:write Create payments —
payment_authorizations:write Authorize payments —
payment_captures:write Capture payments —
payment_refunds:read View refunds ⚠ sensitive
payment_refunds:write Refund payments ⚠ sensitive
payment_voids:write Void payments ⚠ sensitive
payment_records:write Record payments received outside Throttle ⚠ sensitive
payment_disputes:read View disputes ⚠ sensitive
payment_disputes:write Handle disputes ⚠ sensitive
payment_methods:read View payment methods ⚠ sensitive
payment_methods:write Tokenize payment methods ⚠ sensitive

Customers

Scope Label Flags
customers:read View customers —
customers:write Manage customers —
customer_pii:read View customer PII ⚠ sensitive
customer_addresses:read View addresses —
customer_addresses:write Manage addresses —
customer_payment_methods:read View stored cards ⚠ sensitive
customer_payment_methods:write Manage stored cards ⚠ sensitive

Customer accounts

Scope Label Flags
customer_accounts:write Let shoppers register, sign in and manage their account pk_ ok

Carts

Scope Label Flags
carts:read View carts —
carts:write Manage carts —
cart_items:write Manage line items —
checkout_sessions:read View checkout sessions —
checkout_sessions:write Manage checkout sessions —

Discounts

Scope Label Flags
discounts:read View discounts —
discounts:write Manage discounts —

Subscriptions

Scope Label Flags
subscriptions:read View subscriptions —
subscriptions:write Manage subscriptions —
subscription_pauses:write Pause/resume subscriptions —
subscription_cancellations:write Cancel subscriptions —
subscription_usage:read View subscription usage —
subscription_usage:write Report subscription usage —

Fulfillments

Scope Label Flags
fulfillments:read View fulfillments —
fulfillments:write Manage fulfillments —
fulfillment_shipments:write Update shipments —
fulfillment_digital:read View digital delivery —
fulfillment_digital:write Manage digital delivery —
fulfillment_access:write Manage access credentials —
fulfillment_services:write Manage service fulfillment —

Invoices / AR

Scope Label Flags
invoices:read View invoices & aging —
invoice_payments:write Mark invoices paid ⚠ sensitive
invoice_dunning:write Send dunning notices —

Shipping & Tax

Scope Label Flags
shipping_tax:read View shipping/tax config —
shipping_tax:write Edit shipping/tax config —
shipping_tax_publications:write Publish shipping/tax config —
shipping_quotes:write Request shipping quotes pk_ ok
tax_calculations:write Calculate tax pk_ ok
shipping_tax_quote_tokens:read View quote tokens —
shipping_tax_quote_tokens:write Manage quote tokens —
shipping_tax_snapshots:write Accept external snapshots —

Scripts

Scope Label Flags
storefront_scripts:read Load storefront scripts pk_ ok
storefront_scripts:write Report storefront script load outcomes pk_ ok
application_scripts:read View merchant-authored scripts —
application_scripts:write Create, edit and disable merchant-authored scripts —
extension_scripts:read View an extension's buyer-facing scripts —
extension_scripts:write Create, edit and delete an extension's buyer-facing scripts —

Connectors

Scope Label Flags
connectors:read View connectors —
connectors:write Manage connectors —

Webhooks & Events

Scope Label Flags
webhooks:read View webhooks —
webhooks:write Manage webhooks —
webhook_deliveries:read View deliveries —
webhook_deliveries:write Retry deliveries —
events:read View events —
audit_logs:read View audit log —

Applications

Scope Label Flags
applications:read View applications —
applications:write Manage applications —

Workspace

Scope Label Flags
merchant:read View workspace settings —
merchant:write Edit workspace settings —
embed_config:read View embed config —
embed_config:write Edit embed config —
branding:write Upload branding assets —

Team

Scope Label Flags
team_members:read View members —
team_members:write Manage members —
team_invites:read View invites —
team_invites:write Manage invites —

Platform billing

Scope Label Flags
billing:read View billing —
billing:write Manage subscription —
billing_payment_methods:read View billing cards —
billing_payment_methods:write Manage billing cards —

Email

Scope Label Flags
email_templates:read View email templates —
email_templates:write Edit email templates —
email_settings:read View email settings —
email_settings:write Edit email settings —

Go-live

Scope Label Flags
go_live:write Submit go-live —

Partner

Scope Label Flags
partner:read View partner profile —
partner:write Edit partner profile —
affiliates:read View affiliates —
affiliates:write Manage affiliates —

Notifications

Scope Label Flags
notifications:write Send notifications —
preferences:read View preferences —
preferences:write Edit preferences —

Integrations

Scope Label Flags
integrations:read View integrations —
integrations:write Manage integrations —

Support

Scope Label Flags
support:read View support tickets —
support:write Manage support tickets —

Admin (staff)

Scope Label Flags
admin:read View admin data ⚠ sensitive staff only
admin:write Perform admin actions ⚠ sensitive staff only

Extensions

Scope Label Flags
extensions:read View extensions & installs —
extensions:write Author, version & publish extensions —
extensions:install Install, configure & manage extensions —

Migration from coarse scopes

Throttle previously used ~27 coarse scopes (for example a single payments:write). Those were replaced with the granular catalog above. Existing keys keep working unchanged:

  • Each legacy scope expands to the superset of granular scopes it used to cover — so a key with the old payments:write now holds payment_authorizations:write, payment_captures:write, payment_refunds:write, and the rest of the payment family. No power is lost.
  • stores:read and stores:write are deprecated aliases for applications:read / applications:write, still accepted on input and expanded at evaluation time. New keys should request applications:read / applications:write directly.
API-key scopes are immutable
There is no endpoint to edit the scopes on an existing API key. To change a key's scopes, revoke it and create a new one with the scopes you want. (Extension manifest scopes, by contrast, are editable via PATCH /api/v1/extensions/{id}.)

Machine-readable catalog

GET /api/v1/scopes returns the full catalog as JSON — every scope definition (id, resource, action, group, label, sensitive, staffOnly, publishableAllowed, extensionAllowed, implies) plus the group ordering. Build a scope picker or validate requested scopes against it rather than hard-coding the list.

        {
  "data": {
    "scopes": [
  {
    "id": "payment_refunds:write",
    "resource": "payment_refunds",
    "action": "write",
    "group": "Payments",
    "label": "Refund payments",
    "sensitive": true,
    "staffOnly": false,
    "publishableAllowed": false,
    "extensionAllowed": true,
    "implies": ["payment_refunds:read"]
  }
  // ...
    ],
    "groups": { "Payments": ["payments:read", "payments:write", ...], ... }
  }
}