> ## Documentation Index
> Fetch the complete documentation index at: https://pro-bot.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /api/bots

> Upsert the authenticated user's bot. Requires a session cookie.

Creates or updates the current user's bot. The platform supports **one bot per user** today - the route is an upsert keyed on the session's `userId`.

## Request

```http theme={null}
POST /api/bots
Content-Type: application/json
Cookie: next-auth.session-token=<jwt>
```

### Body

```json theme={null}
{
  "name": "Career Bot",
  "headline": "Senior platform engineer · open to staff roles",
  "personality": "professional",
  "contextText": "I am a software engineer based in...",
  "suggestedQuestions": [
    "What stack do you work in?",
    "Are you open to remote?"
  ],
  "llmProvider": "anthropic",
  "llmModel": "claude-sonnet-4-5"
}
```

| Field                | Type                                                   | Constraint                                                 |
| -------------------- | ------------------------------------------------------ | ---------------------------------------------------------- |
| `name`               | string                                                 | 1–100 chars, trimmed                                       |
| `headline`           | string (optional)                                      | ≤ 120 chars                                                |
| `personality`        | `"professional"` \| `"creative"` \| `"enthusiastic"`   |                                                            |
| `contextText`        | string                                                 | 1–50,000 chars, trimmed                                    |
| `suggestedQuestions` | string\[]                                              | ≤ 6 entries, each ≤ 200 chars                              |
| `llmProvider`        | `"anthropic"` \| `"openai"` \| `"google"` \| `"azure"` |                                                            |
| `llmModel`           | string (optional)                                      | ≤ 60 chars; provider-specific model id or Azure deployment |

<Note>
  The LLM API key is **not** part of this body and **must not** be sent here.
  It's envelope-encrypted at rest via a separate endpoint and never rides in a
  chat body. See [BYO-key flow](/docs/concepts/byo-key).
</Note>

## Behaviour

The route runs in a single Drizzle transaction:

1. Update the user's `llm_provider` and `llm_model` columns.
2. Look up an existing bot for the user.
3. If present, `UPDATE` it; return `200 OK`.
4. Otherwise `INSERT`; return `201 Created`.

## Responses

### 201 Created (first save)

```json theme={null}
{
  "bot": {
    "id": "00000000-0000-0000-0000-000000000000",
    "userId": "11111111-1111-1111-1111-111111111111",
    "name": "Career Bot",
    "headline": "Senior platform engineer · open to staff roles",
    "personality": "professional",
    "contextText": "I am a software engineer based in...",
    "suggestedQuestions": [
      "What stack do you work in?",
      "Are you open to remote?"
    ],
    "loadingMessages": [
      "Thinking…",
      "Searching memory…",
      "Drafting a response…",
      "Almost ready…"
    ],
    "isActive": true,
    "createdAt": "2026-01-01T00:00:00.000Z",
    "updatedAt": "2026-01-01T00:00:00.000Z"
  }
}
```

Dates serialize as ISO-8601 `YYYY-MM-DDThh:mm:ss.sssZ`.

### 200 OK (subsequent saves)

Same shape, `updatedAt` advances.

### 400 Bad Request - invalid JSON

```json theme={null}
{ "error": "Invalid JSON body" }
```

### 400 Bad Request - validation failure

```json theme={null}
{
  "error": "Validation failed",
  "details": {
    "fieldErrors": {
      "personality": ["Invalid enum value..."]
    },
    "formErrors": []
  }
}
```

### 401 Unauthorized

```json theme={null}
{ "error": "Unauthorized" }
```

When no session cookie is attached or the session is invalid.

## cURL

```bash theme={null}
curl -X POST https://probot.vercel.app/api/bots \
  -H 'Content-Type: application/json' \
  -b 'next-auth.session-token=<JWT>' \
  -d '{
    "name": "Career Bot",
    "personality": "professional",
    "contextText": "I am a software engineer based in...",
    "suggestedQuestions": ["What stack do you work in?"],
    "llmProvider": "anthropic",
    "llmModel": "claude-sonnet-4-5"
  }'
```

## Notes

* `loadingMessages` is set server-side at `INSERT` time from a default JSON literal. It is **not** part of the request body.
* `isActive` defaults to `true`; bot enable/disable is managed from the dashboard.
* Multi-bot support is planned (see the [Roadmap](/docs/release-notes/roadmap)).
