# API

> Talk to your AI Agent programmatically with the Quickchat AI Chat endpoint — ideal for building a custom chat UI.

:::note[This is the API channel]
This page covers using the **API as a channel** — connecting your AI Agent to your own app or backend through the conversational **Chat** endpoint. Looking for the full API? Head to the **[REST API reference](/api-reference/)** to manage your Knowledge Base, conversations, AI Actions, widget configuration, and more.
:::

## Chat

The realtime Chat endpoint sends a visitor message to your AI Agent and returns the AI reply in a single round-trip. This is the endpoint you want when building a custom chat UI on top of Quickchat AI.

It differs from the other endpoints in two ways: it sits at `app.quickchat.ai/chat`, outside the `/v1/api/` and `/v1/api_core/` base paths, and it reads `scenario_id` from the request body rather than from the token. It uses the same Bearer token authentication as the rest of this API.

:::note
Send every request to `https://app.quickchat.ai/chat`. The `scenario_id` in the body must match the AI Agent your Bearer token is bound to.
:::

### Send Message

`POST https://app.quickchat.ai/chat`

**Request Body**

| Parameter | Description |
|-----------|-------------|
| `scenario_id` <br/> string, required | ID of your AI Agent. Must match the `scenario_id` bound to the Bearer token |
| `text` <br/> string, required | User input message |
| `conv_id` <br/> string | Conversation ID. Omit on the first request to start a new conversation, then pass the returned `conv_id` back on subsequent requests to continue it |
| `client_metadata` <br/> object | Custom key-value pairs (max 5 keys) attached to every message. Displayed as data columns in the conversation export in the Inbox |

A request without `conv_id` starts a new conversation, and the generated `conv_id` is returned in the response. Store that `conv_id` and send it back on later requests to maintain conversation context across multiple user interactions.

**Shell**

```shell
# Start a new conversation by omitting conv_id
curl -X POST https://app.quickchat.ai/chat \
  -H 'Authorization: Bearer <API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
  "scenario_id": "<SCENARIO_ID>",
  "text": "Hello!"
}'
```

**Python**

```python
import requests

response = requests.post(
    url="https://app.quickchat.ai/chat",
    headers={"Authorization": "Bearer <API_TOKEN>"},
    json={
        "scenario_id": "<SCENARIO_ID>",
        "text": "Hello!",
    },
)
data = response.json()
```

**Response** `200 OK`

```json
{
  "conv_id": "conv-uuid-1234",
  "reply": "Hi there! How can I help you today?",
  "ord_number": 3,
  "src": 0
}
```

| Field | Description |
|-------|-------------|
| `conv_id` <br/> string | Conversation identifier. Always returned. Pass it back in the `conv_id` body field to continue the conversation |
| `reply` <br/> string | The AI Agent's response. May contain HTML such as `<br>` line breaks |
| `ord_number` <br/> integer | Sequential message number within the conversation |
| `src` <br/> integer | Internal source indicator. API clients can ignore this field |

To continue an existing conversation, pass back the `conv_id` you received:

**Shell**

```shell
curl -X POST https://app.quickchat.ai/chat \
  -H 'Authorization: Bearer <API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
  "scenario_id": "<SCENARIO_ID>",
  "conv_id": "conv-uuid-1234",
  "text": "What is your return policy?"
}'
```

**Python**

```python
import requests

response = requests.post(
    url="https://app.quickchat.ai/chat",
    headers={"Authorization": "Bearer <API_TOKEN>"},
    json={
        "scenario_id": "<SCENARIO_ID>",
        "conv_id": "conv-uuid-1234",
        "text": "What is your return policy?",
    },
)
data = response.json()
```

### Client Metadata

The Chat endpoint accepts an optional `client_metadata` parameter: custom attributes that are assigned to every new message and displayed as data columns in the conversation export in the Inbox. You can attach the same attributes through the widget. A maximum of 5 keys can be sent at a time, for example `{"userId": 12, "website": "mywebsite.com"}`.

**Shell**

```shell
curl -X POST https://app.quickchat.ai/chat \
  -H 'Authorization: Bearer <API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
  "scenario_id": "<SCENARIO_ID>",
  "conv_id": "conv-uuid-1234",
  "text": "Hello!",
  "client_metadata": {"userId": 12, "website": "mywebsite.com"}
}'
```

**Python**

```python
import requests

response = requests.post(
    url="https://app.quickchat.ai/chat",
    headers={"Authorization": "Bearer <API_TOKEN>"},
    json={
        "scenario_id": "<SCENARIO_ID>",
        "conv_id": "conv-uuid-1234",
        "text": "Hello!",
        "client_metadata": {"userId": 12, "website": "mywebsite.com"},
    },
)
data = response.json()
```

#### Knowledge Base Tag Filtering

You can add [tags](#tags) to Knowledge Base articles and use them to restrict which articles the AI draws on, so it answers based only on a subset of the Knowledge Base. This filtering is currently supported only via the API.

To filter by tag, add a `kb_topic` key to `client_metadata`. The `kb_topic` key must be present on every request in the conversation, including the request that starts it. Its value can change between requests, but the key itself has to be present throughout the conversation for the filter to apply.

In the example below, any article tagged `your-topic`, or with no tag at all, is included in the candidate pool of knowledge for the response.

```python
json={
    "scenario_id": "<SCENARIO_ID>",
    "conv_id": "conv-uuid-1234",
    "text": "Hello!",
    "client_metadata": {"kb_topic": "your-topic"},
}
```

### Errors

The Chat endpoint returns a plain-text error message with an appropriate HTTP status code.

| Status | Description | Action |
|--------|-------------|--------|
| `400` | Missing `scenario_id`, or the request is not authenticated | Include `scenario_id` in the body and a valid `Authorization: Bearer <API_TOKEN>` header |
| `400` | Invalid `conv_id` (`Conversation conv_id <id> is not valid.`) | Omit `conv_id` to start a new conversation, or pass a `conv_id` returned by a previous response |
| `404` | Unknown `scenario_id` (`No implementation found for scenario_id <id>`) | Verify the `scenario_id` and that your Bearer token is bound to it |
| `500` | Internal server error | An issue on our side. Please [get in touch](https://quickchat.ai/contact) with support |
| `503` | Service unavailable | Servers are temporarily overloaded or under maintenance. If the problem persists, please [get in touch](https://quickchat.ai/contact) with support |
