# API Reference — Bots

> Complete API reference for Aerostack bot endpoints — CRUD, activation, testing, conversations, analytics, templates, and webhooks.

All bot management endpoints require JWT authentication via the `Authorization: Bearer <token>` header. Webhook endpoints use platform-specific verification instead.

**Base URL:** `https://api.aerostack.dev`

---

## Bot CRUD

### List Bots

```
GET /api/bots
```

Returns all bots owned by the authenticated user, with conversation counts.

**Auth:** JWT required

```bash
curl https://api.aerostack.dev/api/bots \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

**Response:**

```json
{
  "bots": [
    {
      "id": "bt_a1b2c3d4e5f6g7h8i9j0",
      "name": "Support Bot",
      "slug": "support-bot",
      "platform": "telegram",
      "status": "active",
      "llm_provider": "anthropic",
      "llm_model": "claude-sonnet-4-6",
      "created_at": "2026-03-14T10:00:00Z",
      "updated_at": "2026-03-14T12:00:00Z",
      "last_active_at": "2026-03-14T15:30:00Z",
      "conversation_count": 42
    }
  ]
}
```

---

### Create Bot

```
POST /api/bots
```

**Auth:** JWT required

**Required fields:**

| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Bot display name |
| `platform` | string | `telegram`, `discord`, `whatsapp`, `slack`, or `custom` |
| `workspace_id` | string | MCP workspace ID (must be owned by the user) |
| `system_prompt` | string | LLM system instructions |

**Optional fields:**

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `description` | string | null | Bot description |
| `platform_config` | object | `{}` | Platform-specific credentials (stored securely) |
| `llm_provider` | string | `anthropic` | `anthropic`, `openai`, `gemini`, `groq`, `workers-ai`, `custom` |
| `llm_model` | string | `claude-sonnet-4-6` | Model identifier |
| `llm_api_key` | string | null | BYOK LLM API key (stored securely) |
| `llm_config` | object | `{}` | LLM config (e.g., `{ "temperature": 0.7 }`) |
| `billing_mode` | string | `wallet` | `wallet`, `byok`, `plan_quota` |
| `max_loop_iterations` | number | 10 | Max agent loop tool-call rounds |
| `max_tokens_per_turn` | number | 8192 | Max output tokens per LLM call |
| `timeout_ms` | number | 30000 | Processing timeout (max 60000) |
| `conversation_max_messages` | number | 20 | Context window size (messages) |
| `conversation_ttl_hours` | number | 24 | Conversation expiry |
| `enable_rag` | boolean | false | Reserved for RAG integration |
| `welcome_message` | string | null | Sent on first interaction |
| `fallback_message` | string | null | Sent on error |
| `spending_cap_cents` | number | null | Lifetime spending cap |

```bash
curl -X POST https://api.aerostack.dev/api/bots \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Bot",
    "platform": "telegram",
    "workspace_id": "ws-abc123",
    "system_prompt": "You are a helpful assistant.",
    "platform_config": { "bot_token": "123:ABC" },
    "llm_provider": "openai",
    "llm_model": "gpt-4o-mini"
  }'
```

**Response:** `201 Created`

```json
{
  "bot": {
    "id": "bt_a1b2c3d4e5f6g7h8i9j0",
    "name": "My Bot",
    "platform": "telegram",
    "status": "draft",
    "has_platform_config": true,
    "has_llm_api_key": false
  }
}
```

Sensitive fields like platform credentials and LLM API keys are never returned in API responses. Instead, boolean flags `has_platform_config` and `has_llm_api_key` indicate whether they are set.

---

### Get Bot

```
GET /api/bots/:id
```

**Auth:** JWT required (must be bot owner)

Returns the bot with template info (if created from a template).

```bash
curl https://api.aerostack.dev/api/bots/bt_abc123 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

---

### Update Bot

```
PATCH /api/bots/:id
```

**Auth:** JWT required (must be bot owner)

Update any bot field. Validates `workflow_json` structure if provided.

```bash
curl -X PATCH https://api.aerostack.dev/api/bots/bt_abc123 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "system_prompt": "Updated prompt.",
    "max_loop_iterations": 5,
    "spending_cap_cents": 1000
  }'
```

