BuddyBots HTTP + WebSocket API
All JSON. When BB_TOKEN is set, send it as Authorization: Bearer <token> (the web app uses a cookie). In hosted mode (BB_MULTI=1) every route except /api/health, /api/auth/*, the OAuth/Composio callbacks and webhooks needs the bb_sid session cookie from POST /api/auth/login; ids of another organisation answer 404. Errors: { error, requestId }. Generated from server/src/routes.ts and server/src/index.ts.
WebSocket
GET /ws— app events (WsEventinshared/types.ts): messages, tasks,task.phase,computer.update,screen.frame(send{type:'watch',botId}),workspace.switch,chrome.ext.GET /ext?token=<pairing token>— the BuddyBots Chrome extension. Server → extension:{id, op:'tab.create'|'tab.get'|'tab.focus'|'tab.close'|'tab.navigate'|'tab.back'|'tab.screenshot'|'dom'|'tab.realClick'|'tab.record', tabId?, url?, fn?, args?, x?, y?, on?}(tab.realClick= a trusted click via chrome.debugger at viewport x,y;tab.recordstarts/stops recording the owner's own actions in that tab, relayed as{type:'event', name:'recorded', tabId, step}); extension → server:{id, ok, result|error},{type:'hello', ua, version},{type:'event', name:'tab.removed'|'tab.updated'|'detached', tabId}. Pairing code (http://127.0.0.1:PORT#TOKEN) fromGET /api/chrome.
activity
GET /api/activityGET /api/activity/export
approvals
GET /api/approvalsGET /api/approvals/:idPOST /api/approvals/:id/decide
auth (hosted mode, BB_MULTI=1)
POST /api/auth/signup—{ email, password (10+), name?, orgName? }→AuthInfo, setsbb_sidcookie; creates the user, their organisation (roleowner) and a first workspace.POST /api/auth/login—{ email, password, orgId? }→AuthInfo, sets the cookie.POST /api/auth/logoutclears it.GET /api/auth/me—AuthInfo({ multi:false }in local mode;{ multi:true }signed out).POST /api/auth/password—{ current, next }; ends every other session of the user.GET /api/auth/orgs·POST /api/auth/orgs{ name }(new organisation, you become owner, session switches to it) ·POST /api/auth/switch{ orgId }.GET /api/auth/members→{ members, invites }·POST /api/auth/invite{ email, role: 'admin'|'member' }→{ token, url }(owner/admin) ·POST /api/auth/accept{ token }(signed in as that email) ·DELETE /api/auth/members/:userId·DELETE /api/auth/invites/:id.
billing, admin, crews, shares, data (hosted mode)
GET /api/billing→{ state: LimitState, plans, breakdown, stripe, org }·POST /api/billing/checkout{ plan: 'pro'|'team', seats? }→{ url }·POST /api/billing/portal→{ url }·POST /api/billing/budget{ usd }·POST /api/billing/webhook(Stripe-signed).- Admin (
BB_ADMIN_EMAILS):GET /api/admin/orgs,POST /api/admin/orgs/:id/plan{ plan, status? },POST /api/admin/orgs/:id/credits{ delta, reason },POST /api/admin/orgs/:id/report-overage,POST /api/admin/orgs/:id/undelete,GET /api/admin/metrics,GET /api/admin/events. - Crews:
GET /api/crews,POST /api/crews/:id/apply{ start? }→{ bots, roomId, leadId, firstTask }. - Built-in connectors:
GET /api/connectors/builtin,POST /api/connectors/builtin/:id{ fields }. - Shares:
GET /api/shares,POST /api/shares{ type: 'task'|'bot'|'room', id }→{ token, url },DELETE /api/shares/:token; public pageGET /s/:token. - Trust:
POST /api/auth/reset{ email },POST /api/auth/reset/finish{ token, password },POST /api/auth/verify{ token },POST /api/auth/verify/resend,POST /api/auth/accept-terms,GET /api/audit,GET /api/data/export(zip),POST /api/data/delete{ confirm: <org name>, password }. - Public:
GET /api/status→{ ok, version, sandbox, uptimeS, bots, multi }; site pages/,/pricing,/docs/*,/terms,/privacy,/status; app at/app.
learning
GET /api/learning→{ summary, stats, notes, paths, improvement }·POST /api/learning/notes{ domain, text }·PATCH /api/learning/notes/:id{ text?, enabled? }·DELETE /api/learning/notes/:id·DELETE /api/learning/paths/:id.
bootstrap
GET /api/bootstrap— also carriesauth: AuthInfo.
bots
GET /api/botsPOST /api/botsPOST /api/bots/generatePATCH /api/bots/:idDELETE /api/bots/:idPOST /api/bots/:id/duplicatePOST /api/bots/:id/stopPOST /api/bots/:id/readPOST /api/bots/:id/unreadGET /api/bots/:id/exportPOST /api/bots/importGET /api/bots/:id/tasksGET /api/bots/:id/memoryPOST /api/bots/:id/memoryGET /api/bots/:id/analyticsGET /api/bots/:id/computerPOST /api/bots/:id/computer/openPOST /api/bots/:id/computer/signinPOST /api/bots/:id/computer/signin/donePOST /api/bots/:id/computer/help/skipPOST /api/bots/:id/computer/takeoverPOST /api/bots/:id/computer/show— bring the bot's tab to the front in the owner's ChromePOST /api/bots/:id/computer/inputPOST /api/bots/:id/computer/secretPOST /api/bots/:id/show-me/start{context?, taskId?, stepAction?, url?, convType?, convId?}— start a demonstration: the bot pauses, (re)opensurlif given, brings its tab to the front and records the owner's actions; returns{demo, computer}POST /api/bots/:id/show-me/stop— end it: the trace is turned into procedures (model when available) and a review card (data.tag = 'demo_review') is posted in the conversation; returns{demoId, steps, understood, message}POST /api/demos/:id/save{procedures?: [{title, intent?, keep?}]}/POST /api/demos/:id/discard— the owner's verdict; saved procedures appear inGET /api/learningasproceduresand as lesson notesPATCH /api/learning/procedures/:id{title?, intent?, enabled?}·DELETE /api/learning/procedures/:idPOST /api/bots/:id/computer/teach/start{fix?: {action, url?}}— withfix, "Show me how" for one step: the bot pauses on that page and records what the owner does;teach/stopthen saves a lesson note + step path for that site (returns{lesson, domain, steps}) instead of a skillPOST /api/bots/:id/computer/teach/startPOST /api/bots/:id/computer/teach/stopPOST /api/bots/:id/computer/ask
chrome
GET /api/chrome
claude-local
GET /api/claude-localPOST /api/claude-localPOST /api/claude-local/connectPOST /api/claude-local/connect/codePOST /api/claude-local/connect/cancelPOST /api/claude-local/testPOST /api/claude-local/apply
computer
GET /api/computer/snapshotsPOST /api/computer/snapshotsPOST /api/computer/recoverPOST /api/computer/reset
connectors
GET /api/connectorsPOST /api/connectorsPOST /api/connectors/quickPOST /api/connectors/:id/callPOST /api/connectors/:id/writesPATCH /api/connectors/:idDELETE /api/connectors/:id
conversations
GET /api/conversations/:type/:id/messagesPOST /api/conversations/:type/:id/messages
ext
GET /ext— The BuddyBots Chrome extension connects here (pairing token in the query) and relays tab + DevTools commands.
files
GET /api/filesGET /api/files/previewDELETE /api/files
health
GET /api/health
hooks
POST /api/hooks/:id
keys
GET /api/keysPUT /api/keys/:providerDELETE /api/keys/:provider
login
GET /loginPOST /login
POST /api/mail/check
memory
PATCH /api/memory/:idDELETE /api/memory/:id
messages
GET /api/messages/:id/threadPOST /api/messages/:id/react
rooms
GET /api/roomsPOST /api/roomsPATCH /api/rooms/:idDELETE /api/rooms/:idPOST /api/rooms/:id/readPOST /api/rooms/:id/unread
routines
GET /api/routinesPOST /api/routinesPATCH /api/routines/:idDELETE /api/routines/:idPOST /api/routines/:id/testGET /api/routines/:id/runs
rules
GET /api/rulesPOST /api/rulesDELETE /api/rules/:id
search
GET /api/search
settings
GET /api/settingsPATCH /api/settings
skills
GET /api/skillsPUT /api/skills/:idDELETE /api/skills/:id
t
GET /t/:file
tasks
GET /api/tasks/:idPOST /api/tasks/:id/stop
templates
GET /api/templatesGET /api/templates/grok-export-promptPOST /api/templatesPOST /api/templates/from-bot/:idDELETE /api/templates/:idGET /api/templates/:id/exportPOST /api/templates/:id/share— opt-in public link; the token is unguessable and only this template is exposedDELETE /api/templates/:id/sharePOST /api/templates/import— Preview only: nothing is saved until the client posts the result to /api/templates (or creates a bot from it).
upload
POST /api/upload
usage
GET /api/usage
workspaces
GET /api/workspacesPOST /api/workspacesPOST /api/workspaces/:id/switchPATCH /api/workspaces/:idDELETE /api/workspaces/:id
ws
GET /ws