Devices
The devices paired to your account.
10 operations. Errors link to their row on the overview.
Run a job on an agent computerlink to Run a job on an agent computer
POST /v1/devices/{device_id}/jobs
Queue one device-shell job on a linked agent computer, by its id. First-party only: a session or a device token of your own Superbot app; agent computer tokens, MCP connectors, caller keys and the account API key are refused (403). An asleep agent computer answers queued_asleep; the job waits for its next poll up to 600 s.
A caller key holding devices:write (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
device_idstring requiredAn agent computer (
agt_…) on your account.
Request body
kindAgentJobKind requiredThe device-shell job kinds a first-party device may run on an agent computer. One of
bash,bash_write,bash_output,bash_kill,bash_resize,read,write,glob,grep.argsobject requiredThe relay tool's own args, camelCase, per kind: bash {command, cwd?, timeoutMs?, runInBackground?, interactive?} (interactive: a real tty, answered with bash_write; open a terminal pane with {command: <login shell>, runInBackground: true, interactive: true}, whose result carries {type: 'terminal', terminalId}); bash_write {terminalId, input, newline?}; bash_output {terminalId, since?, wait?}; bash_kill {terminalId}; bash_resize {terminalId, cols, rows} (a terminal pane's resize of an interactive terminal's tty: integers, cols 20..500, rows 5..200; a non-interactive terminal answers not_a_tty); read {path, line?, limit?}; write {path, content, overwrite?}; glob {pattern, cwd?}; grep {pattern, path?, cwd?}. Unknown keys are refused.
Response 201
Queued.
job_idstring requiredstateAgentJobState requiredqueued_asleep: the agent computer has no open poll; the job waits for its next poll inside the 600 s TTL.expired: the TTL ran out before a result. One ofqueued,queued_asleep,claimed,done,failed,expired.expires_atstring requiredISO 8601, 600 s after the enqueue.
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. |
| 429 | rate_limited | Over the per-key request bucket; retry after |
curl
curl -sS -X POST "https://superbot.gg/v1/devices/$DEVICE_ID/jobs" \
-H "Authorization: Bearer $SUPERBOT_API_KEY" \
-H "content-type: application/json" \
-d '{"kind":"bash","args":{}}'JavaScript
const deviceId = 'DEVICE_ID';
const res = await fetch(`https://superbot.gg/v1/devices/${deviceId}/jobs`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
'content-type': 'application/json',
},
body: JSON.stringify({"kind":"bash","args":{}}),
});
console.log(res.status, await res.json());Python
import os
import requests
device_id = "DEVICE_ID"
res = requests.request(
"POST",
f"https://superbot.gg/v1/devices/{device_id}/jobs",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
"content-type": "application/json",
},
json={"kind":"bash","args":{}},
)
print(res.status_code, res.json())201 Queued.
{
"job_id": "your-job-id",
"state": "queued",
"expires_at": "your-expires-at"
}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"
}429 Over the per-key request bucket; retry after x-ratelimit-reset.
{
"error": "rate_limited",
"message": "Over the per-key request bucket; retry after x-ratelimit-reset.",
"doc_url": "https://superbot.gg/developers#errors-rate_limited",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Read an agent computer joblink to Read an agent computer job
GET /v1/devices/{device_id}/jobs/{job_id}
The job and, once it is done or failed, its result. wait (seconds, at most 25) parks the read until the job settles. A job lost to a Superbot restart answers 410 job_lost_in_restart (retryable: true, kind): it may have run on the agent computer, so check before repeating anything that changes state, then send it again. An id nobody minted, another account's, or older than the 600 s job lifetime is 404 job_not_found.
A caller key holding devices:read (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
device_idstring requiredAn agent computer (
agt_…) on your account.job_idstring requiredThe job id the enqueue answered.
Query parameters
waitstring optionalSeconds to wait for the job to settle, 0-25.
Response 200
The job.
job_idstring requireddevice_idstring requiredkindAgentJobKind requiredThe device-shell job kinds a first-party device may run on an agent computer. One of
bash,bash_write,bash_output,bash_kill,bash_resize,read,write,glob,grep.stateAgentJobState requiredqueued_asleep: the agent computer has no open poll; the job waits for its next poll inside the 600 s TTL.expired: the TTL ran out before a result. One ofqueued,queued_asleep,claimed,done,failed,expired.created_atstring requiredexpires_atstring requiredresultAgentJobResultPresent once the state is
doneorfailed.3 fields
okboolean requiredcontentanyerrorobject2 fields
codestring requiredmessagestring required
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. |
| 410 | job_lost_in_restart | Superbot restarted after the job was queued and its outcome was not kept ( |
curl
curl -sS -X GET "https://superbot.gg/v1/devices/$DEVICE_ID/jobs/$JOB_ID" \
-H "Authorization: Bearer $SUPERBOT_API_KEY"JavaScript
const deviceId = 'DEVICE_ID';
const jobId = 'JOB_ID';
const res = await fetch(`https://superbot.gg/v1/devices/${deviceId}/jobs/${jobId}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
},
});
console.log(res.status, await res.json());Python
import os
import requests
device_id = "DEVICE_ID"
job_id = "JOB_ID"
res = requests.request(
"GET",
f"https://superbot.gg/v1/devices/{device_id}/jobs/{job_id}",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
},
)
print(res.status_code, res.json())200 The job.
{
"job_id": "your-job-id",
"device_id": "your-device-id",
"kind": "bash",
"state": "queued",
"created_at": "your-created-at",
"expires_at": "your-expires-at",
"result": {
"ok": true,
"content": "your-content",
"error": {
"code": "your-code",
"message": "your-message"
}
}
}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"
}410 Superbot restarted after the job was queued and its outcome was not kept (`job_lost_in_restart`, `retryable: true`, `kind`). Send the job again once a repeat is safe.
{
"error": "job_lost_in_restart",
"message": "your-message",
"doc_url": "https://superbot.gg/developers#errors",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Stream an agent computer terminallink to Stream an agent computer terminal
GET /v1/devices/{device_id}/terminals/{terminal_id}/stream
Server-sent events, every frame event: terminal with an AgentTerminalFrame as JSON: output (seq strictly increasing), then exit or gone, after which the stream closes. Resume with since=<seq> (or Last-Event-ID). Open a terminal with a bash job {command: <login shell>, runInBackground: true, interactive: true} (a real tty: prompts, sudo and TUIs work) and type into it with bash_write.
A caller key holding devices:read (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
device_idstring requiredAn agent computer (
agt_…) on your account.terminal_idstring requiredThe terminal id a background
bashjob answered.
Query parameters
sincestring optionalResume after this output seq (a byte cursor). Absent: from the start of the buffer.
Response 200
The terminal stream.
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 GET "https://superbot.gg/v1/devices/$DEVICE_ID/terminals/$TERMINAL_ID/stream" \
-H "Authorization: Bearer $SUPERBOT_API_KEY"JavaScript
const deviceId = 'DEVICE_ID';
const terminalId = 'TERMINAL_ID';
const res = await fetch(`https://superbot.gg/v1/devices/${deviceId}/terminals/${terminalId}/stream`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
},
});
console.log(res.status, await res.json());Python
import os
import requests
device_id = "DEVICE_ID"
terminal_id = "TERMINAL_ID"
res = requests.request(
"GET",
f"https://superbot.gg/v1/devices/{device_id}/terminals/{terminal_id}/stream",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
},
)
print(res.status_code, res.json())200 The terminal stream.
text/event-stream: string400 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"
}Preview an agent computer codelink to Preview an agent computer code
GET /v1/pair/{user_code}
The details of a pending code an agent computer showed. First-party only: your own Superbot app (a session or its device token).
Any live caller key (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
user_codestring requiredThe code the agent computer shows (e.g.
ABCD-EFGH).
Response 200
The pending code.
kindstring requiredOne of
agent_computer.labelstring requiredagent_vendorstring | null requiredipstring | null requiredgeostring | null requiredtierstring requiredOne of
link.approve_onstring requiredOne of
this_device,phone.asked_atstringWhen the agent computer asked for this code (ISO-8601 UTC). Absent on an older edge.
expires_atstringWhen the code lapses (ISO-8601 UTC). Absent on an older edge.
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/pair/$USER_CODE" \
-H "Authorization: Bearer $SUPERBOT_API_KEY"JavaScript
const userCode = 'USER_CODE';
const res = await fetch(`https://superbot.gg/v1/pair/${userCode}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
},
});
console.log(res.status, await res.json());Python
import os
import requests
user_code = "USER_CODE"
res = requests.request(
"GET",
f"https://superbot.gg/v1/pair/{user_code}",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
},
)
print(res.status_code, res.json())200 The pending code.
{
"kind": "agent_computer",
"label": "your-label",
"agent_vendor": "your-agent-vendor",
"ip": "your-ip",
"geo": "your-geo",
"tier": "link",
"approve_on": "this_device",
"asked_at": "your-asked-at",
"expires_at": "your-expires-at"
}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"
}Approve an agent computer codelink to Approve an agent computer code
POST /v1/pair/{user_code}/approve
Link the agent computer behind a pending code at the link tier (terminal and relay, no synced data). First-party only; a web session with a recent phone is told to finish on the phone (409 approve_on_phone).
Any live caller key (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
user_codestring requiredThe code the agent computer shows (e.g.
ABCD-EFGH).
Request body
labelstringA new label, 1-32 characters.
Response 200
Linked.
device_idstring requiredkindstring requiredOne of
agent_computer.tierstring requiredOne of
link.
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. |
| 429 | rate_limited | Over the per-key request bucket; retry after |
curl
curl -sS -X POST "https://superbot.gg/v1/pair/$USER_CODE/approve" \
-H "Authorization: Bearer $SUPERBOT_API_KEY" \
-H "content-type: application/json" \
-d '{"label":"your-label"}'JavaScript
const userCode = 'USER_CODE';
const res = await fetch(`https://superbot.gg/v1/pair/${userCode}/approve`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
'content-type': 'application/json',
},
body: JSON.stringify({"label":"your-label"}),
});
console.log(res.status, await res.json());Python
import os
import requests
user_code = "USER_CODE"
res = requests.request(
"POST",
f"https://superbot.gg/v1/pair/{user_code}/approve",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
"content-type": "application/json",
},
json={"label":"your-label"},
)
print(res.status_code, res.json())200 Linked.
{
"device_id": "your-device-id",
"kind": "agent_computer",
"tier": "link"
}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"
}429 Over the per-key request bucket; retry after x-ratelimit-reset.
{
"error": "rate_limited",
"message": "Over the per-key request bucket; retry after x-ratelimit-reset.",
"doc_url": "https://superbot.gg/developers#errors-rate_limited",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Decline an agent computer codelink to Decline an agent computer code
POST /v1/pair/{user_code}/deny
Decline a pending code ("Not me"). The agent computer's next poll of its device code answers access_denied (RFC 8628 §3.5) and the code is dead. reason not_me says the user never asked for it: it is logged with the claimed vendor and the request network, and three distinct accounts reporting one network inside 24 hours count against that network's code limit. First-party only. 404 not_found for a code that is unknown, expired, approved or already declined.
Any live caller key (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
user_codestring requiredThe code the agent computer shows (e.g.
ABCD-EFGH).
Request body
reasonstringWhy. Default
cancel. One ofcancel,not_me.
Response 200
Declined.
okboolean requiredOne of
true.
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. |
| 429 | rate_limited | Over the per-key request bucket; retry after |
curl
curl -sS -X POST "https://superbot.gg/v1/pair/$USER_CODE/deny" \
-H "Authorization: Bearer $SUPERBOT_API_KEY" \
-H "content-type: application/json" \
-d '{"reason":"cancel"}'JavaScript
const userCode = 'USER_CODE';
const res = await fetch(`https://superbot.gg/v1/pair/${userCode}/deny`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
'content-type': 'application/json',
},
body: JSON.stringify({"reason":"cancel"}),
});
console.log(res.status, await res.json());Python
import os
import requests
user_code = "USER_CODE"
res = requests.request(
"POST",
f"https://superbot.gg/v1/pair/{user_code}/deny",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
"content-type": "application/json",
},
json={"reason":"cancel"},
)
print(res.status_code, res.json())200 Declined.
{
"ok": true
}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"
}429 Over the per-key request bucket; retry after x-ratelimit-reset.
{
"error": "rate_limited",
"message": "Over the per-key request bucket; retry after x-ratelimit-reset.",
"doc_url": "https://superbot.gg/developers#errors-rate_limited",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}List deviceslink to List devices
GET /v1/devices
The devices paired to this account, oldest first, paged by device id. online filters on presence (seen within the last two minutes). Revoked devices are not listed.
A caller key holding devices:read (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Query parameters
limitinteger optionalItems per page, 1-100.
after_idstring optionalReturn the page after this resource id (the previous page’s
last_id).before_idstring optionalReturn the page before this resource id (the next page’s
first_id).onlinestring optionalOnly devices that are (
true) or are not (false) online now. One oftrue,false.
Response 200
A page of devices.
objectstring requiredOne of
list.dataarray of Device required13 fields
idstring requiredobjectstring requiredOne of
device.kindstring requiredlabelstring requiredfingerprintstring requiredcreated_atstring requiredlast_seen_atstring | null requiredonlineboolean requiredcapabilitiesobject5 fields
tools_countinteger requiredhub_portintegerhelper_versionstringheld_vendorsarray of string requiredheld_modelsarray of string required
agentAgentDeviceFacetPresent only on a Device of kind
agent_computer.6 fields
agent_vendorstring requiredThe agent VM vendor, as it declared itself at link time.
genericis any other agent. One ofgrok-bot,muse,dots,manus,cursor-cloud,devin,replit,genspark,kimi,generic.tierstring requiredlink: terminal and relay only.data: link plus the synced data the linking app granted. One oflink,data.statestring requiredonline: polling now.asleep: suspended by its vendor (jobs waitqueued_asleep).offline: not seen recently. One ofonline,asleep,offline.expires_atstring requiredThe next lifecycle deadline (ISO 8601), the one
expiry_kindnames. Warned 3 days ahead.expiry_kindstring requireddata_idle: 14 days idle drops the data tier to link.reconfirm: the 90-day re-confirm is due (missed: link tier).link_idle: 30 days idle unlinks it. One ofdata_idle,reconfirm,link_idle.reconfirm_due_atstring | null requiredWhen the data tier must be re-confirmed (POST /me/devices/{device_id}/agent-reconfirm); null at the link tier.
keystringWhether this device holds the account's current end-to-end encryption key, from its own last report.
linked: it holds the current key.not_linked: it holds none (it can still add logins, which reach the other devices).out_of_date: it holds an older or a different key.unknown: it has not reported, or the account has no key yet. Absent on a device that holds no key (an agent computer, an API key, an MCP connector, the cloud computer, a web browser: browsers never hold the key). A desktop app reports through its Helper (custody_via). One oflinked,not_linked,out_of_date,unknown.custody_viastringThe id of the device whose key this one uses (a desktop app names its Helper);
keyis that device's state. Absent when the device holds its own.created_viastringPresent only on a Device of kind
agent_computer.app_link: linked through the app-minted link, so the vendor was recorded by the app and may be shown as verified.device_code: the agent claimed its own vendor at a device-code approval, so show it as unverified. A missing value isdevice_code. One ofapp_link,device_code.
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.
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 |
| 429 | rate_limited | Over the per-key request bucket; retry after |
curl
curl -sS -X GET "https://superbot.gg/v1/devices" \
-H "Authorization: Bearer $SUPERBOT_API_KEY"JavaScript
const res = await fetch(`https://superbot.gg/v1/devices`, {
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/devices",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
},
)
print(res.status_code, res.json())200 A page of devices.
{
"object": "list",
"data": [
{
"id": "your-id",
"object": "device",
"kind": "your-kind",
"label": "your-label",
"fingerprint": "your-fingerprint",
"created_at": "your-created-at",
"last_seen_at": "your-last-seen-at",
"online": true,
"capabilities": {
"tools_count": 0,
"hub_port": 0,
"helper_version": "your-helper-version",
"held_vendors": [],
"held_models": []
},
"agent": {
"agent_vendor": "grok-bot",
"tier": "link",
"state": "online",
"expires_at": "your-expires-at",
"expiry_kind": "data_idle",
"reconfirm_due_at": "your-reconfirm-due-at"
},
"key": "linked",
"custody_via": "your-custody-via",
"created_via": "app_link"
}
],
"has_more": true,
"first_id": "your-first-id",
"last_id": "your-last-id"
}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"
}429 Over the per-key request bucket; retry after x-ratelimit-reset.
{
"error": "rate_limited",
"message": "Over the per-key request bucket; retry after x-ratelimit-reset.",
"doc_url": "https://superbot.gg/developers#errors-rate_limited",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Get a devicelink to Get a device
GET /v1/devices/{device_id}
One device, with its live capabilities when it is connected.
A caller key holding devices:read (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
device_idstring requiredThe device id (a Device
id).
Response 200
The device.
idstring requiredobjectstring requiredOne of
device.kindstring requiredlabelstring requiredfingerprintstring requiredcreated_atstring requiredlast_seen_atstring | null requiredonlineboolean requiredcapabilitiesobject5 fields
tools_countinteger requiredhub_portintegerhelper_versionstringheld_vendorsarray of string requiredheld_modelsarray of string required
agentAgentDeviceFacetPresent only on a Device of kind
agent_computer.6 fields
agent_vendorstring requiredThe agent VM vendor, as it declared itself at link time.
genericis any other agent. One ofgrok-bot,muse,dots,manus,cursor-cloud,devin,replit,genspark,kimi,generic.tierstring requiredlink: terminal and relay only.data: link plus the synced data the linking app granted. One oflink,data.statestring requiredonline: polling now.asleep: suspended by its vendor (jobs waitqueued_asleep).offline: not seen recently. One ofonline,asleep,offline.expires_atstring requiredThe next lifecycle deadline (ISO 8601), the one
expiry_kindnames. Warned 3 days ahead.expiry_kindstring requireddata_idle: 14 days idle drops the data tier to link.reconfirm: the 90-day re-confirm is due (missed: link tier).link_idle: 30 days idle unlinks it. One ofdata_idle,reconfirm,link_idle.reconfirm_due_atstring | null requiredWhen the data tier must be re-confirmed (POST /me/devices/{device_id}/agent-reconfirm); null at the link tier.
keystringWhether this device holds the account's current end-to-end encryption key, from its own last report.
linked: it holds the current key.not_linked: it holds none (it can still add logins, which reach the other devices).out_of_date: it holds an older or a different key.unknown: it has not reported, or the account has no key yet. Absent on a device that holds no key (an agent computer, an API key, an MCP connector, the cloud computer, a web browser: browsers never hold the key). A desktop app reports through its Helper (custody_via). One oflinked,not_linked,out_of_date,unknown.custody_viastringThe id of the device whose key this one uses (a desktop app names its Helper);
keyis that device's state. Absent when the device holds its own.created_viastringPresent only on a Device of kind
agent_computer.app_link: linked through the app-minted link, so the vendor was recorded by the app and may be shown as verified.device_code: the agent claimed its own vendor at a device-code approval, so show it as unverified. A missing value isdevice_code. One ofapp_link,device_code.
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. |
| 429 | rate_limited | Over the per-key request bucket; retry after |
curl
curl -sS -X GET "https://superbot.gg/v1/devices/$DEVICE_ID" \
-H "Authorization: Bearer $SUPERBOT_API_KEY"JavaScript
const deviceId = 'DEVICE_ID';
const res = await fetch(`https://superbot.gg/v1/devices/${deviceId}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
},
});
console.log(res.status, await res.json());Python
import os
import requests
device_id = "DEVICE_ID"
res = requests.request(
"GET",
f"https://superbot.gg/v1/devices/{device_id}",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
},
)
print(res.status_code, res.json())200 The device.
{
"id": "your-id",
"object": "device",
"kind": "your-kind",
"label": "your-label",
"fingerprint": "your-fingerprint",
"created_at": "your-created-at",
"last_seen_at": "your-last-seen-at",
"online": true,
"capabilities": {
"tools_count": 0,
"hub_port": 0,
"helper_version": "your-helper-version",
"held_vendors": [
"your-held-vendors"
],
"held_models": [
"your-held-models"
]
},
"agent": {
"agent_vendor": "grok-bot",
"tier": "link",
"state": "online",
"expires_at": "your-expires-at",
"expiry_kind": "data_idle",
"reconfirm_due_at": "your-reconfirm-due-at"
},
"key": "linked",
"custody_via": "your-custody-via",
"created_via": "app_link"
}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"
}429 Over the per-key request bucket; retry after x-ratelimit-reset.
{
"error": "rate_limited",
"message": "Over the per-key request bucket; retry after x-ratelimit-reset.",
"doc_url": "https://superbot.gg/developers#errors-rate_limited",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Rename a devicelink to Rename a device
PATCH /v1/devices/{device_id}
Set the device label. The label survives later activity from the device.
A caller key holding devices:write (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
device_idstring requiredThe device id (a Device
id).
Request body
labelstring requiredThe new label, 1-64 printable characters (trimmed).
Response 200
The renamed device.
idstring requiredobjectstring requiredOne of
device.kindstring requiredlabelstring requiredfingerprintstring requiredcreated_atstring requiredlast_seen_atstring | null requiredonlineboolean requiredcapabilitiesobject5 fields
tools_countinteger requiredhub_portintegerhelper_versionstringheld_vendorsarray of string requiredheld_modelsarray of string required
agentAgentDeviceFacetPresent only on a Device of kind
agent_computer.6 fields
agent_vendorstring requiredThe agent VM vendor, as it declared itself at link time.
genericis any other agent. One ofgrok-bot,muse,dots,manus,cursor-cloud,devin,replit,genspark,kimi,generic.tierstring requiredlink: terminal and relay only.data: link plus the synced data the linking app granted. One oflink,data.statestring requiredonline: polling now.asleep: suspended by its vendor (jobs waitqueued_asleep).offline: not seen recently. One ofonline,asleep,offline.expires_atstring requiredThe next lifecycle deadline (ISO 8601), the one
expiry_kindnames. Warned 3 days ahead.expiry_kindstring requireddata_idle: 14 days idle drops the data tier to link.reconfirm: the 90-day re-confirm is due (missed: link tier).link_idle: 30 days idle unlinks it. One ofdata_idle,reconfirm,link_idle.reconfirm_due_atstring | null requiredWhen the data tier must be re-confirmed (POST /me/devices/{device_id}/agent-reconfirm); null at the link tier.
keystringWhether this device holds the account's current end-to-end encryption key, from its own last report.
linked: it holds the current key.not_linked: it holds none (it can still add logins, which reach the other devices).out_of_date: it holds an older or a different key.unknown: it has not reported, or the account has no key yet. Absent on a device that holds no key (an agent computer, an API key, an MCP connector, the cloud computer, a web browser: browsers never hold the key). A desktop app reports through its Helper (custody_via). One oflinked,not_linked,out_of_date,unknown.custody_viastringThe id of the device whose key this one uses (a desktop app names its Helper);
keyis that device's state. Absent when the device holds its own.created_viastringPresent only on a Device of kind
agent_computer.app_link: linked through the app-minted link, so the vendor was recorded by the app and may be shown as verified.device_code: the agent claimed its own vendor at a device-code approval, so show it as unverified. A missing value isdevice_code. One ofapp_link,device_code.
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. |
| 429 | rate_limited | Over the per-key request bucket; retry after |
curl
curl -sS -X PATCH "https://superbot.gg/v1/devices/$DEVICE_ID" \
-H "Authorization: Bearer $SUPERBOT_API_KEY" \
-H "content-type: application/json" \
-d '{"label":"Studio Mac"}'JavaScript
const deviceId = 'DEVICE_ID';
const res = await fetch(`https://superbot.gg/v1/devices/${deviceId}`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
'content-type': 'application/json',
},
body: JSON.stringify({"label":"Studio Mac"}),
});
console.log(res.status, await res.json());Python
import os
import requests
device_id = "DEVICE_ID"
res = requests.request(
"PATCH",
f"https://superbot.gg/v1/devices/{device_id}",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
"content-type": "application/json",
},
json={"label":"Studio Mac"},
)
print(res.status_code, res.json())200 The renamed device.
{
"id": "your-id",
"object": "device",
"kind": "your-kind",
"label": "your-label",
"fingerprint": "your-fingerprint",
"created_at": "your-created-at",
"last_seen_at": "your-last-seen-at",
"online": true,
"capabilities": {
"tools_count": 0,
"hub_port": 0,
"helper_version": "your-helper-version",
"held_vendors": [
"your-held-vendors"
],
"held_models": [
"your-held-models"
]
},
"agent": {
"agent_vendor": "grok-bot",
"tier": "link",
"state": "online",
"expires_at": "your-expires-at",
"expiry_kind": "data_idle",
"reconfirm_due_at": "your-reconfirm-due-at"
},
"key": "linked",
"custody_via": "your-custody-via",
"created_via": "app_link"
}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"
}429 Over the per-key request bucket; retry after x-ratelimit-reset.
{
"error": "rate_limited",
"message": "Over the per-key request bucket; retry after x-ratelimit-reset.",
"doc_url": "https://superbot.gg/developers#errors-rate_limited",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}Unlink a devicelink to Unlink a device
DELETE /v1/devices/{device_id}
Sign the device out: its tokens and the caller keys it minted are revoked. The caller's own device answers 409 own_device (sign out from that device instead).
A caller key holding devices:write (Authorization: Bearer sbc_… or x-api-key: sbc_…), or a signed-in session.
Path parameters
device_idstring requiredThe device id (a Device
id).
Response 200
The device was unlinked.
idstring requiredobjectstring requiredOne of
device.deletedboolean requiredOne of
true.agent_unlinkAgentUnlinkWhat unlinking an agent computer did, and the credentials to rotate at the source.
5 fields
device_idstring requiredreasonstring requiredOne of
user,revoked,link_idle.cancelledobject required7 fields
jobsinteger requiredterminalsinteger requiredlociinteger requiredpromptsinteger requiredpair_requestsinteger requiredlive_sessionsinteger requiredautomationsinteger required
keyobject required3 fields
holder_removedboolean requiredfactor_wraps_removedinteger requiredrotationstring requiredOne of
enqueued,no_holder_device,not_needed.
rotate_at_sourcearray of object required4 fields
kindstring requiredadapterstring requiredlabelstring | null requiredclassstring required
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. |
| 429 | rate_limited | Over the per-key request bucket; retry after |
curl
curl -sS -X DELETE "https://superbot.gg/v1/devices/$DEVICE_ID" \
-H "Authorization: Bearer $SUPERBOT_API_KEY"JavaScript
const deviceId = 'DEVICE_ID';
const res = await fetch(`https://superbot.gg/v1/devices/${deviceId}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.SUPERBOT_API_KEY}`,
},
});
console.log(res.status, await res.json());Python
import os
import requests
device_id = "DEVICE_ID"
res = requests.request(
"DELETE",
f"https://superbot.gg/v1/devices/{device_id}",
headers={
"Authorization": f"Bearer {os.environ['SUPERBOT_API_KEY']}",
},
)
print(res.status_code, res.json())200 The device was unlinked.
{
"id": "your-id",
"object": "device",
"deleted": true,
"agent_unlink": {
"device_id": "your-device-id",
"reason": "user",
"cancelled": {
"jobs": 0,
"terminals": 0,
"loci": 0,
"prompts": 0,
"pair_requests": 0,
"live_sessions": 0,
"automations": 0
},
"key": {
"holder_removed": true,
"factor_wraps_removed": 0,
"rotation": "enqueued"
},
"rotate_at_source": [
{
"kind": "your-kind",
"adapter": "your-adapter",
"label": "your-label",
"class": "your-class"
}
]
}
}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"
}429 Over the per-key request bucket; retry after x-ratelimit-reset.
{
"error": "rate_limited",
"message": "Over the per-key request bucket; retry after x-ratelimit-reset.",
"doc_url": "https://superbot.gg/developers#errors-rate_limited",
"request_id": "req_5f1c0a9e2b7d4c3a1e0f9b8d"
}No operation matches this filter.