Management API
Manage keys, usage, members and budgets from scripts.
Everything you can do on your own pages, plus the workspace owner and admin pages, is also a REST call. The MCP server exposes the same actions as tools.
Tokens
The API uses management tokens, not API keys. Create one in Settings → Management tokens.
- Tokens start with
sk-spm-and are shown once. - A token acts as you, with your roles. It can't do anything you can't do in the app.
Readtokens can only callGETroutes.Read and writetokens can call all of them.- Tokens expire after 30, 90 or 365 days, or never. Pick when you create one; a token that never expires lasts until you revoke it.
- Tokens never work for model calls, and API keys never work here.
- Tokens can't create other tokens. That only happens in the app.
curl https://simpang.zakiego.com/api/manage/v1/me \
-H "Authorization: Bearer sk-spm-..."Responses
Success is 200 with { "data": ... }. Errors look like this:
{ "error": { "code": "read_only_token", "message": "This token is read-only. ..." } }| Status | Codes |
|---|---|
| 400 | invalid_request, invalid_json, nothing_to_change |
| 401 | invalid_token (missing, wrong, revoked or expired) |
| 403 | read_only_token, not_allowed, owners_only, super_admin_only, workspace_suspended |
| 404 | route_not_found, workspace_not_found, key_not_found, member_not_found, invite_not_found, budget_not_found |
| 409 | last_owner, no_models |
| 429 | rate_limited, with a Retry-After header |
Each token gets 120 calls a minute. Too many bad tokens from one IP gets that IP a short pause.
Routes
All paths are under /api/manage/v1. GET /api/manage/v1 lists them as JSON. Query params on GET routes take lists as a,b or repeated params.
You
| Method | Path | Scope | Does |
|---|---|---|---|
| GET | /me | read | Your account, the token's scope, and your workspaces |
| GET | /workspaces/:workspaceId/keys | read | Your keys, masked, with spend and limits |
| POST | /workspaces/:workspaceId/keys | write | New key. Body: name, expiresInDays, monthlyLimitUsd, modelAllowlist, rpmLimit, concurrencyLimit |
| PATCH | /workspaces/:workspaceId/keys/:keyId | write | Body: name and/or disabled |
| DELETE | /workspaces/:workspaceId/keys/:keyId | write | Revoke a key |
| GET | /workspaces/:workspaceId/models | read | Models you can call, with prices |
| GET | /workspaces/:workspaceId/usage | read | Overview. Query: range (24h, 7d, 30d, 90d), scope (me, workspace) |
| GET | /workspaces/:workspaceId/analytics | read | Time series, plus a breakdown by thinking budget. Query: range, scope, keys, models, clients |
| GET | /workspaces/:workspaceId/activity | read | Your requests. Query: range, key, model, status, client, stream, thinking, cursor, limit |
Workspace owners and admins
scope=workspace on usage and analytics also needs this role.
| Method | Path | Scope | Does |
|---|---|---|---|
| GET | /workspaces/:workspaceId | read | Budgets, models, members and open invites |
| PATCH | /workspaces/:workspaceId | write | Rename. Body: name |
| GET | /workspaces/:workspaceId/members/:memberId | read | One member with budgets, ledger and keys |
| PATCH | /workspaces/:workspaceId/members/:memberId | write | Body: role and/or models (null = all models) |
| DELETE | /workspaces/:workspaceId/members/:memberId | write | Remove a member. Anyone can remove themselves to leave |
| PUT | /workspaces/:workspaceId/members/:memberId/budgets/:period | write | Cap for day, week, month or total. Body: usdLimit (like "25.00"), tokenLimit |
| POST | /workspaces/:workspaceId/grants | write | Extra budget this period. Body: budgetId, usd, reason |
| GET | /workspaces/:workspaceId/invites | read | Invites and their status |
| POST | /workspaces/:workspaceId/invites | write | Body: email, role, expiresInDays. Returns the link once |
| DELETE | /workspaces/:workspaceId/invites/:inviteId | write | Revoke an invite |
| DELETE | /workspaces/:workspaceId/member-keys/:keyId | write | Revoke a member's key |
Same rules as the app: only owners touch owners, admins can't lift their own cap, and a workspace keeps at least one owner.