# Create a bot

Source: https://langbot.ai/docs/api/bots/create-bot

`POST /v1/bots`

Register a bot you run yourself so Langbot can watch it. Langbot never receives its exchange keys and never trades for it.

**Auth.** An account token (`Authorization: Bearer lb_…`) or a signed-in web session. A report-only token (`lbr_…`) is refused here with `403 scope_denied`.

**Limits.** Counts against your plan's API requests (60, 600 or 3,000 a minute on Free, Builder and Standard). Each bot counts toward your plan's bots (1, 5 or 50; custom on Desk).

## Parameters

### Body

| Name | Type | Required | Description |
|---|---|---|---|
| `name` | string | yes | A name you will recognise, unique on your account. |
| `venues` | array of string | yes | Where the bot trades: `kalshi`, `polymarket`, `polymarket_us`. Up to 3 items. |
| `description` | string | no | Anything to remember it by. |
| `test_run_id` | string | no | A Sim run of yours (`POST /v1/sim/runs`) to compare live results against. |

## Request

**curl**

```bash
curl -X POST "https://api.langbot.ai/v1/bots" \
  -H "Authorization: Bearer $LANGBOT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "mention-sniper", "venues": ["kalshi", "polymarket"], "description": "Kalshi mention markets"}'
```

**Python**

```python
from langbot import LangbotClient

async with LangbotClient() as lb:  # reads LANGBOT_API_TOKEN
    bot = await lb.bots.create("mention-sniper", ["kalshi", "polymarket"])
    print(bot["id"])
```

**TypeScript**

```ts
import { LangbotClient } from "@langbotai/sdk";

const lb = new LangbotClient(); // reads LANGBOT_API_TOKEN
const bot = await lb.bots.create({ name: "mention-sniper", venues: ["kalshi", "polymarket"] });
console.log(bot.id);
```

## Response

`201 Created`

```json
{
  "id": "bot_01M6G72RFQRQ8JGNG8T1447GGP",
  "name": "mention-sniper",
  "description": "Kalshi mention markets",
  "venues": [
    "kalshi",
    "polymarket"
  ],
  "test_run_id": null,
  "status": "new",
  "status_reason": "no events yet",
  "created_at": 1793693147639,
  "updated_at": 1793693147639,
  "last_event_at": null,
  "last_heartbeat_at": null,
  "halted_at": null,
  "halt_reason": null,
  "retention_days": 90,
  "wallets": []
}
```

`status` is `new` until the first event, then `ok`, `stale` (no heartbeat inside the heartbeat window) or `halted`.

## Errors

| Status | `code` | When |
|---|---|---|
| 402 | `quota_exceeded` | Your plan's bots are all in use; delete one or move up a plan. `quota.dimension` is `bots`. |
| 404 | `not_found` | `test_run_id` is not a Sim run on your account. |
| 409 | `conflict` | A bot with that name already exists. |
| 401 | `auth_required` | No token was sent. |
| 401 | `token_invalid` | The token was not recognised (mistyped, revoked or expired). |
| 422 | `validation_error` | A parameter failed validation; `detail[].loc` names it. |
| 429 | `rate_limited` | Over your request budget; wait `Retry-After` seconds. |

Every error body is `{"detail": …, "code": "…"}`; branch on `code`. All codes: [Errors](https://langbot.ai/docs/api#errors).