**Updatable fields:** `name`, `description`, `system_prompt`, `llm_provider`, `llm_model`, `llm_config`, `llm_api_key`, `platform_config`, `billing_mode`, `max_loop_iterations`, `max_tokens_per_turn`, `timeout_ms`, `conversation_max_messages`, `conversation_ttl_hours`, `enable_rag`, `welcome_message`, `fallback_message`, `spending_cap_cents`, `workflow_json`, `workflow_enabled`

---

### Delete Bot

```
DELETE /api/bots/:id
```

**Auth:** JWT required (must be bot owner)

Deletes the bot and all associated conversations, messages, and analytics. Unregisters the Telegram webhook (best effort).

```bash
curl -X DELETE https://api.aerostack.dev/api/bots/bt_abc123 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

**Response:**

```json
{ "deleted": true }
```

---

## Lifecycle

### Activate Bot

```
POST /api/bots/:id/activate
```

**Auth:** JWT required (must be bot owner)

Registers the webhook with the platform and sets status to `active`.

```bash
curl -X POST https://api.aerostack.dev/api/bots/bt_abc123/activate \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

**Response:**

```json
{
  "status": "active",
  "webhook_url": "https://api.aerostack.dev/api/bots/webhook/telegram/bt_abc123",
  "warnings": [],
  "manual_setup_required": false
}
```

| Field | Description |
|-------|-------------|
| `webhook_url` | The URL registered with the platform |
| `warnings` | Security warnings (e.g., missing webhook secret) |
| `manual_setup_required` | `true` for Slack and WhatsApp (webhook URL must be set manually) |

---

### Pause Bot

```
POST /api/bots/:id/pause
```

**Auth:** JWT required (must be bot owner)

Unregisters the webhook and sets status to `paused`. The bot stops receiving messages.

```bash
curl -X POST https://api.aerostack.dev/api/bots/bt_abc123/pause \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

**Response:**

```json
{ "status": "paused" }
```

---

### Test Bot

```
POST /api/bots/:id/test
```

**Auth:** JWT required (must be bot owner)

**Rate limit:** 10 requests per 60 seconds per user

Sends a test message through the full bot engine pipeline without going through a platform adapter.

```bash
curl -X POST https://api.aerostack.dev/api/bots/bt_abc123/test \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "message": "What can you help with?" }'
```

**Response:**

```json
{
  "response": "I can help you with...",
  "tool_calls": [],
  "tokens": { "input": 342, "output": 28 },
  "token_breakdown": { "systemPrompt": 120, "total": 370 },
  "cost_cents": 0,
  "latency_ms": 1230,
  "loop_iterations": 0,
  "conversation_id": "bconv_abc123"
}
```

The test endpoint creates real conversations and messages in the database. Costs are charged to your wallet in wallet billing mode.

---

## Conversations

### List Conversations

```
GET /api/bots/:id/conversations
```

**Auth:** JWT required (must be bot owner)

**Query parameters:**

| Param | Default | Max | Description |
|-------|---------|-----|-------------|
| `limit` | 50 | 100 | Number of conversations to return |
| `offset` | 0 | - | Pagination offset |

```bash
curl "https://api.aerostack.dev/api/bots/bt_abc123/conversations?limit=20&offset=0" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

---

### Get Conversation with Messages

```
GET /api/bots/:id/conversations/:convId
```

**Auth:** JWT required (must be bot owner)

**Query parameters:**

| Param | Default | Max | Description |
|-------|---------|-----|-------------|
| `limit` | 100 | 500 | Number of messages to return |

```bash
curl "https://api.aerostack.dev/api/bots/bt_abc123/conversations/bconv_xyz/messages?limit=200" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

**Response:**

```json
{
  "conversation": {
    "id": "bconv_xyz",
    "platform_user_id": "user_123",
    "message_count": 15,
    "total_cost_cents": 3,
    "started_at": "2026-03-14T10:00:00Z",
    "last_message_at": "2026-03-14T10:05:00Z"
  },
  "messages": [
    { "id": "bmsg_1", "role": "user", "content": "Hello", "created_at": "..." },
    { "id": "bmsg_2", "role": "assistant", "content": "Hi there!", "created_at": "..." }
  ]
}
```

---

## Analytics

### Get Analytics

```
GET /api/bots/:id/analytics
```

**Auth:** JWT required (must be bot owner)

**Query parameters:**

| Param | Default | Description |
|-------|---------|-------------|
| `from` | 30 days ago | Start date (YYYY-MM-DD) |
| `to` | today | End date (YYYY-MM-DD) |

Returns daily analytics, summary totals, top tools, average latency, and conversations by status.

```bash
curl "https://api.aerostack.dev/api/bots/bt_abc123/analytics?from=2026-03-01&to=2026-03-15" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

