# Start a chat

> POST /v1/chats

Start a chat with one of your agents by sending its first message. Answers `201` with the first `chat.turn`: the agent's greeting in `opening`, and its reply. Send `stream: true` for the reply as server-sent events. Needs `chats:write`. An `Idempotency-Key` is optional: the same request again returns the same chat.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `Idempotency-Key` | header | string | No | Your own id for this chat. Optional. |

## Body

Sent as JSON. A field this operation does not take is refused, so a typo fails loudly.

| Field | Type | Required | Description |
|---|---|---|---|
| `agent_id` | string (uuid) | Yes | The agent to chat with. |
| `agent_version` | integer or null | No | Answer with this published version of the agent rather than what is live now — its number from `GET /v1/agents/{id}/versions`. Its values and languages are that version's, and every turn of the conversation keeps it. |
| `attachment_ids` | array of string (uuid) | No | Pictures to send with it, from `POST /v1/attachments`. |
| `external_id` | string or null | No |  |
| `language` | string or null | No | One of the agent's language versions, like `ar`. |
| `message` | string | Yes | What the person wrote. |
| `metadata` | object | No | Your own data, returned on every read and event. The agent never sees it. |
| `stream` | boolean | No | Send the reply as it is written, as server-sent events. `Accept: text/event-stream` does the same. |
| `variables` | object | No | Values for the agent's `{{placeholders}}`. See its `variables_schema`. |

## Answer

`201` with [ChatTurn](/reference/objects/ChatTurn).

With `stream: true`, the same answer arrives as server-sent events instead — see [Chat and streaming](/guides/chat).

## Errors

Every error is a [problem document](/errors) with a stable `code`.

| Status | When |
|---|---|
| `401` | The key is missing, mistyped, unknown, revoked or expired. |
| `402` | The organization's credit is used up. |
| `403` | The key lacks a permission, a live key was sent from a browser, or the organization is frozen and the request would change something. |
| `404` | This key reaches no such agent. |
| `409` | The agent is not published, its project is frozen, or the first message is still being answered. |
| `422` | A field, a variable or the language does not fit. |
| `429` | Too many requests for this key or its organization; see `Retry-After`. |
| `500` | Something went wrong on our side. Quote the `request_id` to support. |

## Examples

**curl**

```sh
#!/bin/sh
# Start a chat
curl -sS --fail-with-body -X POST "https://api.aigently.ai/v1/chats" \
  -H "Authorization: Bearer $AIGENTLY_API_KEY" \
  -H "Idempotency-Key: chat-20931" \
  --json '{
  "agent_id": "3c7d9e1f-5a2b-4c6d-8e0f-1a3b5c7d9e2f",
  "message": "Hello, I would like to book a table.",
  "variables": {
    "first_name": "Sara"
  }
}'
```

**JavaScript**

```js
// Start a chat
const response = await fetch("https://api.aigently.ai/v1/chats", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.AIGENTLY_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "chat-20931",
  },
  body: JSON.stringify({
    "agent_id": "3c7d9e1f-5a2b-4c6d-8e0f-1a3b5c7d9e2f",
    "message": "Hello, I would like to book a table.",
    "variables": {
      "first_name": "Sara"
    }
  }),
});
const answer = await response.json();
if (!response.ok) throw new Error(`${answer.code}: ${answer.detail}`);
console.log(answer);
```

**Python**

```python
# Start a chat
# pip install httpx
import os

import httpx

response = httpx.post(
    "https://api.aigently.ai/v1/chats",
    headers={
        "Authorization": f"Bearer {os.environ['AIGENTLY_API_KEY']}",
        "Idempotency-Key": "chat-20931",
    },
    json={
        "agent_id": "3c7d9e1f-5a2b-4c6d-8e0f-1a3b5c7d9e2f",
        "message": "Hello, I would like to book a table.",
        "variables": {
            "first_name": "Sara",
        },
    },
    timeout=60,
)
if response.is_error:
    raise SystemExit(response.text)
print(response.json())
```

**Go**

```go
// Start a chat
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	payload := []byte(`{
  "agent_id": "3c7d9e1f-5a2b-4c6d-8e0f-1a3b5c7d9e2f",
  "message": "Hello, I would like to book a table.",
  "variables": {
    "first_name": "Sara"
  }
}`)
	request, err := http.NewRequest("POST", "https://api.aigently.ai/v1/chats", bytes.NewReader(payload))
	if err != nil {
		panic(err)
	}
	request.Header.Set("Authorization", "Bearer "+os.Getenv("AIGENTLY_API_KEY"))
	request.Header.Set("Content-Type", "application/json")
	request.Header.Set("Idempotency-Key", "chat-20931")
	response, err := http.DefaultClient.Do(request)
	if err != nil {
		panic(err)
	}
	defer response.Body.Close()
	body, _ := io.ReadAll(response.Body)
	if response.StatusCode >= 400 {
		fmt.Fprintln(os.Stderr, string(body))
		os.Exit(1)
	}
	fmt.Println(string(body))
}
```

**Java**

```java
// Start a chat
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Main {
    public static void main(String[] args) throws Exception {
        String body = """
            {
              "agent_id": "3c7d9e1f-5a2b-4c6d-8e0f-1a3b5c7d9e2f",
              "message": "Hello, I would like to book a table.",
              "variables": {
                "first_name": "Sara"
              }
            }
            """;
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.aigently.ai/v1/chats"))
            .header("Authorization", "Bearer " + System.getenv("AIGENTLY_API_KEY"))
            .header("Content-Type", "application/json")
            .header("Idempotency-Key", "chat-20931")
            .method("POST", HttpRequest.BodyPublishers.ofString(body))
            .build();
        // HTTP/1.1: on a plain-http address Java's default asks to upgrade, which not every
        // server allows.
        HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();
        HttpResponse<String> response =
            client.send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() >= 400) {
            System.err.println(response.body());
            System.exit(1);
        }
        System.out.println(response.body());
    }
}
```

**C#**

```csharp
// Start a chat
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("AIGENTLY_API_KEY"));
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.aigently.ai/v1/chats")
{
    Content = new StringContent(
        """
        {
          "agent_id": "3c7d9e1f-5a2b-4c6d-8e0f-1a3b5c7d9e2f",
          "message": "Hello, I would like to book a table.",
          "variables": {
            "first_name": "Sara"
          }
        }
        """,
        Encoding.UTF8,
        "application/json"),
};
request.Headers.Add("Idempotency-Key", "chat-20931");
var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
    Console.Error.WriteLine(body);
    return 1;
}
Console.WriteLine(body);
return 0;
```

**PHP**

```php
<?php
// Start a chat
$curl = curl_init("https://api.aigently.ai/v1/chats");
curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("AIGENTLY_API_KEY"),
        "Content-Type: application/json",
        "Idempotency-Key: chat-20931",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "agent_id" => "3c7d9e1f-5a2b-4c6d-8e0f-1a3b5c7d9e2f",
        "message" => "Hello, I would like to book a table.",
        "variables" => [
            "first_name" => "Sara",
        ],
    ]),
]);
$body = curl_exec($curl);
if (curl_getinfo($curl, CURLINFO_RESPONSE_CODE) >= 400) {
    fwrite(STDERR, $body . "\n");
    exit(1);
}
echo $body, "\n";
```
