Reliability

Workspace Environments

Throttle isolates production from every sandbox-provider environment inside the same workspace. Each workspace has one immutable production environment and can have multiple non-production environments such as test, UAT, and staging.

Environment-scoped keys

API keys are minted for a workspace environment. The raw key includes the environment slug, and every request is scoped to the key's environment end-to-end:

  • sk_<environment-slug>_* — secret key for server-side requests.
  • pk_<environment-slug>_* — publishable key for browser/frontend code. Publishable keys may hold only stateless compute scopes such as shipping_quotes:write and tax_calculations:write.
Environment variables
# API keys include the workspace environment slug.
# Production is immutable; non-production environments can be named for your flow.

THROTTLE_API_KEY=sk_uat_3e2e04df...             # non-production secret key
THROTTLE_PUBLISHABLE_KEY=pk_uat_290b29b1...     # non-production publishable key

# Production:
THROTTLE_API_KEY=sk_production_fbc6cab6...
THROTTLE_PUBLISHABLE_KEY=pk_production_06646787...
One workspace, many isolated environments
Carts, discounts/promotions, orders, payments, subscriptions, shipping/tax settings, invoices, Net-N customer terms, dashboard views, webhooks, API keys, and connector state all carry an environmentId. A UAT cart never becomes a production order, and a production webhook endpoint never receives UAT events.

Dashboard environment selector

The dashboard topbar selector chooses the active workspace environment for reads and setup writes. Production workspaces can switch between production and any active non-production environment. Workspaces that have not completed go-live can work in non-production environments until production is available. Create and archive custom environments from Workspace Settings → Environments.

Dashboard API selection
// Dashboard and Clerk-authenticated setup calls select an environment explicitly.
// The selected id comes from GET /api/v1/workspaces/{workspaceId}/environments.

await fetch('https://api.usethrottle.dev/api/v1/api-keys', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer <dashboard-session>',
    'X-Throttle-Application-Id': '<applicationId>',
    'X-Throttle-Environment-Id': '<workspace-environment-uuid>',
    'content-type': 'application/json',
  },
  body: JSON.stringify({
    name: 'UAT backend',
    scopes: ['orders:read', 'payments:write'],
  }),
});

Manage environments

Every workspace starts with one immutable production environment. Create additional environments for UAT, staging, or QA; each custom environment is non-production and routes to sandbox-provider credentials. Production cannot be created, archived, or deleted. Archiving a custom environment removes it from normal selectors and prevents new work in that environment; historical rows keep their environment id for audit and reporting.

Environment API
# List active environments
curl https://api.usethrottle.dev/api/v1/workspaces/<workspaceId>/environments \
  -H "Authorization: Bearer <dashboard-session>"

# Include archived environments for settings/audit screens
curl "https://api.usethrottle.dev/api/v1/workspaces/<workspaceId>/environments?includeArchived=true" \
  -H "Authorization: Bearer <dashboard-session>"

# Create a non-production sandbox-provider environment
curl -X POST https://api.usethrottle.dev/api/v1/workspaces/<workspaceId>/environments \
  -H "Authorization: Bearer <dashboard-session>" \
  -H "content-type: application/json" \
  -d '{ "slug": "uat", "name": "UAT" }'

# Archive a custom non-production environment
curl -X DELETE https://api.usethrottle.dev/api/v1/workspaces/<workspaceId>/environments/8a5f2d1e-3d2a-4d24-93a1-fd3f9e1f37f0 \
  -H "Authorization: Bearer <dashboard-session>"

API keys are environment-scoped

GET, POST, and DELETE /api/v1/api-keys act only on the request's selected environment. Create separate keys for production, UAT, staging, or any other non-production environment you run.

Cross-environment access returns 403
If a credential from one workspace environment accesses a resource from another environment, Throttle returns 403 environment_mismatch. Use a key for the correct environment, or select the matching X-Throttle-Environment-Id for dashboard-session setup calls.

Payment provider environments

Throttle uses the workspace environment to choose the provider environment. Production routes to production processors; non-production environments route to sandbox-provider wiring such as the Card Simulator or sandbox payment processor.

Provider routing
// Provider routing comes from the selected workspace environment:
//
//   kind=production      -> providerEnvironment=production
//   kind=non_production  -> providerEnvironment=sandbox
//
// Your code sends the environmentId (or uses an API key minted in that
// environment); the API resolves the payment provider wiring automatically.
Production entitlement gate
Production payment paths require production entitlement. Non-production environments are available for integration work before go-live.

Webhook environment routing

Outbound webhook endpoints are scoped to a workspace environment. Events carryenvironmentId in the delivered envelope and are delivered only to endpoints in the same environment.

Register an environment-scoped webhook endpoint
POST /api/v1/webhook-endpoints
{
  "url": "https://shop.example.com/webhooks/throttle/uat",
  "enabledEvents": ["order.created", "payment.captured"]
}

// Delivery envelope:
{
  "id": "evt_...",
  "type": "order.created",
  "version": "1",
  "createdAt": "2026-06-03T12:00:00.000Z",
  "environmentId": "8a5f2d1e-3d2a-4d24-93a1-fd3f9e1f37f0",
  "workspaceId": "ws_...",
  "data": {}
}

Cheat sheet

  • Use non-production environment keys such as sk_uat_* for development and UAT.
  • Use environmentId to choose dashboard-session setup scope; API keys already carry their environment.
  • Going live makes the immutable production environment usable for production payment paths without changing the structure of your integration code.