Workspaces, members and principals
Members, scoped keys and end-user quotas.
Every inference key belongs to one organization, one workspace and one principal. A principal is the identity a key acts for: a service, an end user or a member. Use workspaces and principals to split limits and usage inside an organization. To sync members and groups from an identity provider, use SCIM provisioning.
In the console, open Team > Members and Team > Workspaces.
Rules for keys and principals
- A key's organization, workspace and principal cannot change. To change them, mint a new key.
- All keys of one principal share its RPM, TPM and concurrency limits.
- Request values never authenticate a principal:
user,metadata,x-user-id,x-tm-principal-idandx-tm-workspace-id. - Your backend creates an end-user principal and keeps that principal's key. Do not let an end user choose a different backend key.
- There is no per-request delegation or SSO.
These keys use the organization's Default workspace and its shared _default service principal:
- existing keys;
- keys created through browser onboarding;
- keys created in the console, unless you choose another workspace there.
A shared older key keeps its access, but RouterPlus cannot tell its individual users apart.
Management authentication
Management calls use a verified console session cookie. Inference keys have no management rights.
x-tm-org-id: <UUID>selects an organization. The session email must be an active member of it. The header never grants access.- Without the header, RouterPlus picks the caller's own organization first, then their oldest active membership.
GET /api/identity/organizationslists your memberships.- The console shows your default organization.
/console/byokand the playground take?org=<UUID>to switch. Manage the other identities with the API below.
Request rules:
- POSTs need
Origin: https://demo.routerplus.com(origin only) andContent-Type: application/json. - Responses are not cacheable.
- Adding a membership sends no invitation or email.
- RouterPlus normalizes membership and member-principal emails like account emails: lowercase,
+tagremoved, and Gmail dots and domain normalized.
| Role | Read org configuration | Manage workspaces, principals, keys, connections, policies, limits | Manage members |
|---|---|---|---|
| owner | Yes | Yes | Yes |
| admin | Yes | Yes | No |
| viewer | Yes | No | No |
This API cannot disable, demote or replace the initial owner.
Workspace roles
A person also has a role in each workspace: admin, member or viewer.
- An org owner or admin is a workspace admin in every workspace.
- An org viewer is a workspace viewer, unless the workspace has a row for them. Then they get that row's role in that workspace only.
- Set a row with
PUT /v1/workspaces/<id>/members/<email>and{role}.
| Workspace role | View usage | Create keys | Disable keys | Manage members and settings |
|---|---|---|---|---|
| admin | Yes | Yes | Yes | Yes |
| member | Yes | Yes | Yes | No |
| viewer | Yes | No | No | No |
- The workspace role applies to key and principal writes, in the console and in the API below.
- A key's workspace is the workspace of its principal.
- A write that the role does not allow returns
403with the reason. - The API keys page in the console shows your role in each workspace.
- Capping or copying a key needs an org owner or admin.
- Removing a membership removes that person's access to this organization. Their memberships in other organizations stay valid.
Identity endpoints
Each list GET returns at most 500 entries. Use the returned UUIDs for later writes. A create returns 201. An update or a member write returns 200.
| Request | JSON body / result |
|---|---|
GET /api/identity/organizations | {organizations:[{org_id,name,role}]} |
GET /api/identity/members | {members:[{email,role,disabled}]} |
POST /api/identity/members | {email,role:"admin"|"viewer",disabled?:boolean}. Owner only. Creates or updates. |
GET /api/identity/workspaces | Workspace metadata and policy pointers |
POST /api/identity/workspaces | {name} → {workspace_id} |
POST /api/identity/workspaces/<id> | Any of {name,disabled,route_policy_id}. null clears its policy. |
GET /api/identity/principals | Principal metadata |
POST /api/identity/principals | {workspace_id,kind:"service"|"end_user"|"member",subject,member_email?} → {principal_id} |
POST /api/identity/principals/<id> | {disabled:boolean} |
GET /api/identity/keys | Metadata only, including workspace and principal bindings |
POST /api/identity/keys | {principal_id,name,connection_id?} → {key_id,key,copyable}. 300 RPM. copyable: true means an owner or admin can copy the key again at /console/keys. It is false when the organization has copying turned off. |
POST /api/identity/keys/<id> | {disabled:boolean}. Disabling deletes the key's copy, so it cannot be copied again. |
Principal fields:
subjectis a stable identifier from your backend. It is unique within a workspace and at most 160 characters. A leading_is reserved.kind:memberwith an existing member'smember_emailties the principal to that member. Revoking the membership also stops their inference keys.- An
end_userorserviceprincipal does not depend on a membership. Disable it to revoke it.
With connection_id, RouterPlus checks that the connection is active and belongs to the same organization. It then creates the key with that binding in one transaction, so an interrupted BYOK setup never leaves a key that RouterPlus funds. Without connection_id, key creation works as for any non-BYOK key.
Revocation
- Disabling a workspace denies all its keys.
- Disabling a principal denies all its keys.
- Disabling a member denies their control access and their
memberprincipals. - New requests see a revocation within 5 seconds. A stream already running can finish.
- A successful write returns only after every gateway can see it. If a write returns 503, check the state before you retry. The change may have saved anyway.
Routes, limits and usage
The restrictions in force are the intersection of org → workspace → key → request. Attach a routing policy to a workspace with POST /api/identity/workspaces/<id> and {route_policy_id:"..."}. A workspace policy cannot grant a route that an org or key policy denies.
The /api/admission-limits API accepts scope:"workspace" and scope:"principal", with the matching UUID in subject.
- The defaults for each are 300 RPM, 1,000,000 TPM and 8 concurrent requests.
- All org, key, model, platform and provider-pool limits also apply.
- These limits create no separate workspace or principal balances or spend caps. Money stays with the organization and the key.
- Set
outage_mode:"closed"when your contract needs RouterPlus to refuse work while the counters are down.
Usage:
GET /v1/usageand/v1/generation?id=...show the attempts of the calling principal and workspace, including its other keys.- Unknown generations, and generations of other principals, return 404.
- Org balance fields are
nullfor scoped principals. The default service principal keeps them. - The console shows org-wide accounting to authorized members.
- Each attempt's route record holds
workspaceId,principalIdand up to three policy revisions.
For agents: /docs/identity.md and /llms.txt