s46 API
Production contract for s46 consumers: an org-scoped, invite-gated control plane plus a vendor-compatible model gateway.
Two base URLs
The control plane handles identity and configuration; the harness gateway handles model calls.
https://api.s46.dev
Auth, account, teams, sessions, admin, models, worker control.
https://gateway.s46.dev
OpenAI-, and Anthropic-compatible model calls.
Quickstart
From invite to your first model call in five minutes — CLI or raw HTTP.
Make your first call →Conventions
Auth headers, rate limits, idempotency, pagination, versioning.
Read the rules →Errors
One envelope, one code catalog. Branch on status plus code.
See all codes →Build in this order
| # | Step | Where |
|---|---|---|
1 | Check status endpoints and wire JSON error handling. | Operations |
2 | Implement auth; store device-bound access and refresh credentials. | Auth |
3 | Read the current account, then resolve the selected team's metadata. | Account · Teams |
4 | Use the team's endpoint, defaultModel, and models to call the gateway. | Gateway |
5 | If the user is an org/team admin, expose admin and model-policy routes. | Admin · Models |
6 | If you are building infrastructure, implement the worker control protocol. | Worker control |
Core rules
- The API is org-scoped. Teams use canonical
@org/teamidentifiers, e.g.@s46/engineering. - User-facing clients use user-scoped bearer tokens from the invite-gated device flow.
- Admin authorization accepts only
ownerandadminroles. - Membership roles are exactly
owner,admin,member, andviewer.
Request conventions
Authenticated JSON endpoints expect a bearer token and JSON content negotiation:
Authorization: Bearer <accessToken>
Accept: application/json
Content-Type: application/jsonBrowser flows may instead use the HTTP-only s46_access / s46_refresh cookies returned when a login or refresh request sends X-S46-Use-Cookies: true.
Path parameters must be URL path-escaped. This matters for team IDs, emails, device IDs, worker/job/session IDs:
| Value | Path segment |
|---|---|
@s46/engineering | %40s46%2Fengineering |
dscape@s46.dev | dscape%40s46.dev |
@dscape/auth-redirect-fix | %40dscape%2Fauth-redirect-fix |
Query parameters must be query-escaped, e.g. ?team=%40s46%2Fengineering.
Route groups
| Group | Prefix | Start here |
|---|---|---|
| Operations | /healthz · /readyz · /debug/vars | Status and diagnostics |
| Auth | /v1/auth · /device | Sign in and refresh |
| Account | /v1/me · /v1/devices | User and devices |
| Teams / sessions | /v1/teams · /v1/sessions | Team config and sessions |
| Admin | /v1/admin | Orgs, people, workers, jobs |
| Models | /v1/admin/models · /v1/admin/model-policies | Certified models and policy |
| Worker control | /v1/worker · /v1/internal | Register and lease jobs |
| Harness gateway | gateway.s46.dev | Model APIs |
Error envelope
Every JSON failure uses the same shape. Branch on HTTP status plus error.code; never parse message for control flow.
{
"error": {
"code": "invalid_request",
"message": "invalid request"
}
}