# Bot API Each bot can take messages from outside: an app or a script sends it a message with a key and gets its reply. It is off by default, per bot. ## Turning it on In Bot settings (the gear in the bot's panel; Advanced: Access), **Bot API**: switch on **Let apps talk to this bot**. The card shows the command to paste, with the key filled in. The key is shown that once and kept hashed; when the card is opened again the command shows `YOUR_KEY` in its place. **New key** replaces the key (apps using the old one stop working); switching the card off forgets it. Only someone who may edit the bot can switch it on, mint a key or switch it off; each of those is a **Bot API** row in Settings → Activity. ## Plans Bot API isn't part of a Cloud's Starter plan. There the card shows one line and Upgrade; a new key is refused, and a key left from a higher plan answers `403` with an upgrade message. An upgrade works at once, with the same key. Desktop and self-hosted servers aren't affected. ## Calling it ```sh curl -X POST "https://your.domain/hooks/api/bots//messages" \ -H "Authorization: Bearer YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"message": "Hello! What can you do?"}' ``` The address lives under the webhook receiver's `/hooks` path, so wherever this bot's webhooks are reachable (a Cloud's public name, a self-hosted edge that forwards `/hooks/*` as [deploy/Caddyfile](../deploy/Caddyfile) does, or `OMB_WEBHOOK_PUBLIC_URL`) the API is too; nothing new to open. The JSON body takes: - `message` (required, up to 20,000 characters): what to tell the bot. - `thread` (optional): the `thread` an earlier answer returned, to go on in the same conversation. Only a thread the API opened can be continued this way. - `wait` (optional, seconds, at most 300): how long to wait for the reply before answering `working`. The default is 50, under the 60 seconds of silence Fly's proxy is reported to allow; a longer wait is for a path you know keeps a quiet connection open. Answers: - `200 {"reply": "…", "thread": ""}`: the bot's reply, text only. - `202 {"thread": "", "status": "working"}`: the bot is still at it. Read the thread later with `GET …/messages?thread=` and the same key. - `202 {"thread": "", "status": "needs_approval"}`: the bot asked for an approval. Nobody outside can give it: the person opens the thread in the app and answers there; a later `GET` returns the reply. - `400` bad body, `401` wrong key, `403` the API is off for this bot (or there is no such bot), `404` no such thread, `409` that thread is still working or the bot is at its limit of conversations at once, or 50 API calls are being answered, `413` body over 256 KB, `415` not JSON, `429` more than ten calls in a minute for this key, `502` the bot could not answer (the reason is on the card, not in the response). ## What a call may do A call starts a normal thread the app shows, marked as sent through the Bot API. Anything in that thread answers only from the bot's standing instructions, its saved memory and the thread itself, whoever writes there next: - It runs confined and in Ask, whatever the bot's own level, with none of its saved allowances. Nothing answers an approval for the caller. - It has no shell, computer, browser, phone, connected apps, MCP servers or data tools, and none of OpenMausBot's own tools, so it can't start a thread, ask a teammate, make a routine or webhook, change the bot, write its memory or search other conversations. - It works in the thread's own empty folder, and its words stay out of the person's other conversations. A call that fails shows on the card and in its thread, and reports to no Chief. A key is like a password: whoever holds it can read what this bot can read, which here means its instructions and memory, through its replies. A bot whose AI can't run confined (Claude, Codex and the API-key AIs can) answers `403`. A key goes when the teammate who made it leaves. Each call is kept with the bot's API settings and shown on the card (count, last call, recent calls) to those who can manage the key. Refused calls roll up into one row per burst. Neither ever holds the key.