pk_test_) keys work immediately and let you build the full integration against the production API surface — only the live-money-movement paths are gated behind a manual approval.
You request live access by submitting a one-time declaration; a Sly admin reviews and approves (or denies) the request. Until then, any attempt to create a pk_live_ key, set X-Environment: live on a JWT session, or call a money-moving endpoint with a live key returns 403 FORBIDDEN.
State machine
| State | What it means | Live keys usable? |
|---|---|---|
sandbox_only | Default for new tenants. No declaration submitted yet. | ❌ |
declaration_pending | Declaration submitted; awaiting Sly admin review. | ❌ |
production_approved | Approved — pk_live_ keys can be minted and used. | ✅ |
production_denied | Admin denied the request. Re-declaration allowed. | ❌ |
production_suspended | Previously approved, then suspended by an admin. | ❌ |
What unlocks at production_approved
- Live API keys —
POST /v1/api-keysacceptsenvironment: 'live'(was blocked). - Live JWT sessions — dashboard users can flip the env toggle to Production in the header;
X-Environment: liveheaders are honored (instead of silently downgraded totestwithliveBlocked: true). - Live agent tokens — agents claimed into the tenant resolve to
environment: 'live'when the tenant is approved. - Strict beta ceilings apply (see Beta ceilings). Approval doesn’t grant unlimited volume — it grants audited volume up to a conservative cap.
POST /v1/api-keys with { environment: 'live' } or the dashboard’s API Keys page.
Request production access
Sign in as the organization owner
Only an owner signed in via the dashboard (JWT session) can submit a declaration. API keys and agent tokens cannot.
Submit the declaration
Send a
POST /v1/tenants/declare-production with your intended use case and accepted terms. SSO identity (verified email, name, provider, organization) is auto-attached server-side — you don’t re-enter it.Wait for review
Status flips to
declaration_pending. Sly admins review manually. You’ll receive an email + an in-app notification on decision.POST /v1/tenants/declare-production
Owner-JWT only. Allowed from sandbox_only and production_denied; rejected from declaration_pending, production_approved, and production_suspended.
| Field | Type | Required | Notes |
|---|---|---|---|
intended_use_case | string (20–1000 chars) | ✅ | Free-form description of what you’re building. The denser this is, the faster the review. |
expected_monthly_volume_usd | positive number | optional | Best-effort estimate. Influences your initial beta ceiling. |
website_url | URL | optional | Public-facing site or repo. Speeds up identity verification. |
accepted_terms | literal true | ✅ | Acceptance of the live-money-movement terms. |
202 Accepted
| Status | Code | When |
|---|---|---|
| 403 | FORBIDDEN | Caller is not an owner-JWT (e.g. API key, agent token, or non-owner user). |
| 403 | — | Tenant is in a state that does not allow declaration (declaration_pending, production_approved, production_suspended). |
| 400 | INVALID_REQUEST_FORMAT | Body fails schema validation (use case too short, terms not accepted, invalid URL). |
GET /v1/tenants/production-status
Read the current state — used by the dashboard’s Production Access page to render the gating banner and live-key CTA. Callable by any tenant context (owner JWT, member JWT, tenant API key).
Beta ceilings
Approval doesn’t unlock unlimited volume. During the open beta, every approved tenant operates under a strict platform-wide aggregate cap across all of its agents, regardless of per-agent KYA tier. The ceiling is enforced only in thelive environment — sandbox/test is unthrottled so onboarding, testing, and marketplace simulations stay fast.
| Limit | Default | What it means |
|---|---|---|
perTx | $100 | Largest single transaction (sum of items in one settlement). |
daily | $500 | Sum of all live transactions tenant-wide in a UTC day. |
monthly | $2,000 | Sum of all live transactions tenant-wide in a calendar month. |
apps/api/src/config/beta-ceilings.ts. Per-tenant overrides — beta_ceiling_per_tx, beta_ceiling_daily, beta_ceiling_monthly, beta_ceiling_disabled — are admin-settable as trust builds.
When a live transaction would breach the ceiling, the API returns:
exceeds_tenant_beta_ceiling_daily, exceeds_tenant_beta_ceiling_monthly. The same gate fires across all eight money paths (transfers, x402, ACP, AP2, UCP, streams) — there’s a single chokepoint in LimitService._checkTransactionLimitInner.
Re-declaring after a denial
If your declaration is denied, you can submit a revised one. Same endpoint, same shape — strengthen theintended_use_case based on the denial notes (returned in reviewNotes on GET /v1/tenants/production-status) and re-POST it. The state machine permits production_denied → declaration_pending.
How long does review take?
Manual review during the open beta typically lands within 1–3 business days. We’ll email the declaration owner the moment a decision is made; the in-app notification fires simultaneously. If you need a faster decision for a time-sensitive integration pilot, mention it inintended_use_case and we’ll prioritize the review.
Dashboard equivalent
If you prefer not to script the declaration, the dashboard exposes the same flow at Settings → Production Access. The form’s fields map 1:1 to the JSON body above; submission hits the same endpoint server-side and rewrites the status banner in place.Related
- Authentication overview — how
pk_test_vspk_live_keys differ and which routes require which scope - Environments — the test/live split, sandbox-only behavior, and what the
X-Environmentheader does - Scope grants — Epic 82’s per-action
treasuryscope, the other gate that fires on any money-moving call regardless of production status