---

### Get Insights

```
GET /api/bots/:id/insights
```

**Auth:** JWT required (must be bot owner)

Returns unanswered questions (messages where the bot did not use tools) and resolution rate.

```bash
curl https://api.aerostack.dev/api/bots/bt_abc123/insights \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

**Response:**

```json
{
  "unanswered_questions": [
    { "question": "Can I get a refund?", "bot_response": "...", "created_at": "..." }
  ],
  "resolution_rate": 78,
  "total_answered": 312,
  "total_responses": 400
}
```

---

## Setup Wizard

### Create Bot from Template

```
POST /api/bots/setup
```

**Auth:** JWT required

Creates a workspace, connects MCP servers, and creates a bot in one call.

| Field | Required | Description |
|-------|----------|-------------|
| `template_id` | Yes | Template ID (e.g., `tpl_support`) |
| `bot_name` | No | Bot name (defaults to template name) |
| `platform` | No | Platform (defaults to `custom`) |
| `platform_config` | No | Platform credentials |
| `config_values` | No | Key-value pairs injected into the system prompt |
| `llm_api_key` | No | BYOK LLM API key |

```bash
curl -X POST https://api.aerostack.dev/api/bots/setup \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl_support",
    "bot_name": "Acme Support",
    "platform": "telegram",
    "platform_config": { "bot_token": "123:ABC" },
    "config_values": { "company_name": "Acme Corp" }
  }'
```

---

## Templates

### List Templates

```
GET /api/bots/templates
```

**Auth:** None required

| Param | Default | Max | Description |
|-------|---------|-----|-------------|
| `type` | - | - | Filter by category |
| `limit` | 50 | 100 | Number of templates |

### Get Template

```
GET /api/bots/templates/:templateId
```

**Auth:** None required

### Create Template

```
POST /api/bots/templates
```

**Auth:** JWT required

**Required:** `name`, `description`, `category`, `system_prompt`

### Update Template

```
PATCH /api/bots/templates/:templateId
```

**Auth:** JWT required (must be template owner; system templates return 403)

### Delete Template

```
DELETE /api/bots/templates/:templateId
```

**Auth:** JWT required (must be template owner; system templates return 403)

---

## Webhook Endpoints

These endpoints receive messages from messaging platforms. They use platform-specific verification, not JWT auth.

| Method | Path | Platform | Verification |
|--------|------|----------|-------------|
| POST | `/api/bots/webhook/telegram/:botId` | Telegram | `X-Telegram-Bot-Api-Secret-Token` header |
| POST | `/api/bots/webhook/discord/:botId` | Discord | Ed25519 signature |
| POST | `/api/bots/webhook/whatsapp/:botId` | WhatsApp | HMAC-SHA256 `X-Hub-Signature-256` |
| GET | `/api/bots/webhook/whatsapp/:botId` | WhatsApp | Verify token challenge |
| POST | `/api/bots/webhook/slack/:botId` | Slack | HMAC-SHA256 `X-Slack-Signature` |
| POST | `/api/bots/webhook/custom/:botId` | Custom | None |

### Custom Webhook Request

```bash
curl -X POST https://api.aerostack.dev/api/bots/webhook/custom/bt_abc123 \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hello",
    "user_id": "user_1",
    "channel_id": "channel_1",
    "user_name": "Jane"
  }'
```

**Response:**

```json
{
  "response": "Hi Jane! How can I help?",
  "tool_calls": [],
  "tokens": { "input": 200, "output": 15 },
  "cost_cents": 0,
  "latency_ms": 890
}
```

---

## Error Responses

All error responses follow this format:

```json
{ "error": "Error description" }
```

| Status | Meaning |
|--------|---------|
| 400 | Invalid request (missing fields, invalid JSON, etc.) |
| 404 | Bot or resource not found, or not owned by caller |
| 403 | Cannot modify system template |
| 429 | Rate limited |
