StarkBee Gateway¶
StarkBee partner gateway: trial activation, status, agent connectivity.
All endpoints below are mounted under /api. Authentication: Authorization: Bearer <token> unless noted as public.
Endpoint count: 14
Endpoints¶
| Method | Path | Handler | Guards |
|---|---|---|---|
POST |
/api/starkbee/activate |
starkbeeActivate |
AuthWithDB(cfg.JWTSecret, db) |
GET |
/api/starkbee/chat |
starkbeeChatWS |
- |
DELETE |
/api/starkbee/gateway |
starkbeeGatewayUninstall |
AuthWithDB(cfg.JWTSecret, db) |
POST |
/api/starkbee/gateway/install |
starkbeeGatewayInstall |
AuthWithDB(cfg.JWTSecret, db) |
POST |
/api/starkbee/gateway/restart |
starkbeeGatewayRestart |
AuthWithDB(cfg.JWTSecret, db) |
GET |
/api/starkbee/gateway/status |
starkbeeGatewayStatus |
AuthWithDB(cfg.JWTSecret, db) |
POST |
/api/starkbee/gateway/stop |
starkbeeGatewayStop |
AuthWithDB(cfg.JWTSecret, db) |
DELETE |
/api/starkbee/messages |
starkbeeClearMessages |
AuthWithDB(cfg.JWTSecret, db) |
GET |
/api/starkbee/messages |
starkbeeListMessages |
AuthWithDB(cfg.JWTSecret, db) |
GET |
/api/starkbee/status |
starkbeeStatus |
AuthWithDB(cfg.JWTSecret, db) |
DELETE |
/api/starkbee/telegram |
starkbeeTelegramDisconnect |
AuthWithDB(cfg.JWTSecret, db) |
GET |
/api/starkbee/telegram |
starkbeeTelegramGet |
AuthWithDB(cfg.JWTSecret, db) |
PATCH |
/api/starkbee/telegram |
starkbeeTelegramSave |
AuthWithDB(cfg.JWTSecret, db) |
POST |
/api/starkbee/telegram |
starkbeeTelegramSave |
AuthWithDB(cfg.JWTSecret, db) |
Source¶
Handlers for this section live in api/routes/handlers_*.go in the StarkOne source. Each handler binds its request body with gin.ShouldBindJSON(&req) and responds with the standard envelope:
On error:
Reference¶
POST /api/starkbee/activate¶
Performs the one-time StarkBee trial provisioning by calling the upstream partner API (api.starkbee.ai) and persisting the returned token, WebSocket URL, and expiry locally.
Guards: AuthWithDB(cfg.JWTSecret, db)
Request body
This endpoint takes no request body fields; it derives the license ID, hostname, and system prompt server-side.
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
409 |
already_activated |
A trial is already active on this server (activation is one-time per license). The response also includes a trial object with expires_at, activated_at, and blocked. |
500 |
build_misconfigured |
Panel was built without STARKBEE_PARTNER_SECRET. |
502 |
partner_secret_rejected |
Upstream rejected the panel's partner secret (remapped from upstream 401). |
502 |
starkbee_error |
Generic upstream partner error (the upstream code/message is passed through; upstream 401/403 are remapped to 502). |
502 |
starkbee_unreachable |
Could not reach the StarkBee partner API. |
500 |
save_failed |
Trial was created upstream but persisting it locally failed. |
Side effects
- Best-effort creation of
DATA_DIRand reference files viaEnsureDataDir. - Outbound HTTPS POST to
api.starkbee.ai/api/partner/trials. - Persists the trial row (token, ws_url, expires_at, license_used) to the panel DB via
SaveTrial.
Example
curl -X POST https://panel.example.com:2087/api/starkbee/activate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json"
GET /api/starkbee/chat¶
WebSocket endpoint that upgrades the browser connection and bridges chat frames bidirectionally between the panel browser and the upstream StarkBee WSS, persisting messages and intercepting blocked events.
Note: This is a WebSocket upgrade endpoint, not a standard JSON GET. The browser sends { "type": "message", "text": "..." } frames; the server forwards upstream frames (banner, typing, done, blocked, error) back to the browser. There is no enveloped JSON 200 response - the connection is upgraded to a WebSocket.
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
not_activated |
No trial is activated on this server; activate first. |
The endpoint also writes an in-band WebSocket frame { "type": "error", "text": "Could not reach StarkBee..." } if the upstream WSS dial fails after the browser connection is already upgraded.
Side effects
- Opens an outbound WebSocket connection to the upstream
ws_urlstored on the trial. - Persists user messages (role
user) before forwarding viaSaveMessage. - Persists assistant replies on
done/blockedframes (roleassistant) viaSaveMessage. - On a
blockedframe, flips the trial's blocked flag viaMarkBlocked.
Example
# WebSocket handshake (illustrative); use a WebSocket client in practice.
curl -i -N \
-H "Authorization: Bearer $TOKEN" \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
https://panel.example.com:2087/api/starkbee/chat
DELETE /api/starkbee/gateway¶
Uninstalls the StarkBee gateway agent and removes its DB row.
Guards: AuthWithDB(cfg.JWTSecret, db)
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
uninstall_failed |
Uninstall failed; the response also includes an output field with command output. |
Side effects
- Runs the gateway uninstall routine (
starkbee.Uninstall), which removes the installed agent and deletes the gateway DB row.
Example
curl -X DELETE https://panel.example.com:2087/api/starkbee/gateway \
-H "Authorization: Bearer $TOKEN"
POST /api/starkbee/gateway/install¶
Starts the StarkBee gateway installer in a background goroutine and returns 202 Accepted immediately; progress is observed by polling the status endpoint.
Guards: AuthWithDB(cfg.JWTSecret, db)
Request body
| Field | Type | Required | Description |
|---|---|---|---|
token |
string | yes | Gateway token used to install/authenticate the agent. Trimmed of surrounding whitespace before use. |
Response - 202 Accepted
{
"data": {
"installing": true,
"message": "Installation started. Poll /api/starkbee/gateway/status?include_log=1 for progress."
}
}
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed to bind (e.g. missing token). |
400 |
install_failed |
Installer rejected the request (e.g. invalid token). |
409 |
install_failed |
Gateway is already installed (error message contains "already installed"). |
Side effects
- Launches the gateway installer in the background (
starkbee.Install), which provisions the agent on the host and writes install state/log to the DB.
Example
curl -X POST https://panel.example.com:2087/api/starkbee/gateway/install \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"token": "gw_example_token"}'
POST /api/starkbee/gateway/restart¶
Restarts the gateway agent process via pm2.
Guards: AuthWithDB(cfg.JWTSecret, db)
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
pm2_error |
pm2 restart failed; the response also includes an output field with command output. |
Side effects
- Executes a pm2 restart of the gateway process (
starkbee.Restart).
Example
curl -X POST https://panel.example.com:2087/api/starkbee/gateway/restart \
-H "Authorization: Bearer $TOKEN"
GET /api/starkbee/gateway/status¶
Returns the combined DB + pm2 status view of the gateway, optionally including the install log.
Guards: AuthWithDB(cfg.JWTSecret, db)
Query parameters
| Name | Type | Optional | Description |
|---|---|---|---|
include_log |
string | yes | When non-empty, includes the gateway install_log in the response. |
Response - 200 OK
This handler returns a flat (non-enveloped) JSON body. When no gateway is installed it returns { "installed": false }. Otherwise:
{
"installed": true,
"install_status": "done",
"installed_at": "2026-06-17T00:00:00Z",
"running": true,
"uptime_ms": 123456,
"memory_bytes": 10485760,
"restart_count": 0,
"cpu_percent": 0.5,
"pm_id": 3,
"pm2_status": "online",
"last_error": "",
"install_log": "...(only when include_log is set)"
}
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
server_error |
Failed to read gateway status from the DB/pm2. |
Example
curl -X GET "https://panel.example.com:2087/api/starkbee/gateway/status?include_log=1" \
-H "Authorization: Bearer $TOKEN"
POST /api/starkbee/gateway/stop¶
Stops the gateway agent process via pm2.
Guards: AuthWithDB(cfg.JWTSecret, db)
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
pm2_error |
pm2 stop failed; the response also includes an output field with command output. |
Side effects
- Executes a pm2 stop of the gateway process (
starkbee.Stop).
Example
curl -X POST https://panel.example.com:2087/api/starkbee/gateway/stop \
-H "Authorization: Bearer $TOKEN"
DELETE /api/starkbee/messages¶
Clears the StarkBee chat history for the current panel user.
Guards: AuthWithDB(cfg.JWTSecret, db)
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
server_error |
Failed to clear messages in the DB. |
Side effects
- Deletes the current user's chat messages from the DB (
starkbee.ClearMessages).
Example
curl -X DELETE https://panel.example.com:2087/api/starkbee/messages \
-H "Authorization: Bearer $TOKEN"
GET /api/starkbee/messages¶
Returns the StarkBee chat history (up to 200 messages) for the current panel user.
Guards: AuthWithDB(cfg.JWTSecret, db)
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
server_error |
Failed to read messages from the DB. |
Example
curl -X GET https://panel.example.com:2087/api/starkbee/messages \
-H "Authorization: Bearer $TOKEN"
GET /api/starkbee/status¶
Reports trial activation state (days remaining, blocked status, expiry) along with a summary of the connected Telegram bot, used by the AI page to decide which section to render.
Guards: AuthWithDB(cfg.JWTSecret, db)
Response - 200 OK
This handler returns a flat (non-enveloped) JSON body. When no trial exists, only build_ok and activated are present:
{
"build_ok": true,
"activated": true,
"expires_at": "2026-07-17T00:00:00Z",
"activated_at": "2026-06-17T00:00:00Z",
"blocked": false,
"blocked_message": "...(present only when blocked is true)",
"days_left": 30,
"telegram": {
"connected": true,
"bot_username": "example_bot",
"enabled": true
}
}
When Telegram is not configured, telegram is { "connected": false }.
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
server_error |
Failed to read trial state from the DB. |
Example
DELETE /api/starkbee/telegram¶
Disconnects the Telegram bot by clearing the upstream telegram_token (which also disables the bot) and wiping the local bookkeeping row.
Guards: AuthWithDB(cfg.JWTSecret, db)
Response - 200 OK
If no active token exists, the handler still clears the local row and returns the same 200 body.
Errors
| Status | Code | Meaning |
|---|---|---|
502 |
partner_error |
Upstream partner API returned an error while clearing the token. |
502 |
partner_unreachable |
Could not reach the partner API. |
Side effects
- Pushes an empty
telegram_tokento the partner API (PushPartnerTelegram), disabling the bot upstream. - Deletes the local Telegram bookkeeping row (
DeleteTelegram).
Example
curl -X DELETE https://panel.example.com:2087/api/starkbee/telegram \
-H "Authorization: Bearer $TOKEN"
GET /api/starkbee/telegram¶
Reads the live Telegram configuration from the partner API and augments it with the locally cached bot username.
Guards: AuthWithDB(cfg.JWTSecret, db)
Response - 200 OK
When no active token (trial or gateway) exists, returns { "data": { "connected": false, "source": "none" } }. Otherwise the data object mirrors the upstream config:
{
"data": {
"connected": true,
"source": "trial",
"enabled": true,
"telegram_token": "123456:ABC...",
"allowed_users": "111,222",
"allowed_user_ids": "111,222",
"allowed_groups": "-1001234567890",
"admin_users": "111",
"mention_only": false,
"bot_username": "example_bot"
}
}
source is "gateway" or "trial" depending on which installation provided the active token. allowed_user_ids is a legacy alias for allowed_users. bot_username is present only when cached locally.
Errors
| Status | Code | Meaning |
|---|---|---|
502 |
partner_error |
Upstream partner API returned an error (upstream 401/403 are remapped to 502; other upstream statuses pass through). |
502 |
partner_unreachable |
Could not reach the partner API. |
Example
curl -X GET https://panel.example.com:2087/api/starkbee/telegram \
-H "Authorization: Bearer $TOKEN"
PATCH /api/starkbee/telegram¶
Pushes a partial Telegram configuration update to the partner API; any omitted field is left untouched upstream. Works for both trial and gateway installations (source auto-detected).
Guards: AuthWithDB(cfg.JWTSecret, db)
Request body
All fields are optional pointers; sending null/omitting a field leaves it untouched upstream, while sending an empty string clears it.
{
"bot_token": "string (optional)",
"allowed_user_ids": "string (optional)",
"allowed_users": "string (optional)",
"allowed_groups": "string (optional)",
"admin_users": "string (optional)",
"mention_only": false
}
| Field | Type | Required | Description |
|---|---|---|---|
bot_token |
string | no | Telegram bot token. Empty disables/clears the bot upstream. Non-empty is shape-checked (<digits>:<rest>). |
allowed_user_ids |
string | no | Legacy alias for allowed_users. Used only when allowed_users is absent. |
allowed_users |
string | no | Comma-separated Telegram user IDs (normalized/deduped; digits only). |
allowed_groups |
string | no | Comma-separated chat IDs; leading - allowed (e.g. -1001234567890). |
admin_users |
string | no | Comma-separated admin Telegram user IDs (digits only). |
mention_only |
boolean | no | Whether the bot only responds when mentioned. |
Response - 200 OK
{
"data": {
"ok": true,
"updated": true,
"pushed_live": true,
"source": "trial",
"bot_username": "example_bot"
}
}
bot_username is populated only when a new bot token was supplied and getMe succeeded.
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed to bind. |
400 |
no_token |
No active StarkBee installation (activate trial or install gateway first). |
400 |
bad_allowed_users |
allowed_users/allowed_user_ids contains invalid (non-digit) IDs. |
400 |
bad_allowed_groups |
allowed_groups contains invalid IDs. |
400 |
bad_admin_users |
admin_users contains invalid (non-digit) IDs. |
400 |
bad_token |
Bot token format looks wrong (expected <digits>:<rest>). |
502 |
partner_error |
Upstream partner API returned an error (upstream 401/403 remapped to 502). |
502 |
partner_unreachable |
Could not reach the partner API. |
Side effects
- Pushes the (partial) Telegram settings to the partner API (
PushPartnerTelegram). - On a new non-empty bot token: calls Telegram
getMeto fetch the bot username, then upserts the local Telegram bookkeeping row (SaveTelegram). - On an empty bot token: deletes the local Telegram row (
DeleteTelegram). - When only the allowlist changes: updates the local allowlist mirror.
Example
curl -X PATCH https://panel.example.com:2087/api/starkbee/telegram \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"bot_token": "123456:ABCdefGhIjKlmNoPqrStUvwxyz012345", "allowed_users": "111,222"}'
POST /api/starkbee/telegram¶
Identical to PATCH /api/starkbee/telegram - both methods map to the same starkbeeTelegramSave handler, which pushes a partial Telegram configuration update to the partner API (omitted fields untouched upstream). See the PATCH block above for the full request body, response, and error details.
Guards: AuthWithDB(cfg.JWTSecret, db)
Example