Keys
Mint, list, edit and revoke scoped caller keys.
6 operations. Errors link to their row on the overview.
List caller keyslink to List caller keys
GET /v1/keys
Every caller key on the account, revoked ones included. Never the hash. A caller key reads the list without person_email, prompt_history and person_limit_usd, which are the account owner's; a person key lists only its own person's keys.
A caller key holding keys:read (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Response 200
The keys.
objectstring requiredOne of
list.dataarray of CallerKey required29 fields
idstring requireduser_idstring requirednamestring requiredWhat the tool calls itself, 1-64 chars.
maskstring requiredThe only form shown after mint.
created_atstring (date-time) requiredlast_used_atstring (date-time)revoked_atstring (date-time)daily_limit_tokensnumberDaily spend cap in whole credits.
monthly_limit_tokensnumberMonthly spend cap in whole credits.
caps_unitstringOne of
credit.allowed_modelsarray of stringGlob allow-list over model names; absent = every model. With models_listed: the exact canonical ids the key may dial, and empty = none.
models_listedbooleantrue = the listed reading: allowed_models are literal canonical ids (no globs), the key lists exactly those as its per-app picker names, and an empty list allows nothing.
model_pinsobjectCanonical model id to the stable account id it is pinned to: a pinned model dials only that account, and one id pinned to two accounts gets two picker names.
model_aliasesobjectCanonical model id (a member of allowed_models) to the custom name its picker shows: 1-64 characters of letters, numbers, dots, dashes or colons; no Cursor routing word (claude, gemini, anthropic, sonnet-, opus-, haiku-, grok, composer); not a house id (superbot, superbot-fast, superbot-omni); unique among this key's forwards; not another model's id. A refused name stores nothing. A custom name replaces the default name for that model.
appstringForwarding app this listed key's model names are spelled for: cursor, copilot-cli, cline, roo, qwen-code, hermes, openclaw, zazen, default. Set at creation, cannot be changed. Absent = cursor.
default_modelstringThe model a call that names the bare house agent
superbot(the default model of Zapier and n8n), or names no model, is answered by instead:superbot-fast,superbot-omnior a model of one of your own accounts. A call that names any other model is dialled as named. Absent = a call namingsuperbotgetssuperbot.routestring requiredOne of
byo,credits,auto.modestring requiredOne of
model,agent.incognitoboolean requireddevice_idstringorg_idstringSet on a team key.
person_idstringSet on a key minted for a person:
per_+ 16 hex. Every key minted for the same person carries the same id. A person key has no device_id and no org_id, and is billed to the owner.person_namestringThe person's display name, 1-64 characters. Present on every person key.
person_emailstringThe person's email address, when the owner gave one.
person_groupstringA free-text grouping the owner sorts people by (a team, a class), 1-64 characters.
prompt_historyPromptHistoryWhat the owner told a person about their prompts, and how long they are kept. Absent on a key until the owner sets it: the person's prompts are then not visible to the owner and follow the account's own retention.
3 fields
visible_to_ownerboolean requiredThe owner may read this person's prompts.
retention_daysinteger requiredWhole days the prompts are kept, 1-3650.
attested_atstring (date-time) requiredISO 8601 time the owner attested the person was told. The owner's own claim, stored as given and not verified; the answer normalises it to UTC.
paused_atstring (date-time)Set while the owner holds this person: until a PATCH clears it the key answers 403
key_pausedat the model gateway, the/v1/keysroutes, the relay door and the Cosmos door; every other route does not recognise a held key and answers 401unauthorized. Held is not revoked. It is written to every live key of the person.person_limit_usdnumberThe owner's monthly spend limit for this person, in US dollars to the cent. Set by the owner's
PUT /v1/keys/person/{person_id}/limit(the Helper), written to every live key of the person, and absent while no limit is set.scopesarray of Scope requiredThe EFFECTIVE scopes: stored list or the legacy set, team keys capped. One of
gateway:invoke,usage:read,billing:read,keys:read,keys:write,endpoints:read,endpoints:write,teams:read,teams:write,devices:read,devices:write,runs:read,runs:write,mcp:invoke,turns:read,tools:invoke.
has_moreboolean requiredfirst_idstring | null requiredId of the first item on this page; pass as
before_idfor the previous page.last_idstring | null requiredId of the last item on this page; pass as
after_idfor the next page.keysarray of CallerKey requiredLegacy: the same rows as
data.29 fields
idstring requireduser_idstring requirednamestring requiredWhat the tool calls itself, 1-64 chars.
maskstring requiredThe only form shown after mint.
created_atstring (date-time) requiredlast_used_atstring (date-time)revoked_atstring (date-time)daily_limit_tokensnumberDaily spend cap in whole credits.
monthly_limit_tokensnumberMonthly spend cap in whole credits.
caps_unitstringOne of
credit.allowed_modelsarray of stringGlob allow-list over model names; absent = every model. With models_listed: the exact canonical ids the key may dial, and empty = none.
models_listedbooleantrue = the listed reading: allowed_models are literal canonical ids (no globs), the key lists exactly those as its per-app picker names, and an empty list allows nothing.
model_pinsobjectCanonical model id to the stable account id it is pinned to: a pinned model dials only that account, and one id pinned to two accounts gets two picker names.
model_aliasesobjectCanonical model id (a member of allowed_models) to the custom name its picker shows: 1-64 characters of letters, numbers, dots, dashes or colons; no Cursor routing word (claude, gemini, anthropic, sonnet-, opus-, haiku-, grok, composer); not a house id (superbot, superbot-fast, superbot-omni); unique among this key's forwards; not another model's id. A refused name stores nothing. A custom name replaces the default name for that model.
appstringForwarding app this listed key's model names are spelled for: cursor, copilot-cli, cline, roo, qwen-code, hermes, openclaw, zazen, default. Set at creation, cannot be changed. Absent = cursor.
default_modelstringThe model a call that names the bare house agent
superbot(the default model of Zapier and n8n), or names no model, is answered by instead:superbot-fast,superbot-omnior a model of one of your own accounts. A call that names any other model is dialled as named. Absent = a call namingsuperbotgetssuperbot.routestring requiredOne of
byo,credits,auto.modestring requiredOne of
model,agent.incognitoboolean requireddevice_idstringorg_idstringSet on a team key.
person_idstringSet on a key minted for a person:
per_+ 16 hex. Every key minted for the same person carries the same id. A person key has no device_id and no org_id, and is billed to the owner.person_namestringThe person's display name, 1-64 characters. Present on every person key.
person_emailstringThe person's email address, when the owner gave one.
person_groupstringA free-text grouping the owner sorts people by (a team, a class), 1-64 characters.
prompt_historyPromptHistoryWhat the owner told a person about their prompts, and how long they are kept. Absent on a key until the owner sets it: the person's prompts are then not visible to the owner and follow the account's own retention.
3 fields
visible_to_ownerboolean requiredThe owner may read this person's prompts.
retention_daysinteger requiredWhole days the prompts are kept, 1-3650.
attested_atstring (date-time) requiredISO 8601 time the owner attested the person was told. The owner's own claim, stored as given and not verified; the answer normalises it to UTC.
paused_atstring (date-time)Set while the owner holds this person: until a PATCH clears it the key answers 403
key_pausedat the model gateway, the/v1/keysroutes, the relay door and the Cosmos door; every other route does not recognise a held key and answers 401unauthorized. Held is not revoked. It is written to every live key of the person.person_limit_usdnumberThe owner's monthly spend limit for this person, in US dollars to the cent. Set by the owner's
PUT /v1/keys/person/{person_id}/limit(the Helper), written to every live key of the person, and absent while no limit is set.scopesarray of Scope requiredThe EFFECTIVE scopes: stored list or the legacy set, team keys capped. One of
gateway:invoke,usage:read,billing:read,keys:read,keys:write,endpoints:read,endpoints:write,teams:read,teams:write,devices:read,devices:write,runs:read,runs:write,mcp:invoke,turns:read,tools:invoke.
Errors
| Status | Code | What to change |
|---|---|---|
| 401 | unauthorized | Send a live caller key or session as |
| 403 | insufficient_scope | The key lacks the scope in |
curl
curl -sS -X GET "https://superbot.gg/v1/keys" \
-H "Authorization: Bearer $SUPERBOT_API_KEY"JavaScript
const res = await fetch(`https://superbot.gg/v1/keys`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
},
});
console.log(res.status, await res.json());Python
import os
import requests
res = requests.request(
"GET",
"https://superbot.gg/v1/keys",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
},
)
print(res.status_code, res.json())200 The keys.
{
"object": "list",
"data": [
{
"id": "ck_9f2c41d0",
"user_id": "your-user-id",
"name": "your-name",
"mask": "sbc_ab12…cd34",
"created_at": "2026-09-01T00:00:00Z",
"last_used_at": "2026-09-01T00:00:00Z",
"revoked_at": "2026-09-01T00:00:00Z",
"daily_limit_tokens": 0,
"monthly_limit_tokens": 0,
"caps_unit": "credit",
"allowed_models": [
"your-allowed-models"
],
"models_listed": true,
"model_pins": {},
"model_aliases": {},
"app": "your-app",
"default_model": "your-default-model",
"route": "byo",
"mode": "model",
"incognito": true,
"device_id": "your-device-id",
"org_id": "your-org-id",
"person_id": "per_9f2c41d0a7b35e68",
"person_name": "your-person-name",
"person_email": "[email protected]",
"person_group": "your-person-group",
"prompt_history": {
"visible_to_owner": true,
"retention_days": 0,
"attested_at": "2026-09-01T00:00:00Z"
},
"paused_at": "2026-09-01T00:00:00Z",
"person_limit_usd": 0,
"scopes": [
"gateway:invoke"
]
}
],
"has_more": true,
"first_id": "your-first-id",
"last_id": "your-last-id",
"keys": [
{
"id": "ck_9f2c41d0",
"user_id": "your-user-id",
"name": "your-name",
"mask": "sbc_ab12…cd34",
"created_at": "2026-09-01T00:00:00Z",
"last_used_at": "2026-09-01T00:00:00Z",
"revoked_at": "2026-09-01T00:00:00Z",
"daily_limit_tokens": 0,
"monthly_limit_tokens": 0,
"caps_unit": "credit",
"allowed_models": [
"your-allowed-models"
],
"models_listed": true,
"model_pins": {},
"model_aliases": {},
"app": "your-app",
"default_model": "your-default-model",
"route": "byo",
"mode": "model",
"incognito": true,
"device_id": "your-device-id",
"org_id": "your-org-id",
"person_id": "per_9f2c41d0a7b35e68",
"person_name": "your-person-name",
"person_email": "[email protected]",
"person_group": "your-person-group",
"prompt_history": {
"visible_to_owner": true,
"retention_days": 0,
"attested_at": "2026-09-01T00:00:00Z"
},
"paused_at": "2026-09-01T00:00:00Z",
"person_limit_usd": 0,
"scopes": [
"gateway:invoke"
]
}
]
}401 The bearer is missing, malformed or unknown.
{
"error": "unauthorized",
"message": "Send a live caller key or session as Authorization: Bearer … or x-api-key. No key yet: create one at /account/api, or sign a user in at /auth.md.",
"doc_url": "https://superbot.gg/developers#errors-unauthorized",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}403 The key lacks a scope (insufficient_scope), is revoked, or may not call this route.
{
"error": "insufficient_scope",
"message": "The key lacks the scope in required_scopes; mint a key that holds it.",
"doc_url": "https://superbot.gg/developers#errors-insufficient_scope",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Create a caller keylink to Create a caller key
POST /v1/keys
Mint a key. The plaintext is returned once. A caller key can only mint keys within its own reach: no scope, route, cap or model it does not hold. With person the key is minted for someone else and billed to you: the row carries person_id, person_name and the rest, and name defaults to the person's name. A bad person answers 400 invalid_person. Only the account owner (a signed-in session, a device or the account key) mints a key for a person: a caller key that sends person answers 403 caller_key_forbidden, and so does a person key minting any key. A person key minted with no scopes or preset holds gateway:invoke alone. A paused caller key answers 403 key_paused.
A caller key holding keys:write (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Request body
namestringWhat the tool calls itself, 1-64 chars. Required unless
personis given, then it defaults to the person's name.personKeyPersonThe person a key is minted for. Without
idit makes a new person (namerequired); withidit adds a key to that person. A person key stamps no device (the minting device's logout never revokes it), takes noorg_idand is billed to the owner.4 fields
namestringThe person's display name, 1-64 printable characters (no
<,>,"or'). Required for a new person; withidit must equal the stored name or be left out.emailstringThe person's email address. With
idit must equal the stored one or be left out.groupstringA free-text grouping, 1-64 characters. With
idit must equal the stored one or be left out.idstringThe
person_idof a person already on this account: adds another key for them, which inherits the stored name, email, group, prompt_history and paused_at (a paused person's new key is born paused). Rotating a key is a mint with the sameid, then a revoke of the old key.
routestringOne of
byo,credits,auto.modestringOne of
model,agent.daily_limit_tokensnumberDaily spend cap in whole credits.
monthly_limit_tokensnumberMonthly spend cap in whole credits.
allowed_modelsarray of stringGlob allow-list over model names; with models_listed, the exact canonical ids (no globs).
models_listedbooleantrue = the listed reading: the key dials exactly its allowed_models, listed as the per-app picker names; empty = none. A PATCH that omits it leaves it as it was.
model_pinsobject | nullCanonical model id to the stable account id it is pinned to (non-empty strings). A PATCH replaces the whole map; null clears it.
model_aliasesobject | nullCanonical model id (a member of allowed_models) to the custom name its picker shows (1-64 characters: letters, numbers, dots, dashes, colons). A PATCH replaces the whole map; null clears it. A refused name stores nothing and answers the reason. Removing a model from allowed_models drops its custom name.
default_modelstring | nullThe model a call that names the bare house agent
superbot(the default model of Zapier and n8n), or names no model, is answered by instead:superbot-fast,superbot-omni, or a model of one of your own accounts (claude-sonnet-5-5,gpt-5.5,custom/<endpoint>/<id>). A call that names any other model is dialled as named.nullorsuperbotclears it. A model of your own account needs a key on routeautoorbyoin modemodelwhoseallowed_modelsadmits it; a key on routecreditstakes a house model only, and a key withmodels_listedtakes none. The write is judged on the key as it will be stored, so a PATCH that would leave the default unusable (route credits, mode agent, a narrower list) answers 400invalid_default_model: senddefault_model: nullwith it. A PATCH that omits it leaves it as it was.incognitobooleanscopesarray of ScopeExplicit scopes; wins over
preset. One ofgateway:invoke,usage:read,billing:read,keys:read,keys:write,endpoints:read,endpoints:write,teams:read,teams:write,devices:read,devices:write,runs:read,runs:write,mcp:invoke,turns:read,tools:invoke.appstringForwarding app this listed key's model names are spelled for: cursor, copilot-cli, cline, roo, qwen-code, hermes, openclaw, zazen, default. Set at creation, cannot be changed. Absent = cursor.
presetstringA named scope set. One of
gateway,read_only,full.
Response 201
The new key.
keystring requiredThe plaintext
sbc_…key, shown once.rowCallerKey required29 fields
idstring requireduser_idstring requirednamestring requiredWhat the tool calls itself, 1-64 chars.
maskstring requiredThe only form shown after mint.
created_atstring (date-time) requiredlast_used_atstring (date-time)revoked_atstring (date-time)daily_limit_tokensnumberDaily spend cap in whole credits.
monthly_limit_tokensnumberMonthly spend cap in whole credits.
caps_unitstringOne of
credit.allowed_modelsarray of stringGlob allow-list over model names; absent = every model. With models_listed: the exact canonical ids the key may dial, and empty = none.
models_listedbooleantrue = the listed reading: allowed_models are literal canonical ids (no globs), the key lists exactly those as its per-app picker names, and an empty list allows nothing.
model_pinsobjectCanonical model id to the stable account id it is pinned to: a pinned model dials only that account, and one id pinned to two accounts gets two picker names.
model_aliasesobjectCanonical model id (a member of allowed_models) to the custom name its picker shows: 1-64 characters of letters, numbers, dots, dashes or colons; no Cursor routing word (claude, gemini, anthropic, sonnet-, opus-, haiku-, grok, composer); not a house id (superbot, superbot-fast, superbot-omni); unique among this key's forwards; not another model's id. A refused name stores nothing. A custom name replaces the default name for that model.
appstringForwarding app this listed key's model names are spelled for: cursor, copilot-cli, cline, roo, qwen-code, hermes, openclaw, zazen, default. Set at creation, cannot be changed. Absent = cursor.
default_modelstringThe model a call that names the bare house agent
superbot(the default model of Zapier and n8n), or names no model, is answered by instead:superbot-fast,superbot-omnior a model of one of your own accounts. A call that names any other model is dialled as named. Absent = a call namingsuperbotgetssuperbot.routestring requiredOne of
byo,credits,auto.modestring requiredOne of
model,agent.incognitoboolean requireddevice_idstringorg_idstringSet on a team key.
person_idstringSet on a key minted for a person:
per_+ 16 hex. Every key minted for the same person carries the same id. A person key has no device_id and no org_id, and is billed to the owner.person_namestringThe person's display name, 1-64 characters. Present on every person key.
person_emailstringThe person's email address, when the owner gave one.
person_groupstringA free-text grouping the owner sorts people by (a team, a class), 1-64 characters.
prompt_historyPromptHistoryWhat the owner told a person about their prompts, and how long they are kept. Absent on a key until the owner sets it: the person's prompts are then not visible to the owner and follow the account's own retention.
3 fields
visible_to_ownerboolean requiredThe owner may read this person's prompts.
retention_daysinteger requiredWhole days the prompts are kept, 1-3650.
attested_atstring (date-time) requiredISO 8601 time the owner attested the person was told. The owner's own claim, stored as given and not verified; the answer normalises it to UTC.
paused_atstring (date-time)Set while the owner holds this person: until a PATCH clears it the key answers 403
key_pausedat the model gateway, the/v1/keysroutes, the relay door and the Cosmos door; every other route does not recognise a held key and answers 401unauthorized. Held is not revoked. It is written to every live key of the person.person_limit_usdnumberThe owner's monthly spend limit for this person, in US dollars to the cent. Set by the owner's
PUT /v1/keys/person/{person_id}/limit(the Helper), written to every live key of the person, and absent while no limit is set.scopesarray of Scope requiredThe EFFECTIVE scopes: stored list or the legacy set, team keys capped. One of
gateway:invoke,usage:read,billing:read,keys:read,keys:write,endpoints:read,endpoints:write,teams:read,teams:write,devices:read,devices:write,runs:read,runs:write,mcp:invoke,turns:read,tools:invoke.
Errors
| Status | Code | What to change |
|---|---|---|
| 400 | invalid_request | A parameter or body field is invalid; |
| 401 | unauthorized | Send a live caller key or session as |
| 403 | insufficient_scope | The key lacks the scope in |
curl
curl -sS -X POST "https://superbot.gg/v1/keys" \
-H "Authorization: Bearer $SUPERBOT_API_KEY" \
-H "content-type: application/json" \
-d '{"name":"your-name","person":{"name":"your-name","email":"[email protected]","group":"your-group"},"route":"byo"}'JavaScript
const res = await fetch(`https://superbot.gg/v1/keys`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
'content-type': 'application/json',
},
body: JSON.stringify({"name":"your-name","person":{"name":"your-name","email":"[email protected]","group":"your-group"},"route":"byo"}),
});
console.log(res.status, await res.json());Python
import os
import requests
res = requests.request(
"POST",
"https://superbot.gg/v1/keys",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
"content-type": "application/json",
},
json={"name":"your-name","person":{"name":"your-name","email":"[email protected]","group":"your-group"},"route":"byo"},
)
print(res.status_code, res.json())201 The new key.
{
"key": "your-key",
"row": {
"id": "ck_9f2c41d0",
"user_id": "your-user-id",
"name": "your-name",
"mask": "sbc_ab12…cd34",
"created_at": "2026-09-01T00:00:00Z",
"last_used_at": "2026-09-01T00:00:00Z",
"revoked_at": "2026-09-01T00:00:00Z",
"daily_limit_tokens": 0,
"monthly_limit_tokens": 0,
"caps_unit": "credit",
"allowed_models": [
"your-allowed-models"
],
"models_listed": true,
"model_pins": {},
"model_aliases": {},
"app": "your-app",
"default_model": "your-default-model",
"route": "byo",
"mode": "model",
"incognito": true,
"device_id": "your-device-id",
"org_id": "your-org-id",
"person_id": "per_9f2c41d0a7b35e68",
"person_name": "your-person-name",
"person_email": "[email protected]",
"person_group": "your-person-group",
"prompt_history": {
"visible_to_owner": true,
"retention_days": 0,
"attested_at": "2026-09-01T00:00:00Z"
},
"paused_at": "2026-09-01T00:00:00Z",
"person_limit_usd": 0,
"scopes": [
"gateway:invoke"
]
}
}400 The request is malformed or a parameter is invalid; `param` names the field.
{
"error": "invalid_request",
"message": "A parameter or body field is invalid; param names it and issues lists every problem.",
"doc_url": "https://superbot.gg/developers#errors-invalid_request",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}401 The bearer is missing, malformed or unknown.
{
"error": "unauthorized",
"message": "Send a live caller key or session as Authorization: Bearer … or x-api-key. No key yet: create one at /account/api, or sign a user in at /auth.md.",
"doc_url": "https://superbot.gg/developers#errors-unauthorized",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}403 The key lacks a scope (insufficient_scope), is revoked, or may not call this route.
{
"error": "insufficient_scope",
"message": "The key lacks the scope in required_scopes; mint a key that holds it.",
"doc_url": "https://superbot.gg/developers#errors-insufficient_scope",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Get the calling keylink to Get the calling key
GET /v1/keys/whoami
The calling caller key’s own row and effective scopes, and its own metered usage in three windows (usage). A person key’s fields ride on row. Caller keys only; a session gets 403 caller_key_required. A revoked key gets 403 revoked_key, a paused one 403 key_paused.
Any live caller key (Authorization: Bearer sbc_… or x-api-key: sbc_…).
Response 200
The key.
rowCallerKey required29 fields
idstring requireduser_idstring requirednamestring requiredWhat the tool calls itself, 1-64 chars.
maskstring requiredThe only form shown after mint.
created_atstring (date-time) requiredlast_used_atstring (date-time)revoked_atstring (date-time)daily_limit_tokensnumberDaily spend cap in whole credits.
monthly_limit_tokensnumberMonthly spend cap in whole credits.
caps_unitstringOne of
credit.allowed_modelsarray of stringGlob allow-list over model names; absent = every model. With models_listed: the exact canonical ids the key may dial, and empty = none.
models_listedbooleantrue = the listed reading: allowed_models are literal canonical ids (no globs), the key lists exactly those as its per-app picker names, and an empty list allows nothing.
model_pinsobjectCanonical model id to the stable account id it is pinned to: a pinned model dials only that account, and one id pinned to two accounts gets two picker names.
model_aliasesobjectCanonical model id (a member of allowed_models) to the custom name its picker shows: 1-64 characters of letters, numbers, dots, dashes or colons; no Cursor routing word (claude, gemini, anthropic, sonnet-, opus-, haiku-, grok, composer); not a house id (superbot, superbot-fast, superbot-omni); unique among this key's forwards; not another model's id. A refused name stores nothing. A custom name replaces the default name for that model.
appstringForwarding app this listed key's model names are spelled for: cursor, copilot-cli, cline, roo, qwen-code, hermes, openclaw, zazen, default. Set at creation, cannot be changed. Absent = cursor.
default_modelstringThe model a call that names the bare house agent
superbot(the default model of Zapier and n8n), or names no model, is answered by instead:superbot-fast,superbot-omnior a model of one of your own accounts. A call that names any other model is dialled as named. Absent = a call namingsuperbotgetssuperbot.routestring requiredOne of
byo,credits,auto.modestring requiredOne of
model,agent.incognitoboolean requireddevice_idstringorg_idstringSet on a team key.
person_idstringSet on a key minted for a person:
per_+ 16 hex. Every key minted for the same person carries the same id. A person key has no device_id and no org_id, and is billed to the owner.person_namestringThe person's display name, 1-64 characters. Present on every person key.
person_emailstringThe person's email address, when the owner gave one.
person_groupstringA free-text grouping the owner sorts people by (a team, a class), 1-64 characters.
prompt_historyPromptHistoryWhat the owner told a person about their prompts, and how long they are kept. Absent on a key until the owner sets it: the person's prompts are then not visible to the owner and follow the account's own retention.
3 fields
visible_to_ownerboolean requiredThe owner may read this person's prompts.
retention_daysinteger requiredWhole days the prompts are kept, 1-3650.
attested_atstring (date-time) requiredISO 8601 time the owner attested the person was told. The owner's own claim, stored as given and not verified; the answer normalises it to UTC.
paused_atstring (date-time)Set while the owner holds this person: until a PATCH clears it the key answers 403
key_pausedat the model gateway, the/v1/keysroutes, the relay door and the Cosmos door; every other route does not recognise a held key and answers 401unauthorized. Held is not revoked. It is written to every live key of the person.person_limit_usdnumberThe owner's monthly spend limit for this person, in US dollars to the cent. Set by the owner's
PUT /v1/keys/person/{person_id}/limit(the Helper), written to every live key of the person, and absent while no limit is set.scopesarray of Scope requiredThe EFFECTIVE scopes: stored list or the legacy set, team keys capped. One of
gateway:invoke,usage:read,billing:read,keys:read,keys:write,endpoints:read,endpoints:write,teams:read,teams:write,devices:read,devices:write,runs:read,runs:write,mcp:invoke,turns:read,tools:invoke.
scopesarray of Scope requiredOne of
gateway:invoke,usage:read,billing:read,keys:read,keys:write,endpoints:read,endpoints:write,teams:read,teams:write,devices:read,devices:write,runs:read,runs:write,mcp:invoke,turns:read,tools:invoke.usageKeyUsage requiredThis key's own metered usage in three windows:
dayis the trailing 24 hours (the daily cap's window),weekthe trailing 7 days,monththe current UTC calendar month (the monthly cap's window). Each window reportsrequests(every metered request),prompts(the requests that were the person's own text),tokensandbilled_usd.3 fields
dayKeyUsageWindow required6 fields
requestsinteger requiredDistinct metered requests (a request that dialed several times counts once). Every request the key made is one, an agent's tool legs, a title helper and a probe included: the call volume, not what the person asked.
promptsinteger requiredDistinct answered prompts: requests whose last message was the person's own text and that were answered (the gateway marks the request's row only then), counted once per request id. A tool leg, a title helper, a probe and a refused or failed call are requests but not prompts. Only the dials the gateway wrote a row for are read, so the relay door's turns are not counted here.
prompts_truncatedbooleanPresent (true) when
promptsis a floor, not the window's count: the read of this key's rows behind it stopped at its row ceiling before it reached the window's start, or the read failed.promptsthen counts the newest prompts the read reached. Absent when the read covered the whole window. One oftrue.tokensnumber requiredEvery metered leg: fresh input, output and both cache legs.
billed_usdnumber requiredWhat the window's calls are worth to the caps and the usage pages, USD: the router's settle once read back, else the metered list value.
clientsobjectDistinct requests of the window made by Zapier or n8n, counted from the
x-superbot-clienttag (zapier/<v>,n8n/<v>) the request carried. A platform with no request in the window is absent, and the member is absent when neither made one.2 fields
zapierintegern8ninteger
weekKeyUsageWindow required6 fields
requestsinteger requiredDistinct metered requests (a request that dialed several times counts once). Every request the key made is one, an agent's tool legs, a title helper and a probe included: the call volume, not what the person asked.
promptsinteger requiredDistinct answered prompts: requests whose last message was the person's own text and that were answered (the gateway marks the request's row only then), counted once per request id. A tool leg, a title helper, a probe and a refused or failed call are requests but not prompts. Only the dials the gateway wrote a row for are read, so the relay door's turns are not counted here.
prompts_truncatedbooleanPresent (true) when
promptsis a floor, not the window's count: the read of this key's rows behind it stopped at its row ceiling before it reached the window's start, or the read failed.promptsthen counts the newest prompts the read reached. Absent when the read covered the whole window. One oftrue.tokensnumber requiredEvery metered leg: fresh input, output and both cache legs.
billed_usdnumber requiredWhat the window's calls are worth to the caps and the usage pages, USD: the router's settle once read back, else the metered list value.
clientsobjectDistinct requests of the window made by Zapier or n8n, counted from the
x-superbot-clienttag (zapier/<v>,n8n/<v>) the request carried. A platform with no request in the window is absent, and the member is absent when neither made one.2 fields
zapierintegern8ninteger
monthKeyUsageWindow required6 fields
requestsinteger requiredDistinct metered requests (a request that dialed several times counts once). Every request the key made is one, an agent's tool legs, a title helper and a probe included: the call volume, not what the person asked.
promptsinteger requiredDistinct answered prompts: requests whose last message was the person's own text and that were answered (the gateway marks the request's row only then), counted once per request id. A tool leg, a title helper, a probe and a refused or failed call are requests but not prompts. Only the dials the gateway wrote a row for are read, so the relay door's turns are not counted here.
prompts_truncatedbooleanPresent (true) when
promptsis a floor, not the window's count: the read of this key's rows behind it stopped at its row ceiling before it reached the window's start, or the read failed.promptsthen counts the newest prompts the read reached. Absent when the read covered the whole window. One oftrue.tokensnumber requiredEvery metered leg: fresh input, output and both cache legs.
billed_usdnumber requiredWhat the window's calls are worth to the caps and the usage pages, USD: the router's settle once read back, else the metered list value.
clientsobjectDistinct requests of the window made by Zapier or n8n, counted from the
x-superbot-clienttag (zapier/<v>,n8n/<v>) the request carried. A platform with no request in the window is absent, and the member is absent when neither made one.2 fields
zapierintegern8ninteger
Errors
| Status | Code | What to change |
|---|---|---|
| 401 | unauthorized | Send a live caller key or session as |
| 403 | insufficient_scope | The key lacks the scope in |
| 404 | not_found | No such resource on this account; check the id. |
curl
curl -sS -X GET "https://superbot.gg/v1/keys/whoami" \
-H "Authorization: Bearer $SUPERBOT_API_KEY"JavaScript
const res = await fetch(`https://superbot.gg/v1/keys/whoami`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
},
});
console.log(res.status, await res.json());Python
import os
import requests
res = requests.request(
"GET",
"https://superbot.gg/v1/keys/whoami",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
},
)
print(res.status_code, res.json())200 The key.
{
"row": {
"id": "ck_9f2c41d0",
"user_id": "your-user-id",
"name": "your-name",
"mask": "sbc_ab12…cd34",
"created_at": "2026-09-01T00:00:00Z",
"last_used_at": "2026-09-01T00:00:00Z",
"revoked_at": "2026-09-01T00:00:00Z",
"daily_limit_tokens": 0,
"monthly_limit_tokens": 0,
"caps_unit": "credit",
"allowed_models": [
"your-allowed-models"
],
"models_listed": true,
"model_pins": {},
"model_aliases": {},
"app": "your-app",
"default_model": "your-default-model",
"route": "byo",
"mode": "model",
"incognito": true,
"device_id": "your-device-id",
"org_id": "your-org-id",
"person_id": "per_9f2c41d0a7b35e68",
"person_name": "your-person-name",
"person_email": "[email protected]",
"person_group": "your-person-group",
"prompt_history": {
"visible_to_owner": true,
"retention_days": 0,
"attested_at": "2026-09-01T00:00:00Z"
},
"paused_at": "2026-09-01T00:00:00Z",
"person_limit_usd": 0,
"scopes": [
"gateway:invoke"
]
},
"scopes": [
"gateway:invoke"
],
"usage": {
"day": {
"requests": 0,
"prompts": 0,
"prompts_truncated": true,
"tokens": 0,
"billed_usd": 0,
"clients": {
"zapier": 0,
"n8n": 0
}
},
"week": {
"requests": 0,
"prompts": 0,
"prompts_truncated": true,
"tokens": 0,
"billed_usd": 0,
"clients": {
"zapier": 0,
"n8n": 0
}
},
"month": {
"requests": 0,
"prompts": 0,
"prompts_truncated": true,
"tokens": 0,
"billed_usd": 0,
"clients": {
"zapier": 0,
"n8n": 0
}
}
}
}401 The bearer is missing, malformed or unknown.
{
"error": "unauthorized",
"message": "Send a live caller key or session as Authorization: Bearer … or x-api-key. No key yet: create one at /account/api, or sign a user in at /auth.md.",
"doc_url": "https://superbot.gg/developers#errors-unauthorized",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}403 The key lacks a scope (insufficient_scope), is revoked, or may not call this route.
{
"error": "insufficient_scope",
"message": "The key lacks the scope in required_scopes; mint a key that holds it.",
"doc_url": "https://superbot.gg/developers#errors-insufficient_scope",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}404 No such resource on this account.
{
"error": "not_found",
"message": "No such resource on this account; check the id.",
"doc_url": "https://superbot.gg/developers#errors-not_found",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Update a caller keylink to Update a caller key
PATCH /v1/keys/{id}
Edit a key’s name, route, mode, caps, models, default model or scopes. A bad default_model answers 400 invalid_default_model. On a person key, person_name, person_email, person_group, prompt_history and paused_at edit the person and are written to every live key of that person; on any other key they answer 400 not_a_person_key, and an invalid value answers 400 invalid_person. A person key is edited by the account owner only, and a person field is changed by the account owner only: a caller key that tries either answers 403 caller_key_forbidden. A person key cannot be renamed account. A paused caller key answers 403 key_paused.
A caller key holding keys:write (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
idstring required
Request body
namestringroutestringOne of
byo,credits,auto.modestringOne of
model,agent.daily_limit_tokensnumberDaily spend cap in whole credits.
monthly_limit_tokensnumberMonthly spend cap in whole credits.
allowed_modelsarray of stringGlob allow-list over model names; with models_listed, the exact canonical ids (no globs).
models_listedbooleantrue = the listed reading: the key dials exactly its allowed_models, listed as the per-app picker names; empty = none. A PATCH that omits it leaves it as it was.
model_pinsobject | nullCanonical model id to the stable account id it is pinned to (non-empty strings). A PATCH replaces the whole map; null clears it.
model_aliasesobject | nullCanonical model id (a member of allowed_models) to the custom name its picker shows (1-64 characters: letters, numbers, dots, dashes, colons). A PATCH replaces the whole map; null clears it. A refused name stores nothing and answers the reason. Removing a model from allowed_models drops its custom name.
default_modelstring | nullThe model a call that names the bare house agent
superbot(the default model of Zapier and n8n), or names no model, is answered by instead:superbot-fast,superbot-omni, or a model of one of your own accounts (claude-sonnet-5-5,gpt-5.5,custom/<endpoint>/<id>). A call that names any other model is dialled as named.nullorsuperbotclears it. A model of your own account needs a key on routeautoorbyoin modemodelwhoseallowed_modelsadmits it; a key on routecreditstakes a house model only, and a key withmodels_listedtakes none. The write is judged on the key as it will be stored, so a PATCH that would leave the default unusable (route credits, mode agent, a narrower list) answers 400invalid_default_model: senddefault_model: nullwith it. A PATCH that omits it leaves it as it was.incognitobooleanscopesarray of ScopeExplicit scopes; wins over
preset. One ofgateway:invoke,usage:read,billing:read,keys:read,keys:write,endpoints:read,endpoints:write,teams:read,teams:write,devices:read,devices:write,runs:read,runs:write,mcp:invoke,turns:read,tools:invoke.person_namestringRename the person (1-64 printable characters). Cannot be cleared. Does not rename the key (
name).person_emailstring | nullSet the person's email address; null clears it.
person_groupstring | nullSet the person's group; null clears it.
prompt_historyPromptHistory & object | null3 fields
visible_to_ownerboolean requiredThe owner may read this person's prompts.
retention_daysinteger requiredWhole days the prompts are kept, 1-3650.
attested_atstring (date-time) requiredISO 8601 time the owner attested the person was told. The owner's own claim, stored as given and not verified; the answer normalises it to UTC.
paused_atboolean | string | nulltruepauses the person now (the edge stamps the time), an ISO 8601 time pauses from then (not in the future),falseor null resumes. A paused person's keys answer 403key_pausedat the model gateway, the/v1/keysroutes, the relay door and the Cosmos door; every other route does not recognise a held key and answers 401unauthorized.
Response 200
The edited key.
rowCallerKey required29 fields
idstring requireduser_idstring requirednamestring requiredWhat the tool calls itself, 1-64 chars.
maskstring requiredThe only form shown after mint.
created_atstring (date-time) requiredlast_used_atstring (date-time)revoked_atstring (date-time)daily_limit_tokensnumberDaily spend cap in whole credits.
monthly_limit_tokensnumberMonthly spend cap in whole credits.
caps_unitstringOne of
credit.allowed_modelsarray of stringGlob allow-list over model names; absent = every model. With models_listed: the exact canonical ids the key may dial, and empty = none.
models_listedbooleantrue = the listed reading: allowed_models are literal canonical ids (no globs), the key lists exactly those as its per-app picker names, and an empty list allows nothing.
model_pinsobjectCanonical model id to the stable account id it is pinned to: a pinned model dials only that account, and one id pinned to two accounts gets two picker names.
model_aliasesobjectCanonical model id (a member of allowed_models) to the custom name its picker shows: 1-64 characters of letters, numbers, dots, dashes or colons; no Cursor routing word (claude, gemini, anthropic, sonnet-, opus-, haiku-, grok, composer); not a house id (superbot, superbot-fast, superbot-omni); unique among this key's forwards; not another model's id. A refused name stores nothing. A custom name replaces the default name for that model.
appstringForwarding app this listed key's model names are spelled for: cursor, copilot-cli, cline, roo, qwen-code, hermes, openclaw, zazen, default. Set at creation, cannot be changed. Absent = cursor.
default_modelstringThe model a call that names the bare house agent
superbot(the default model of Zapier and n8n), or names no model, is answered by instead:superbot-fast,superbot-omnior a model of one of your own accounts. A call that names any other model is dialled as named. Absent = a call namingsuperbotgetssuperbot.routestring requiredOne of
byo,credits,auto.modestring requiredOne of
model,agent.incognitoboolean requireddevice_idstringorg_idstringSet on a team key.
person_idstringSet on a key minted for a person:
per_+ 16 hex. Every key minted for the same person carries the same id. A person key has no device_id and no org_id, and is billed to the owner.person_namestringThe person's display name, 1-64 characters. Present on every person key.
person_emailstringThe person's email address, when the owner gave one.
person_groupstringA free-text grouping the owner sorts people by (a team, a class), 1-64 characters.
prompt_historyPromptHistoryWhat the owner told a person about their prompts, and how long they are kept. Absent on a key until the owner sets it: the person's prompts are then not visible to the owner and follow the account's own retention.
3 fields
visible_to_ownerboolean requiredThe owner may read this person's prompts.
retention_daysinteger requiredWhole days the prompts are kept, 1-3650.
attested_atstring (date-time) requiredISO 8601 time the owner attested the person was told. The owner's own claim, stored as given and not verified; the answer normalises it to UTC.
paused_atstring (date-time)Set while the owner holds this person: until a PATCH clears it the key answers 403
key_pausedat the model gateway, the/v1/keysroutes, the relay door and the Cosmos door; every other route does not recognise a held key and answers 401unauthorized. Held is not revoked. It is written to every live key of the person.person_limit_usdnumberThe owner's monthly spend limit for this person, in US dollars to the cent. Set by the owner's
PUT /v1/keys/person/{person_id}/limit(the Helper), written to every live key of the person, and absent while no limit is set.scopesarray of Scope requiredThe EFFECTIVE scopes: stored list or the legacy set, team keys capped. One of
gateway:invoke,usage:read,billing:read,keys:read,keys:write,endpoints:read,endpoints:write,teams:read,teams:write,devices:read,devices:write,runs:read,runs:write,mcp:invoke,turns:read,tools:invoke.
Errors
| Status | Code | What to change |
|---|---|---|
| 400 | invalid_request | A parameter or body field is invalid; |
| 401 | unauthorized | Send a live caller key or session as |
| 403 | insufficient_scope | The key lacks the scope in |
| 404 | not_found | No such resource on this account; check the id. |
curl
curl -sS -X PATCH "https://superbot.gg/v1/keys/$ID" \
-H "Authorization: Bearer $SUPERBOT_API_KEY" \
-H "content-type: application/json" \
-d '{"name":"your-name","route":"byo","mode":"model"}'JavaScript
const id = 'ID';
const res = await fetch(`https://superbot.gg/v1/keys/${id}`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
'content-type': 'application/json',
},
body: JSON.stringify({"name":"your-name","route":"byo","mode":"model"}),
});
console.log(res.status, await res.json());Python
import os
import requests
id = "ID"
res = requests.request(
"PATCH",
f"https://superbot.gg/v1/keys/{id}",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
"content-type": "application/json",
},
json={"name":"your-name","route":"byo","mode":"model"},
)
print(res.status_code, res.json())200 The edited key.
{
"row": {
"id": "ck_9f2c41d0",
"user_id": "your-user-id",
"name": "your-name",
"mask": "sbc_ab12…cd34",
"created_at": "2026-09-01T00:00:00Z",
"last_used_at": "2026-09-01T00:00:00Z",
"revoked_at": "2026-09-01T00:00:00Z",
"daily_limit_tokens": 0,
"monthly_limit_tokens": 0,
"caps_unit": "credit",
"allowed_models": [
"your-allowed-models"
],
"models_listed": true,
"model_pins": {},
"model_aliases": {},
"app": "your-app",
"default_model": "your-default-model",
"route": "byo",
"mode": "model",
"incognito": true,
"device_id": "your-device-id",
"org_id": "your-org-id",
"person_id": "per_9f2c41d0a7b35e68",
"person_name": "your-person-name",
"person_email": "[email protected]",
"person_group": "your-person-group",
"prompt_history": {
"visible_to_owner": true,
"retention_days": 0,
"attested_at": "2026-09-01T00:00:00Z"
},
"paused_at": "2026-09-01T00:00:00Z",
"person_limit_usd": 0,
"scopes": [
"gateway:invoke"
]
}
}400 The request is malformed or a parameter is invalid; `param` names the field.
{
"error": "invalid_request",
"message": "A parameter or body field is invalid; param names it and issues lists every problem.",
"doc_url": "https://superbot.gg/developers#errors-invalid_request",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}401 The bearer is missing, malformed or unknown.
{
"error": "unauthorized",
"message": "Send a live caller key or session as Authorization: Bearer … or x-api-key. No key yet: create one at /account/api, or sign a user in at /auth.md.",
"doc_url": "https://superbot.gg/developers#errors-unauthorized",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}403 The key lacks a scope (insufficient_scope), is revoked, or may not call this route.
{
"error": "insufficient_scope",
"message": "The key lacks the scope in required_scopes; mint a key that holds it.",
"doc_url": "https://superbot.gg/developers#errors-insufficient_scope",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}404 No such resource on this account.
{
"error": "not_found",
"message": "No such resource on this account; check the id.",
"doc_url": "https://superbot.gg/developers#errors-not_found",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Revoke a caller keylink to Revoke a caller key
DELETE /v1/keys/{id}
Revoke a key. Revoking an already-revoked key is a no-op (already: true). A person key is revoked by the account owner only; a caller key that tries answers 403 caller_key_forbidden.
A caller key holding keys:write (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
idstring required
Response 200
Revoked.
okboolean requiredOne of
true.alreadyboolean
Errors
| Status | Code | What to change |
|---|---|---|
| 401 | unauthorized | Send a live caller key or session as |
| 403 | insufficient_scope | The key lacks the scope in |
| 404 | not_found | No such resource on this account; check the id. |
curl
curl -sS -X DELETE "https://superbot.gg/v1/keys/$ID" \
-H "Authorization: Bearer $SUPERBOT_API_KEY"JavaScript
const id = 'ID';
const res = await fetch(`https://superbot.gg/v1/keys/${id}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
},
});
console.log(res.status, await res.json());Python
import os
import requests
id = "ID"
res = requests.request(
"DELETE",
f"https://superbot.gg/v1/keys/{id}",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
},
)
print(res.status_code, res.json())200 Revoked.
{
"ok": true,
"already": true
}401 The bearer is missing, malformed or unknown.
{
"error": "unauthorized",
"message": "Send a live caller key or session as Authorization: Bearer … or x-api-key. No key yet: create one at /account/api, or sign a user in at /auth.md.",
"doc_url": "https://superbot.gg/developers#errors-unauthorized",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}403 The key lacks a scope (insufficient_scope), is revoked, or may not call this route.
{
"error": "insufficient_scope",
"message": "The key lacks the scope in required_scopes; mint a key that holds it.",
"doc_url": "https://superbot.gg/developers#errors-insufficient_scope",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}404 No such resource on this account.
{
"error": "not_found",
"message": "No such resource on this account; check the id.",
"doc_url": "https://superbot.gg/developers#errors-not_found",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Rotate a caller keylink to Rotate a caller key
POST /v1/keys/{id}/rotate
Replace a key with a new one of the same shape (name, scopes, route, mode, caps, models, pins, aliases, default model, incognito, the person it is for, the device that minted it) and revoke the old one. The new key is minted first and the old one revoked after, so a failure never leaves the account without a working key. The reply carries the new key in plaintext once (key), its row, and revoked, the id of the key revoked (null if that revoke failed after the mint: the new key is live, so revoke the old one with DELETE /v1/keys/{id}). No body. A key that is revoked already answers 409 revoked; an id this account does not hold answers 404 not_found; a team key answers 400 team_key (rotate it on the team pane). A person key is rotated by the account owner only; a caller key that tries answers 403 caller_key_forbidden. The new key has made no calls yet, so it lists under Zapier or n8n again with its first call.
A caller key holding keys:write (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
idstring required
Response 201
The new key, once.
keystring requiredThe new key in plaintext. Shown once.
rowCallerKey required29 fields
idstring requireduser_idstring requirednamestring requiredWhat the tool calls itself, 1-64 chars.
maskstring requiredThe only form shown after mint.
created_atstring (date-time) requiredlast_used_atstring (date-time)revoked_atstring (date-time)daily_limit_tokensnumberDaily spend cap in whole credits.
monthly_limit_tokensnumberMonthly spend cap in whole credits.
caps_unitstringOne of
credit.allowed_modelsarray of stringGlob allow-list over model names; absent = every model. With models_listed: the exact canonical ids the key may dial, and empty = none.
models_listedbooleantrue = the listed reading: allowed_models are literal canonical ids (no globs), the key lists exactly those as its per-app picker names, and an empty list allows nothing.
model_pinsobjectCanonical model id to the stable account id it is pinned to: a pinned model dials only that account, and one id pinned to two accounts gets two picker names.
model_aliasesobjectCanonical model id (a member of allowed_models) to the custom name its picker shows: 1-64 characters of letters, numbers, dots, dashes or colons; no Cursor routing word (claude, gemini, anthropic, sonnet-, opus-, haiku-, grok, composer); not a house id (superbot, superbot-fast, superbot-omni); unique among this key's forwards; not another model's id. A refused name stores nothing. A custom name replaces the default name for that model.
appstringForwarding app this listed key's model names are spelled for: cursor, copilot-cli, cline, roo, qwen-code, hermes, openclaw, zazen, default. Set at creation, cannot be changed. Absent = cursor.
default_modelstringThe model a call that names the bare house agent
superbot(the default model of Zapier and n8n), or names no model, is answered by instead:superbot-fast,superbot-omnior a model of one of your own accounts. A call that names any other model is dialled as named. Absent = a call namingsuperbotgetssuperbot.routestring requiredOne of
byo,credits,auto.modestring requiredOne of
model,agent.incognitoboolean requireddevice_idstringorg_idstringSet on a team key.
person_idstringSet on a key minted for a person:
per_+ 16 hex. Every key minted for the same person carries the same id. A person key has no device_id and no org_id, and is billed to the owner.person_namestringThe person's display name, 1-64 characters. Present on every person key.
person_emailstringThe person's email address, when the owner gave one.
person_groupstringA free-text grouping the owner sorts people by (a team, a class), 1-64 characters.
prompt_historyPromptHistoryWhat the owner told a person about their prompts, and how long they are kept. Absent on a key until the owner sets it: the person's prompts are then not visible to the owner and follow the account's own retention.
3 fields
visible_to_ownerboolean requiredThe owner may read this person's prompts.
retention_daysinteger requiredWhole days the prompts are kept, 1-3650.
attested_atstring (date-time) requiredISO 8601 time the owner attested the person was told. The owner's own claim, stored as given and not verified; the answer normalises it to UTC.
paused_atstring (date-time)Set while the owner holds this person: until a PATCH clears it the key answers 403
key_pausedat the model gateway, the/v1/keysroutes, the relay door and the Cosmos door; every other route does not recognise a held key and answers 401unauthorized. Held is not revoked. It is written to every live key of the person.person_limit_usdnumberThe owner's monthly spend limit for this person, in US dollars to the cent. Set by the owner's
PUT /v1/keys/person/{person_id}/limit(the Helper), written to every live key of the person, and absent while no limit is set.scopesarray of Scope requiredThe EFFECTIVE scopes: stored list or the legacy set, team keys capped. One of
gateway:invoke,usage:read,billing:read,keys:read,keys:write,endpoints:read,endpoints:write,teams:read,teams:write,devices:read,devices:write,runs:read,runs:write,mcp:invoke,turns:read,tools:invoke.
revokedstring | null requiredThe id of the key that was revoked, or null if that revoke failed after the mint.
Errors
| Status | Code | What to change |
|---|---|---|
| 400 | invalid_request | A parameter or body field is invalid; |
| 401 | unauthorized | Send a live caller key or session as |
| 403 | insufficient_scope | The key lacks the scope in |
| 404 | not_found | No such resource on this account; check the id. |
| 409 | conflict | The resource is not in a state that allows this change. |
curl
curl -sS -X POST "https://superbot.gg/v1/keys/$ID/rotate" \
-H "Authorization: Bearer $SUPERBOT_API_KEY"JavaScript
const id = 'ID';
const res = await fetch(`https://superbot.gg/v1/keys/${id}/rotate`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
},
});
console.log(res.status, await res.json());Python
import os
import requests
id = "ID"
res = requests.request(
"POST",
f"https://superbot.gg/v1/keys/{id}/rotate",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
},
)
print(res.status_code, res.json())201 The new key, once.
{
"key": "your-key",
"row": {
"id": "ck_9f2c41d0",
"user_id": "your-user-id",
"name": "your-name",
"mask": "sbc_ab12…cd34",
"created_at": "2026-09-01T00:00:00Z",
"last_used_at": "2026-09-01T00:00:00Z",
"revoked_at": "2026-09-01T00:00:00Z",
"daily_limit_tokens": 0,
"monthly_limit_tokens": 0,
"caps_unit": "credit",
"allowed_models": [
"your-allowed-models"
],
"models_listed": true,
"model_pins": {},
"model_aliases": {},
"app": "your-app",
"default_model": "your-default-model",
"route": "byo",
"mode": "model",
"incognito": true,
"device_id": "your-device-id",
"org_id": "your-org-id",
"person_id": "per_9f2c41d0a7b35e68",
"person_name": "your-person-name",
"person_email": "[email protected]",
"person_group": "your-person-group",
"prompt_history": {
"visible_to_owner": true,
"retention_days": 0,
"attested_at": "2026-09-01T00:00:00Z"
},
"paused_at": "2026-09-01T00:00:00Z",
"person_limit_usd": 0,
"scopes": [
"gateway:invoke"
]
},
"revoked": "your-revoked"
}400 The request is malformed or a parameter is invalid; `param` names the field.
{
"error": "invalid_request",
"message": "A parameter or body field is invalid; param names it and issues lists every problem.",
"doc_url": "https://superbot.gg/developers#errors-invalid_request",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}401 The bearer is missing, malformed or unknown.
{
"error": "unauthorized",
"message": "Send a live caller key or session as Authorization: Bearer … or x-api-key. No key yet: create one at /account/api, or sign a user in at /auth.md.",
"doc_url": "https://superbot.gg/developers#errors-unauthorized",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}403 The key lacks a scope (insufficient_scope), is revoked, or may not call this route.
{
"error": "insufficient_scope",
"message": "The key lacks the scope in required_scopes; mint a key that holds it.",
"doc_url": "https://superbot.gg/developers#errors-insufficient_scope",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}404 No such resource on this account.
{
"error": "not_found",
"message": "No such resource on this account; check the id.",
"doc_url": "https://superbot.gg/developers#errors-not_found",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}409 The resource is not in a state that allows this change.
{
"error": "conflict",
"message": "The resource is not in a state that allows this change.",
"doc_url": "https://superbot.gg/developers#errors-conflict",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}No operation matches this filter.