RequestContext server-side, so once you’re authenticated, every endpoint behaves the same regardless of how you got there.
| Method | Token prefix | Use when | Revocable | Scoped |
|---|---|---|---|---|
| API key | pk_test_* / pk_live_* | Server-to-server integration from your backend | Yes, manually | Resource scopes |
| Agent token | agent_* | Simple agent auth, getting started | Yes, rotate | Per-agent |
| Ed25519 session | sess_* | Production agents | Yes, per-session | Per-agent |
| Portal token | portal_* | Customer-facing usage / billing API access | Yes, revoke | Operation-scoped |
| JWT session | eyJ… | The Sly dashboard UI | Auto-expires 15 min | User-scoped |
How to choose
Backend server integration
Use API keys. One key per environment (test/live), rotate on staff changes, store in a secrets manager.
Agent running on your infra
Start with agent tokens for simplicity; move to Ed25519 sessions before going live. Production agents should never send a long-lived secret over the wire.
Customer-facing dashboard that needs usage data
Use portal tokens. They’re scoped to read-only operations (e.g.
usage:read), safe to embed in a customer-facing iframe or browser app.Your own app UI (humans logging in)
JWT sessions via Supabase Auth. Used by the Sly dashboard itself; rarely what you want for server integrations.
How requests are authenticated
Every authenticated request carries a bearer token:RequestContext that includes:
tenantId— your organization (always set)environment—testorliveactorType—api_key|user|agent|portal- Method-specific fields —
apiKeyId,actorId+kyaTier,portalScopes, etc.
tenantId automatically. You cannot see another tenant’s data regardless of which method you use.
What’s public (no auth)
A small set of endpoints accept anonymous requests. You never need to authenticate to call these:/health,/ready— liveness / readiness checks/.well-known/ucp,/.well-known/agent.json— protocol discovery/v1/agents/:id/challenge,/v1/agents/:id/authenticate— the Ed25519 handshake/v1/openapi.json,/v1/protocols— spec + capability discovery/webhooks/*— inbound webhooks (signature-verified internally)/a2a,/agents— A2A JSON-RPC + ERC-8004 agent cards
Common pitfalls
Missing `Bearer` prefix
Missing `Bearer` prefix
The header must be
Authorization: Bearer <token>. Raw token without Bearer returns 401.Test key against production URL (or vice versa)
Test key against production URL (or vice versa)
pk_test_* keys only work on sandbox.getsly.ai. pk_live_* keys only work on api.getsly.ai. Mismatched environment → 401.Stale cached tokens in staging
Stale cached tokens in staging
The server caches verified tokens for 60 seconds for performance. A freshly-revoked token may work for up to 60 seconds after revocation. Don’t treat revocation as instantaneous blocking.
Ed25519 session token expired mid-flow
Ed25519 session token expired mid-flow
sess_* tokens expire after 1 hour. Catch 401 with { "error": "SESSION_EXPIRED" } and re-run the challenge-response handshake.