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 stateless compute scopes only — shipping_quotes:write and tax_calculations:write — and can never read carts, orders, customers, payment methods, or PII. (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): the two stateless compute scopes shipping_quotes:write and tax_calculations:write. 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.

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

ScopeLabelFlags
orders:readView orders
orders:writeManage orders
order_cancellations:writeCancel orders
order_returns:writeProcess returns

Payments

ScopeLabelFlags
payments:readView payments
payments:writeCreate payments
payment_authorizations:writeAuthorize payments
payment_captures:writeCapture payments
payment_refunds:readView refunds⚠ sensitive
payment_refunds:writeRefund payments⚠ sensitive
payment_voids:writeVoid payments⚠ sensitive
payment_disputes:readView disputes⚠ sensitive
payment_disputes:writeHandle disputes⚠ sensitive
payment_methods:readView payment methods⚠ sensitive
payment_methods:writeTokenize payment methods⚠ sensitive

Customers

ScopeLabelFlags
customers:readView customers
customers:writeManage customers
customer_pii:readView customer PII⚠ sensitive
customer_addresses:readView addresses
customer_addresses:writeManage addresses
customer_payment_methods:readView stored cards⚠ sensitive
customer_payment_methods:writeManage stored cards⚠ sensitive

Carts

ScopeLabelFlags
carts:readView carts
carts:writeManage carts
cart_items:readView line items
cart_items:writeManage line items
checkout_sessions:readView checkout sessions
checkout_sessions:writeManage checkout sessions

Discounts

ScopeLabelFlags
discounts:readView discounts
discounts:writeManage discounts

Subscriptions

ScopeLabelFlags
subscriptions:readView subscriptions
subscriptions:writeManage subscriptions
subscription_pauses:writePause/resume subscriptions
subscription_cancellations:writeCancel subscriptions
subscription_usage:readView subscription usage
subscription_usage:writeReport subscription usage

Fulfillments

ScopeLabelFlags
fulfillments:readView fulfillments
fulfillments:writeManage fulfillments
fulfillment_shipments:writeUpdate shipments
fulfillment_digital:readView digital delivery
fulfillment_digital:writeManage digital delivery
fulfillment_access:writeManage access credentials
fulfillment_services:writeManage service fulfillment

Invoices / AR

ScopeLabelFlags
invoices:readView invoices & aging
invoice_payments:writeMark invoices paid⚠ sensitive
invoice_dunning:writeSend dunning notices

Shipping & Tax

ScopeLabelFlags
shipping_tax:readView shipping/tax config
shipping_tax:writeEdit shipping/tax config
shipping_tax_publications:writePublish shipping/tax config
shipping_quotes:writeRequest shipping quotespk_ ok
tax_calculations:writeCalculate taxpk_ ok
shipping_tax_quote_tokens:readView quote tokens
shipping_tax_quote_tokens:writeManage quote tokens
shipping_tax_snapshots:writeAccept external snapshots

Connectors

ScopeLabelFlags
connectors:readView connectors
connectors:writeManage connectors
connector_activations:writeActivate/deactivate connectors

Webhooks & Events

ScopeLabelFlags
webhooks:readView webhooks
webhooks:writeManage webhooks
webhook_deliveries:readView deliveries
webhook_deliveries:writeRetry deliveries
events:readView events
audit_logs:readView audit log

Applications

ScopeLabelFlags
applications:readView applications
applications:writeManage applications

Workspace

ScopeLabelFlags
merchant:readView workspace settings
merchant:writeEdit workspace settings
embed_config:readView embed config
embed_config:writeEdit embed config
branding:writeUpload branding assets

Team

ScopeLabelFlags
team_members:readView members
team_members:writeManage members
team_invites:readView invites
team_invites:writeManage invites

Platform billing

ScopeLabelFlags
billing:readView billing
billing:writeManage subscription
billing_payment_methods:readView billing cards
billing_payment_methods:writeManage billing cards

Email

ScopeLabelFlags
email_templates:readView email templates
email_templates:writeEdit email templates
email_settings:readView email settings
email_settings:writeEdit email settings

Go-live

ScopeLabelFlags
go_live:readView go-live status
go_live:writeSubmit go-live

Partner

ScopeLabelFlags
partner:readView partner profile
partner:writeEdit partner profile
affiliates:readView affiliates
affiliates:writeManage affiliates

Notifications

ScopeLabelFlags
notifications:writeSend notifications
preferences:readView preferences
preferences:writeEdit preferences

Integrations

ScopeLabelFlags
integrations:readView integrations
integrations:writeManage integrations

Support

ScopeLabelFlags
support:readView support tickets
support:writeManage support tickets

Admin (staff)

ScopeLabelFlags
admin:readView admin data⚠ sensitivestaff only
admin:writePerform admin actions⚠ sensitivestaff only

Extensions

ScopeLabelFlags
extensions:readView extensions & installs
extensions:writeAuthor, version & publish extensions
extensions:installInstall, 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", ...], ... }
  }
}