Call BusyBro — Busymate's AI assistant — programmatically over the ask Edge Function, and stream its answer back token-by-token. What it can read and do on your behalf is governed entirely by your role.
This is the API behind the dashboard's chat panel. For the product side — what BusyBro is, how it reverse-engineers captured traffic, the specialist lenses — see BusyBro.
TL;DR
| Endpoint | POST https://api.busymate.net/functions/v1/ask |
| Auth | Authorization: Bearer <token> — the same OAuth access token as REST/Realtime/MCP. |
| Request | { "question": "…", "history": [...]?, "context": "…"?, "priorAnswer": "…"? } |
| Response | Streaming SSE when you send Accept: text/event-stream; otherwise a blocking { "answer": "…" } JSON. |
| Scope | Reads + writes run as you — RLS + your role's capabilities bound every answer. |
Authentication
ask accepts the same OAuth access token as the rest of the API surface. Pass it as a bearer token:
Authorization: Bearer <token>The function validates the token, resolves your Busymate user, role, and capabilities, and runs every tool read under your RLS — so BusyBro only ever sees and does what you're allowed to. An unlinked/anonymous caller can't reach this endpoint; you authenticate as a real user.
Request body
{
"question": "how many devices are online right now?",
"history": [
{ "role": "user", "text": "list my devices" },
{ "role": "assistant", "text": "You have 3 devices: …" }
],
"context": "Viewing: Devices (/devices)",
"priorAnswer": "…"
}| Field | Type | Required | Meaning |
|---|---|---|---|
question | string | yes | What you're asking. |
history | array of { role, text } | no | Prior turns, oldest→newest (role is user or assistant). Malformed entries are dropped, degrading to single-turn rather than erroring. |
context | string | no | A short note about what you're currently looking at (e.g. Viewing: Devices (/devices)). Capped server-side. |
priorAnswer | string | no | The immediately preceding answer, for a "continue / refine" turn. |
The answer's surface is fixed to the web/dashboard (Markdown output) — there is no
surfacefield to set. The Telegram surface is driven by the bot, not this endpoint.
Streaming response (SSE)
Send Accept: text/event-stream to stream. The function emits these Server-Sent Events:
| Event | data | Meaning |
|---|---|---|
text | { "delta": "…" } | A chunk of the answer Markdown — append in order. |
tool | { "label": "…" } | BusyBro is running a tool (e.g. reading live data); show a status hint. |
artifact | (tool-specific object) | A structured artifact produced by a tool. |
done | { "answer": "…" } | The full final answer; the stream ends after this. |
error | { "message": "…" } | Something went wrong; a friendly message to show. |
: ping comment frames arrive roughly every 15s to hold the connection open while tools run. Abort the request to stop generation.
curl -sN -X POST https://api.busymate.net/functions/v1/ask \
-H "Authorization: Bearer $TOKEN" \
-H "content-type: application/json" \
-H "accept: text/event-stream" \
-d '{ "question": "what is the busiest domain in the last hour?" }'Blocking response (JSON)
Omit Accept: text/event-stream and you get a single JSON object once the answer is complete:
curl -s -X POST https://api.busymate.net/functions/v1/ask \
-H "Authorization: Bearer $TOKEN" \
-H "content-type: application/json" \
-d '{ "question": "how many devices are online right now?" }'{ "answer": "You have 3 devices online: BMH3, iPad, and the proxy-server. …" }What BusyBro can do for you
Everything is bounded by your role:
- Read live data — stats, devices, settings, captured entries, and (where your role permits) users and breakpoints — all RLS-scoped to you.
- Reverse-engineer captured traffic — explain a real app's auth flow from its actual captured headers/bodies and hand you a runnable repro. Secrets (tokens, cookies, keys) are emitted as placeholders, never echoed.
- Search the web for current/external info, with citations.
- Perform capability-gated write actions — only what your role allows, only on devices you own; destructive fleet operations are never exposed.
The full capability surface and the specialist-lens model live on the BusyBro product page. The same write actions are also available as MCP tools.
Troubleshooting
| Symptom | Cause / fix |
|---|---|
401 unauthorized | Missing/expired token, or it isn't a valid OAuth access token. Use the same token as REST. |
400 bad_request | question is missing or not a string. |
| Answer is read-only / declines a write | Your role lacks the matching edit capability, or the device isn't yours. See Roles & permissions. |
Stream stalls then a : ping arrives | Expected — a tool is running; the ping holds the connection. The done event delivers the final answer. |