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
Scope
Label
Flags
orders:read
View orders
—
orders:write
Manage orders
—
order_cancellations:write
Cancel orders
—
order_returns:write
Process returns
—
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_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
Carts
Scope
Label
Flags
carts:read
View carts
—
carts:write
Manage carts
—
cart_items:read
View line items
—
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
—
Connectors
Scope
Label
Flags
connectors:read
View connectors
—
connectors:write
Manage connectors
—
connector_activations:write
Activate/deactivate 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:read
View go-live status
—
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
⚠ sensitivestaff only
admin:write
Perform admin actions
⚠ sensitivestaff 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.