# INLOBBY bots — API v1

Bots are INLOBBY applications with their own identities and private keys. They are not Discord bots and do not require a Discord account. The developer portal registers the bot and grants API access. **Run the bot program on your own computer or hosting service**; INLOBBY does not execute uploaded programs.

## Create and install a bot

1. Sign in to INLOBBY with a persistent account, then open `/developers/`.
2. Choose **New application** and enter a name and description.
3. Save the private key shown after creation. It is shown once and is never returned by application-detail requests. If it is lost or exposed, generate a replacement in the portal; the previous key stops working immediately.
4. Copy the application's server-invitation link. The link contains the application ID, never its key.
5. A server owner opens the link, chooses an owned server and approves the requested permissions. An application developer cannot add a bot to another person's server without that owner's approval.
6. The server owner can later remove the bot in **Server Settings → Integrations**. Removal immediately blocks that bot's access to the server.

Guest sessions cannot create or authorize bots. A persistent account created with a personal access code is supported. Bots cannot own servers, access personal conversations, manage roles, join voice, or use human account APIs.

## Guided local setup

The application page includes **Your first bot reply**. After the owner approves the invitation, select **Refresh access**, choose an installed server and text channel, then download the example. Choose PowerShell or Bash and copy the generated command into a terminal in the example folder. The command uses the current portal address, so a localhost preview stays local.

The command contains no private key. The terminal prompts for the key without displaying it; PowerShell clears the environment credential afterward and Bash runs inside a separate subshell. Keep the terminal running and send `!ping` in the chosen channel.

Only channels available to the installed bot are listed. The example needs read and send access; missing permissions or an active mute hide the runnable command and show guidance. **Refresh access** rechecks the owner's current grants. This checklist shows setup progress, not a claim that your external process is online.

Server owners can use **Edit permissions** or **Refresh bots** in Server Settings → Integrations. Permission changes still require the owner's approval.

The signed-in developer endpoint `GET /api/developer/apps/{applicationId}/setup` returns installed-server and text-channel metadata with `canRead` and `canSend`. It is limited to the application creator, never returns credentials or messages, and follows bot bans, disabled accounts, membership removal and owner-granted scopes.

## Authentication

Use HTTPS in production. Send the key only in a request header:

```http
Authorization: Bot YOUR_PRIVATE_BOT_KEY
```

Keep the key in an environment variable or secret store. Do not put it in URLs, browser JavaScript, screenshots, source control or logs. Cookie authentication does not replace bot-key authentication. Requests are limited; respect HTTP `429` and the `Retry-After` header.

## Permissions

| Permission | Allows |
| --- | --- |
| `read_messages` | Reading installed-server text channels and their public message history. |
| `send_messages` | Sending text messages to installed-server text channels. |

The server owner's grant is authoritative. Being the developer does not grant access to server content. Server bans, membership removal and active mutes remain effective. Bot keys are not human sign-in credentials.

## Endpoints

All paths below are relative to `/api/bot/v1`. All require `Authorization: Bot …`.

| Method | Path | Result |
| --- | --- | --- |
| GET | `/me` | `{ application, bot: { id, username, isBot } }` |
| GET | `/servers` | `{ servers: [{ id, name, permissions }] }` |
| GET | `/servers/{serverId}/channels` | `{ channels: [{ id, name, type }] }` |
| GET | `/servers/{serverId}/channels/{channelId}/messages` | `{ messages, nextAfter }`, latest 50 messages on the first request. |
| GET | `/servers/{serverId}/channels/{channelId}/messages?after={messageId}` | Up to 50 later messages, in order. Use `nextAfter` for the next request. |
| POST | `/servers/{serverId}/channels/{channelId}/messages` | `{ message, duplicate }` |

IDs must be URI encoded. A channel is always scoped by its server; identical channel IDs in different servers do not share authorization. Bot messages include `senderIsBot: true`. Do not reply to bot messages in a polling loop.

### Send a message

```json
{
  "content": "Hello from my INLOBBY bot!",
  "requestId": "welcome-unique-event-123"
}
```

`content` must contain 1–4000 characters. `requestId` must contain 1–128 ASCII letters, digits, underscores or hyphens. Keep the same request ID and content when retrying a failed request. A successful retry returns the original message and `duplicate: true`. Reusing a request ID for different content is rejected. Never send a claimed sender ID, server ID or privilege in the body.

History is intended for short polling. A deleted cursor returns `400` with `INVALID_CURSOR`; fetch a fresh latest page and decide how your application should resume. The sample bot explicitly reports that recovery and avoids replaying old commands.

## Run the sample ping bot

Node.js 18 or later is required; no npm packages are needed. Download `ping-bot.mjs` from the portal, or use `examples/bots/ping-bot.mjs` in this project.

In PowerShell, read the key without printing it or including it in the shell command history:

```powershell
$privateBotKey = Read-Host 'Bot key' -AsSecureString
$env:INLOBBY_BOT_TOKEN = [System.Net.NetworkCredential]::new('', $privateBotKey).Password
$env:INLOBBY_API_BASE = 'https://inlobby.live'
$env:INLOBBY_SERVER_ID = 'YOUR_SERVER_ID'
$env:INLOBBY_CHANNEL_ID = 'YOUR_TEXT_CHANNEL_ID'
node ./ping-bot.mjs
Remove-Item Env:INLOBBY_BOT_TOKEN
```

For local development, set `INLOBBY_API_BASE` to the loopback origin printed by your local INLOBBY server. The sample accepts plain HTTP only for loopback addresses. Get server/channel IDs with the API endpoints above, then use the selected IDs in the environment variables.

After the program says it is waiting, send `!ping` in the selected channel. It replies `Pong! 🏓`. It skips pre-existing commands, ignores bot-authored messages, uses stable request IDs for safe retries, honors rate limits and exits on revoked authorization. Stop it with Ctrl+C. A registration alone does not run the bot: keep this process or your hosted program running to receive replies.

## Common responses

- `400`: invalid fields, permissions or history cursor.
- `401`: missing, invalid, rotated or revoked key.
- `403`: missing server/channel grant, ban, mute or removed membership.
- `404`: unavailable application or server.
- `409`: a message request ID was reused with different content.
- `429`: rate limited; wait for `Retry-After`.

Developer application management uses the existing signed-in browser session and CSRF protection under `/api/developer`. Bot API credentials are deliberately separate from that session.
