diff --git a/docs.json b/docs.json
index 10703d7580..a58aac9388 100644
--- a/docs.json
+++ b/docs.json
@@ -165,6 +165,7 @@
"group": "AI-powered search",
"pages": [
"learn/ai_powered_search/getting_started_with_ai_search",
+ "learn/ai_powered_search/conversational_search_with_chat",
"learn/ai_powered_search/configure_rest_embedder",
"learn/ai_powered_search/document_template_best_practices",
"learn/ai_powered_search/image_search_with_user_provided_embeddings",
@@ -329,6 +330,7 @@
"reference/api/network",
"reference/api/similar",
"reference/api/facet_search",
+ "reference/api/chats",
"reference/api/tasks",
"reference/api/batches",
"reference/api/keys",
@@ -377,6 +379,7 @@
{
"group": "Artificial intelligence",
"pages": [
+ "guides/ai/getting_started_with_chat",
"guides/ai/mcp",
"guides/embedders/openai",
"guides/langchain",
diff --git a/guides/ai/getting_started_with_chat.mdx b/guides/ai/getting_started_with_chat.mdx
new file mode 100644
index 0000000000..04dc1d3e75
--- /dev/null
+++ b/guides/ai/getting_started_with_chat.mdx
@@ -0,0 +1,276 @@
+---
+title: Getting started with conversational search
+sidebarTitle: Getting started with chat
+description: Learn how to implement AI-powered conversational search in your application
+---
+
+import { Warning, Note } from '/snippets/notice_tag.mdx'
+
+This guide walks you through implementing Meilisearch's chat completions feature to create conversational search experiences in your application.
+
+
+The chat completions feature is experimental and must be enabled before use. See [experimental features](/reference/api/experimental_features) for activation instructions.
+
+
+## Prerequisites
+
+Before starting, ensure you have:
+- Meilisearch instance running (v1.15.1 or later)
+- An API key from an LLM provider (OpenAI, Azure OpenAI, Mistral, Gemini, or access to a vLLM server)
+- At least one index with searchable content
+- The chat completions experimental feature enabled
+
+## Quick start
+
+### Enable the chat completions feature
+
+First, enable the chat completions experimental feature:
+
+```bash
+curl \
+ -X PATCH 'http://localhost:7700/experimental-features' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "chatCompletions": true
+ }'
+```
+
+### Configure a chat completions workspace
+
+Create a workspace with your LLM provider settings. Here are examples for different providers:
+
+
+
+```bash openAi
+curl \
+ -X PATCH 'http://localhost:7700/chats/my-assistant/settings' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "source": "openAi",
+ "apiKey": "sk-abc...",
+ "prompts": {
+ "system": "You are a helpful assistant. Answer questions based only on the provided context."
+ }
+ }'
+```
+
+```bash azureOpenAi
+curl \
+ -X PATCH 'http://localhost:7700/chats/my-assistant/settings' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "source": "azureOpenAi",
+ "apiKey": "your-azure-key",
+ "baseUrl": "https://your-resource.openai.azure.com",
+ "prompts": {
+ "system": "You are a helpful assistant. Answer questions based only on the provided context."
+ }
+ }'
+```
+
+```bash mistral
+curl \
+ -X PATCH 'http://localhost:7700/chats/my-assistant/settings' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "source": "mistral",
+ "apiKey": "your-mistral-key",
+ "prompts": {
+ "system": "You are a helpful assistant. Answer questions based only on the provided context."
+ }
+ }'
+```
+
+```bash gemini
+curl \
+ -X PATCH 'http://localhost:7700/chats/my-assistant/settings' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "source": "gemini",
+ "apiKey": "your-gemini-key",
+ "prompts": {
+ "system": "You are a helpful assistant. Answer questions based only on the provided context."
+ }
+ }'
+```
+
+```bash vLlm
+curl \
+ -X PATCH 'http://localhost:7700/chats/my-assistant/settings' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "source": "vLlm",
+ "baseUrl": "http://localhost:8000",
+ "prompts": {
+ "system": "You are a helpful assistant. Answer questions based only on the provided context."
+ }
+ }'
+```
+
+
+
+### Send your first chat completions request
+
+Now you can start a conversation:
+
+```bash
+curl \
+ -X POST 'http://localhost:7700/chats/my-assistant/chat/completions' \
+ -H 'Authorization: Bearer DEFAULT_CHAT_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "model": "gpt-3.5-turbo",
+ "messages": [
+ {
+ "role": "user",
+ "content": "What is Meilisearch?"
+ }
+ ],
+ "stream": true
+ }'
+```
+
+## Understanding workspaces
+
+Workspaces allow you to create isolated chat configurations for different use cases:
+
+- **Customer support**: Configure with support-focused prompts
+- **Product search**: Optimize for e-commerce queries
+- **Documentation**: Tune for technical Q&A
+
+Each workspace maintains its own:
+- LLM provider configuration
+- System prompt
+
+## Building a chat interface with OpenAI SDK
+
+Since Meilisearch's chat endpoint is OpenAI-compatible, you can use the official OpenAI SDK:
+
+
+
+```javascript JavaScript
+import OpenAI from 'openai';
+
+const client = new OpenAI({
+ baseURL: 'http://localhost:7700/chats/my-assistant',
+ apiKey: 'YOUR_MEILISEARCH_API_KEY',
+});
+
+const completion = await client.chat.completions.create({
+ model: 'gpt-3.5-turbo',
+ messages: [{ role: 'user', content: 'What is Meilisearch?' }],
+ stream: true,
+});
+
+for await (const chunk of completion) {
+ console.log(chunk.choices[0]?.delta?.content || '');
+}
+```
+
+```python Python
+from openai import OpenAI
+
+client = OpenAI(
+ base_url="http://localhost:7700/chats/my-assistant",
+ api_key="YOUR_MEILISEARCH_API_KEY"
+)
+
+stream = client.chat.completions.create(
+ model="gpt-3.5-turbo",
+ messages=[{"role": "user", "content": "What is Meilisearch?"}],
+ stream=True,
+)
+
+for chunk in stream:
+ if chunk.choices[0].delta.content is not None:
+ print(chunk.choices[0].delta.content, end="")
+```
+
+```typescript TypeScript
+import OpenAI from 'openai';
+
+const client = new OpenAI({
+ baseURL: 'http://localhost:7700/chats/my-assistant',
+ apiKey: 'YOUR_MEILISEARCH_API_KEY',
+});
+
+const stream = await client.chat.completions.create({
+ model: 'gpt-3.5-turbo',
+ messages: [{ role: 'user', content: 'What is Meilisearch?' }],
+ stream: true,
+});
+
+for await (const chunk of stream) {
+ const content = chunk.choices[0]?.delta?.content || '';
+ process.stdout.write(content);
+}
+```
+
+
+
+## Error handling
+
+When using the OpenAI SDK with Meilisearch's chat completions endpoint, errors from the streamed responses are natively handled by the official OpenAI SDK. This means you can use the SDK's built-in error handling mechanisms without additional configuration:
+
+
+
+```javascript JavaScript
+import OpenAI from 'openai';
+
+const client = new OpenAI({
+ baseURL: 'http://localhost:7700/chats/my-assistant',
+ apiKey: 'YOUR_MEILISEARCH_API_KEY',
+});
+
+try {
+ const stream = await client.chat.completions.create({
+ model: 'gpt-3.5-turbo',
+ messages: [{ role: 'user', content: 'What is Meilisearch?' }],
+ stream: true,
+ });
+
+ for await (const chunk of stream) {
+ console.log(chunk.choices[0]?.delta?.content || '');
+ }
+} catch (error) {
+ // OpenAI SDK automatically handles streaming errors
+ console.error('Chat completion error:', error);
+}
+```
+
+```python Python
+from openai import OpenAI
+
+client = OpenAI(
+ base_url="http://localhost:7700/chats/my-assistant",
+ api_key="YOUR_MEILISEARCH_API_KEY"
+)
+
+try:
+ stream = client.chat.completions.create(
+ model="gpt-3.5-turbo",
+ messages=[{"role": "user", "content": "What is Meilisearch?"}],
+ stream=True,
+ )
+
+ for chunk in stream:
+ if chunk.choices[0].delta.content is not None:
+ print(chunk.choices[0].delta.content, end="")
+except Exception as error:
+ # OpenAI SDK automatically handles streaming errors
+ print(f"Chat completion error: {error}")
+```
+
+
+
+## Next steps
+
+- Explore [advanced chat API features](/reference/api/chats)
+- Learn about [conversational search concepts](/learn/ai_powered_search/conversational_search_with_chat)
+- Review [security best practices](/learn/security/basic_security)
diff --git a/learn/ai_powered_search/conversational_search_with_chat.mdx b/learn/ai_powered_search/conversational_search_with_chat.mdx
new file mode 100644
index 0000000000..96ae9e5df2
--- /dev/null
+++ b/learn/ai_powered_search/conversational_search_with_chat.mdx
@@ -0,0 +1,107 @@
+---
+title: Conversational search with chat
+sidebarTitle: Conversational search
+description: Learn how to implement AI-powered conversational search using Meilisearch's chat feature
+---
+
+import { Warning } from '/snippets/notice_tag.mdx'
+
+Meilisearch's chat completions feature enables AI-powered conversational search, allowing users to ask questions in natural language and receive direct answers based on your indexed content. This feature transforms the traditional search experience into an interactive dialogue.
+
+
+The chat completions feature is experimental and must be enabled through [experimental features](/reference/api/experimental_features). API specifications may change in future releases.
+
+
+## What is conversational search?
+
+Conversational search allows users to:
+- Ask questions in natural language instead of using keywords
+- Receive direct answers rather than just document links
+- Maintain context across multiple questions
+- Get responses grounded in your actual content
+
+This approach bridges the gap between traditional search and modern AI experiences, making information more accessible and intuitive to find.
+
+## How chat completions differs from traditional search
+
+### Traditional search workflow
+1. User enters keywords
+2. Meilisearch returns matching documents
+3. User reviews results to find answers
+
+### Conversational search workflow
+1. User asks a question in natural language
+2. Meilisearch retrieves relevant documents
+3. AI generates a direct answer based on those documents
+4. User can ask follow-up questions
+
+## RAG implementation simplified
+
+The chat completions feature implements a complete Retrieval Augmented Generation (RAG) pipeline in a single API endpoint. Traditional RAG implementations require:
+
+- Multiple LLM calls for query optimization
+- Separate vector database for semantic search
+- Custom reranking solutions
+- Complex pipeline management
+
+Meilisearch's chat completions consolidates these into one streamlined process:
+
+1. **Query understanding**: Automatically transforms questions into optimal search parameters
+2. **Hybrid retrieval**: Combines keyword and semantic search for superior relevance
+3. **Answer generation**: Uses your chosen LLM to generate responses
+4. **Context management**: Maintains conversation history automatically
+
+## When to use chat completions vs traditional search
+
+### Use conversational search when:
+- Users need direct answers to specific questions
+- Content is informational (documentation, knowledge bases, FAQs)
+- Users benefit from follow-up questions
+- Natural language interaction improves user experience
+
+### Use traditional search when:
+- Users need to browse multiple options
+- Results require comparison (e-commerce products, listings)
+- Exact matching is critical
+- Response time is paramount
+
+## Architecture overview
+
+The chat completions feature operates through workspaces, which are isolated configurations for different use cases or tenants. Each workspace can:
+
+- Use different LLM sources (openAi, azureOpenAi, mistral, gemini, vLlm)
+- Apply custom prompts
+- Access specific indexes based on API keys
+- Maintain separate conversation contexts
+
+### Key components
+
+1. **Chat endpoint**: `/chats/{workspace}/chat/completions`
+ - OpenAI-compatible interface
+ - Supports streaming responses
+ - Handles tool calling for index searches
+
+2. **Workspace settings**: `/chats/{workspace}/settings`
+ - Configure LLM provider and model
+ - Set system prompts
+ - Manage API credentials
+
+3. **Index integration**:
+ - Automatically searches relevant indexes
+ - Uses existing Meilisearch search capabilities
+ - Respects API key permissions
+
+## Security considerations
+
+The chat completions feature integrates with Meilisearch's existing security model:
+
+- **API key permissions**: Chat only accesses indexes visible to the provided API key
+- **Tenant tokens**: Support for multi-tenant applications
+- **LLM credentials**: Stored securely in workspace settings
+- **Content isolation**: Responses based only on indexed content
+
+## Next steps
+
+- [Get started with chat completions implementation](/guides/ai/getting_started_with_chat)
+- [Explore the chat completions API reference](/reference/api/chats)
+- [Learn about experimental features](/reference/api/experimental_features)
diff --git a/reference/api/chats.mdx b/reference/api/chats.mdx
new file mode 100644
index 0000000000..02d03836ee
--- /dev/null
+++ b/reference/api/chats.mdx
@@ -0,0 +1,619 @@
+---
+title: Chats
+sidebarTitle: Chats
+description: The /chats route allows you to create conversational search experiences using LLM technology
+---
+
+import { RouteHighlighter } from '/snippets/route_highlighter.mdx';
+import { Warning } from '/snippets/notice_tag.mdx'
+
+The `/chats` route enables AI-powered conversational search by integrating Large Language Models (LLMs) with your Meilisearch data. This feature allows users to ask questions in natural language and receive contextual answers based on your indexed content.
+
+
+This is an experimental feature. Use the Meilisearch Cloud UI or the experimental features endpoint to activate it:
+
+```sh
+curl \
+ -X PATCH 'MEILISEARCH_URL/experimental-features/' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "chatCompletions": true
+ }'
+```
+
+
+## Chat completions workspace object
+
+```json
+{
+ "uid": "customer-support"
+}
+```
+
+| Name | Type | Description |
+| :---------- | :----- | :-------------------------------------------------- |
+| **`uid`** | String | Unique identifier for the chat completions workspace |
+
+## Update the chat workspace settings
+
+
+
+Configure the LLM provider and settings for a chat workspace.
+
+```json
+{
+ "source": "openAi",
+ "orgId": null,
+ "projectId": null,
+ "apiVersion": null,
+ "deploymentId": null,
+ "baseUrl": null,
+ "apiKey": "sk-abc...",
+ "prompts": {
+ "system": "You are a helpful assistant that answers questions based on the provided context."
+ }
+}
+```
+
+### Path parameters
+
+| Name | Type | Description |
+| :-------------- | :----- | :----------------------------------- |
+| **`workspace`** | String | The workspace identifier |
+
+### Settings parameters
+
+| Name | Type | Description |
+| :---------------- | :----- | :---------------------------------------------------------------------------- |
+| **`source`** | String | LLM source: `"openAi"`, `"azureOpenAi"`, `"mistral"`, `"gemini"`, or `"vLlm"` |
+| **`orgId`** | String | Organization ID for the LLM provider (required for azureOpenAi) |
+| **`projectId`** | String | Project ID for the LLM provider |
+| **`apiVersion`** | String | API version for the LLM provider (required for azureOpenAi) |
+| **`deploymentId`**| String | Deployment ID for the LLM provider (required for azureOpenAi) |
+| **`baseUrl`** | String | Base URL for the provider (required for azureOpenAi and vLlm) |
+| **`apiKey`** | String | API key for the LLM provider (optional for vLlm) |
+| **`prompts`** | Object | Prompts object containing system prompts and other configuration |
+
+### The prompts object
+
+| Name | Type | Description |
+| :------------------------ | :----- | :---------------------------------------------------------------- |
+| **`system`** | String | A prompt added to the start of the conversation to guide the LLM |
+| **`searchDescription`** | String | A prompt to explain what the internal search function does |
+| **`searchQParam`** | String | A prompt to explain what the `q` parameter of the search function does and how to use it |
+| **`searchIndexUidParam`** | String | A prompt to explain what the `indexUid` parameter of the search function does and how to use it |
+
+
+### Request body
+
+```json
+{
+ "source": "openAi",
+ "apiKey": "sk-...",
+ "prompts": {
+ "system": "You are a helpful assistant."
+ }
+}
+```
+
+All fields are optional. Only provided fields will be updated.
+
+### Response: `200 OK`
+
+Returns the updated settings object. Note that `apiKey` is write-only and will not be returned in the response.
+
+### Examples
+
+
+
+```bash openAi
+curl \
+ -X PATCH 'http://localhost:7700/chats/customer-support/settings' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "source": "openAi",
+ "apiKey": "sk-abc...",
+ "prompts": {
+ "system": "You are a helpful customer support assistant."
+ }
+ }'
+```
+
+```bash azureOpenAi
+curl \
+ -X PATCH 'http://localhost:7700/chats/customer-support/settings' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "source": "azureOpenAi",
+ "orgId": "your-azure-org-id",
+ "apiVersion": "your-api-version",
+ "deploymentId": "your-deployment-id",
+ "apiKey": "your-azure-api-key",
+ "baseUrl": "https://your-resource.openai.azure.com",
+ "prompts": {
+ "system": "You are a helpful customer support assistant."
+ }
+ }'
+```
+
+```bash mistral
+curl \
+ -X PATCH 'http://localhost:7700/chats/customer-support/settings' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "source": "mistral",
+ "apiKey": "your-mistral-api-key",
+ "prompts": {
+ "system": "You are a helpful customer support assistant."
+ }
+ }'
+```
+
+```bash gemini
+curl \
+ -X PATCH 'http://localhost:7700/chats/customer-support/settings' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "source": "gemini",
+ "apiKey": "your-gemini-api-key",
+ "prompts": {
+ "system": "You are a helpful customer support assistant."
+ }
+ }'
+```
+
+```bash vLlm
+curl \
+ -X PATCH 'http://localhost:7700/chats/customer-support/settings' \
+ -H 'Authorization: Bearer MASTER_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "source": "vLlm",
+ "baseUrl": "http://your-vllm-server:8000",
+ "prompts": {
+ "system": "You are a helpful customer support assistant."
+ }
+ }'
+```
+
+
+
+## Chat completions
+
+
+
+Create a chat completion using the OpenAI-compatible interface. The endpoint searches relevant indexes and generates responses based on the retrieved content.
+
+### Path parameters
+
+| Name | Type | Description |
+| :-------------- | :----- | :---------------------------------------------------- |
+| **`workspace`** | String | The chat completion workspace unique identifier (uid) |
+
+### Request body
+
+```json
+{
+ "model": "gpt-3.5-turbo",
+ "messages": [
+ {
+ "role": "user",
+ "content": "What are the main features of Meilisearch?"
+ }
+ ],
+ "stream": true
+}
+```
+
+| Name | Type | Required | Description |
+| :------------- | :------ | :------- | :--------------------------------------------------------------------------- |
+| **`model`** | String | Yes | Model to use and will be related to the source LLM in the workspace settings |
+| **`messages`** | Array | Yes | Array of message objects with `role` and `content` |
+| **`stream`** | Boolean | No | Enable streaming responses (default: `true`) |
+
+
+Currently, only streaming responses (`stream: true`) are supported. Non-streaming responses will be available in a future release.
+
+
+### Message object
+
+| Name | Type | Description |
+| :------------ | :----- | :--------------------------------------------------------- |
+| **`role`** | String | Message role: `"system"`, `"user"`, or `"assistant"` |
+| **`content`** | String | Message content |
+
+### Response
+
+The response follows the OpenAI chat completions format. For streaming responses, the endpoint returns Server-Sent Events (SSE).
+
+#### Streaming response example
+
+```
+data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{"content":"Meilisearch"},"finish_reason":null}]}
+
+data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{"content":" is"},"finish_reason":null}]}
+
+data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-3.5-turbo","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
+
+data: [DONE]
+```
+
+### Example
+
+
+
+```bash cURL
+curl \
+ -X POST 'http://localhost:7700/chats/customer-support/chat/completions' \
+ -H 'Authorization: Bearer DEFAULT_CHAT_KEY' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "model": "gpt-3.5-turbo",
+ "messages": [
+ {
+ "role": "user",
+ "content": "What is Meilisearch?"
+ }
+ ],
+ "stream": true
+ }'
+```
+
+```javascript Javascript OpenAI SDK
+import OpenAI from 'openai';
+
+const client = new OpenAI({
+ baseURL: 'http://localhost:7700/chats/customer-support',
+ apiKey: 'DEFAULT_CHAT_KEY',
+});
+
+const stream = await client.chat.completions.create({
+ model: 'gpt-3.5-turbo',
+ messages: [{ role: 'user', content: 'What is Meilisearch?' }],
+ stream: true,
+});
+
+for await (const chunk of stream) {
+ console.log(chunk.choices[0]?.delta?.content || '');
+}
+```
+
+```python Python OpenAI SDK
+from openai import OpenAI
+
+client = OpenAI(
+ base_url="http://localhost:7700/chats/customer-support",
+ api_key="DEFAULT_CHAT_KEY"
+)
+
+stream = client.chat.completions.create(
+ model="gpt-3.5-turbo",
+ messages=[{"role": "user", "content": "What is Meilisearch?"}],
+ stream=True,
+)
+
+for chunk in stream:
+ if chunk.choices[0].delta.content is not None:
+ print(chunk.choices[0].delta.content, end="")
+```
+
+
+
+## Get chat settings
+
+
+
+Retrieve the current settings for a chat workspace.
+
+### Path parameters
+
+| Name | Type | Description |
+| :-------------- | :----- | :----------------------------------- |
+| **`workspace`** | String | The workspace identifier |
+
+### Response: `200 OK`
+
+Returns the settings object without the `apiKey` field.
+
+```json
+{
+ "source": "openAi",
+ "prompts": {
+ "system": "You are a helpful assistant."
+ }
+}
+```
+
+### Example
+
+
+
+```bash cURL
+curl \
+ -X GET 'http://localhost:7700/chats/customer-support/settings' \
+ -H 'Authorization: Bearer MASTER_KEY'
+```
+
+
+
+## List chat workspaces
+
+
+
+List all available chat workspaces. Results can be paginated using query parameters.
+
+### Query parameters
+
+| Query parameter | Description | Default value |
+| :-------------- | :----------------------------- | :------------ |
+| **`offset`** | Number of workspaces to skip | `0` |
+| **`limit`** | Number of workspaces to return | `20` |
+
+### Response
+
+| Name | Type | Description |
+| :------------ | :------ | :---------------------------------------- |
+| **`results`** | Array | An array of chat workspace objects |
+| **`offset`** | Integer | Number of workspaces skipped |
+| **`limit`** | Integer | Number of workspaces returned |
+| **`total`** | Integer | Total number of workspaces |
+
+### Example
+
+
+
+```bash cURL
+curl \
+ -X GET 'http://localhost:7700/chats?limit=10' \
+ -H 'Authorization: Bearer MASTER_KEY'
+```
+
+
+
+#### Response: `200 OK`
+
+```json
+{
+ "results": [
+ {
+ "uid": "customer-support"
+ },
+ {
+ "uid": "internal-docs"
+ }
+ ],
+ "offset": 0,
+ "limit": 10,
+ "total": 2
+}
+```
+
+## Authentication
+
+The chat feature integrates with Meilisearch's authentication system:
+
+- **Default Chat API Key**: A new default key is created when chat is enabled, with permissions to access chat endpoints
+- **Tenant tokens**: Fully supported for multi-tenant applications
+- **Index visibility**: Chat searches only indexes accessible with the provided API key
+
+## Tool calling
+
+The chat feature uses internal tool calling to search your indexes and provide enhanced user experience. For optimal performance and user experience, you should declare three special tools in your chat completion requests. These tools are handled internally by Meilisearch and provide real-time feedback about search operations, conversation context, and source documents.
+
+### Overview of Special Tools
+
+- **`_meiliSearchProgress`**: Reports real-time search progress and operations
+- **`_meiliAppendConversationMessage`**: Maintains conversation context for better responses
+- **`_meiliSearchSources`**: Provides source documents used in generating responses
+
+### Tool Declaration
+
+Include these tools in your request's `tools` array to enable enhanced functionality:
+
+
+
+```json Complete Tool Declaration
+{
+ "model": "gpt-3.5-turbo",
+ "stream": true,
+ "messages": [
+ {
+ "role": "user",
+ "content": "What is Meilisearch?"
+ }
+ ],
+ "tools": [
+ {
+ "type": "function",
+ "function": {
+ "name": "_meiliSearchProgress",
+ "description": "Provides information about the current Meilisearch search operation",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "call_id": {
+ "type": "string",
+ "description": "The call ID to track the sources of the search"
+ },
+ "function_name": {
+ "type": "string",
+ "description": "The name of the function we are executing"
+ },
+ "function_parameters": {
+ "type": "string",
+ "description": "The parameters of the function we are executing, encoded in JSON"
+ }
+ },
+ "required": ["call_id", "function_name", "function_parameters"],
+ "additionalProperties": false
+ },
+ "strict": true
+ }
+ },
+ {
+ "type": "function",
+ "function": {
+ "name": "_meiliAppendConversationMessage",
+ "description": "Append a new message to the conversation based on what happened internally",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "role": {
+ "type": "string",
+ "description": "The role of the messages author, either `role` or `assistant`"
+ },
+ "content": {
+ "type": "string",
+ "description": "The contents of the `assistant` or `tool` message. Required unless `tool_calls` is specified."
+ },
+ "tool_calls": {
+ "type": ["array", "null"],
+ "description": "The tool calls generated by the model, such as function calls",
+ "items": {
+ "type": "object",
+ "properties": {
+ "function": {
+ "type": "object",
+ "description": "The function that the model called",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the function to call"
+ },
+ "arguments": {
+ "type": "string",
+ "description": "The arguments to call the function with, as generated by the model in JSON format. Note that the model does not always generate valid JSON, and may hallucinate parameters not defined by your function schema. Validate the arguments in your code before calling your function."
+ }
+ }
+ },
+ "id": {
+ "type": "string",
+ "description": "The ID of the tool call"
+ },
+ "type": {
+ "type": "string",
+ "description": "The type of the tool. Currently, only function is supported"
+ }
+ }
+ }
+ },
+ "tool_call_id": {
+ "type": ["string", "null"],
+ "description": "Tool call that this message is responding to"
+ }
+ },
+ "required": ["role", "content", "tool_calls", "tool_call_id"],
+ "additionalProperties": false
+ },
+ "strict": true
+ }
+ },
+ {
+ "type": "function",
+ "function": {
+ "name": "_meiliSearchSources",
+ "description": "Provides sources of the search",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "call_id": {
+ "type": "string",
+ "description": "The call ID to track the original search associated to those sources"
+ },
+ "documents": {
+ "type": "object",
+ "description": "The documents associated with the search (call_id). Only the displayed attributes of the documents are returned"
+ }
+ },
+ "required": ["call_id", "documents"],
+ "additionalProperties": false
+ },
+ "strict": true
+ }
+ }
+ ]
+}
+```
+
+
+
+### Tool Functions Explained
+
+#### `_meiliSearchProgress`
+
+This tool reports real-time progress of internal search operations. When declared, Meilisearch will call this function whenever search operations are performed in the background.
+
+**Purpose**: Provides transparency about search operations and reduces perceived latency by showing users what's happening behind the scenes.
+
+**Arguments**:
+- `call_id`: Unique identifier to track the search operation
+- `function_name`: Name of the internal function being executed (e.g., "_meiliSearchInIndex")
+- `function_parameters`: JSON-encoded string containing search parameters like `q` (query) and `index_uid`
+
+**Example Response**:
+```json
+{
+ "function": {
+ "name": "_meiliSearchProgress",
+ "arguments": "{\"call_id\":\"89939d1f-6857-477c-8ae2-838c7a504e6a\",\"function_name\":\"_meiliSearchInIndex\",\"function_parameters\":\"{\\\"index_uid\\\":\\\"movies\\\",\\\"q\\\":\\\"search engine\\\"}\"}"
+ }
+}
+```
+
+#### `_meiliAppendConversationMessage`
+
+Since the `/chats/{workspace}/chat/completions` endpoint is stateless, this tool helps maintain conversation context by requesting the client to append internal messages to the conversation history.
+
+**Purpose**: Maintains conversation context for better response quality in subsequent requests by preserving tool calls and results.
+
+**Arguments**:
+- `role`: Message author role ("user" or "assistant")
+- `content`: Message content (for tool results)
+- `tool_calls`: Array of tool calls made by the assistant
+- `tool_call_id`: ID of the tool call this message responds to
+
+**Example Response**:
+```json
+{
+ "function": {
+ "name": "_meiliAppendConversationMessage",
+ "arguments": "{\"role\":\"assistant\",\"tool_calls\":[{\"id\":\"call_ijAdM42bixq9lAF4SiPwkq2b\",\"type\":\"function\",\"function\":{\"name\":\"_meiliSearchInIndex\",\"arguments\":\"{\\\"index_uid\\\":\\\"movies\\\",\\\"q\\\":\\\"search engine\\\"}\"}}]}"
+ }
+}
+```
+
+#### `_meiliSearchSources`
+
+This tool provides the source documents that were used by the LLM to generate responses, enabling transparency and allowing users to verify information sources.
+
+**Purpose**: Shows users which documents were used to generate responses, improving trust and enabling source verification.
+
+**Arguments**:
+- `call_id`: Matches the `call_id` from `_meiliSearchProgress` to associate queries with results
+- `documents`: JSON object containing the source documents with only displayed attributes
+
+**Example Response**:
+```json
+{
+ "function": {
+ "name": "_meiliSearchSources",
+ "arguments": "{\"call_id\":\"abc123\",\"documents\":[{\"id\":197302,\"title\":\"The Sacred Science\",\"overview\":\"Diabetes. Prostate cancer...\",\"genres\":[\"Documentary\",\"Adventure\",\"Drama\"]}]}"
+ }
+}
+```
+
+### Implementation Best Practices
+
+1. **Always declare all three tools** for the best user experience
+2. **Handle progress updates** by displaying search status to users during streaming
+3. **Append conversation messages** as requested to maintain context for future requests
+4. **Display source documents** to users for transparency and verification
+5. **Use the `call_id`** to associate progress updates with their corresponding source results
+
+
+These special tools are handled internally by Meilisearch and are not forwarded to the LLM provider. They serve as a communication mechanism between Meilisearch and your application to provide enhanced user experience features.
+
diff --git a/reference/api/experimental_features.mdx b/reference/api/experimental_features.mdx
index dd81922901..3393ceed91 100644
--- a/reference/api/experimental_features.mdx
+++ b/reference/api/experimental_features.mdx
@@ -25,7 +25,8 @@ The experimental API route is not compatible with all experimental features. Con
"logsRoute": true,
"containsFilter": false,
"editDocumentsByFunction": false,
- "network": false
+ "network": false,
+ "chatCompletions": false
}
```
@@ -36,6 +37,7 @@ The experimental API route is not compatible with all experimental features. Con
| **`containsFilter`** | Boolean | `true` if feature is active, `false` otherwise |
| **`editDocumentsByFunction`** | Boolean | `true` if feature is active, `false` otherwise |
| **`network`** | Boolean | `true` if feature is active, `false` otherwise |
+| **`chatCompletions`** | Boolean | `true` if feature is active, `false` otherwise |
## Get all experimental features
@@ -55,7 +57,8 @@ Get a list of all experimental features that can be activated via the `/experime
"logsRoute": true,
"containsFilter": false,
"editDocumentsByFunction": false,
- "network": false
+ "network": false,
+ "chatCompletions": false
}
```
@@ -83,6 +86,7 @@ Setting a field to `null` leaves its value unchanged.
"logsRoute": true,
"containsFilter": false,
"editDocumentsByFunction": false,
- "network": false
+ "network": false,
+ "chatCompletions": false
}
```
diff --git a/reference/api/settings.mdx b/reference/api/settings.mdx
index a500ee35bd..4a5f1a6172 100644
--- a/reference/api/settings.mdx
+++ b/reference/api/settings.mdx
@@ -126,7 +126,8 @@ By default, the settings object looks like this. All fields are modifiable.
"facetSearch": true,
"prefixSearch": "indexingTime",
"searchCutoffMs": null,
- "embedders": {}
+ "embedders": {},
+ "chat": {}
}
```
@@ -196,7 +197,8 @@ Get the settings of an index.
"facetSearch": true,
"prefixSearch": "indexingTime",
"searchCutoffMs": null,
- "embedders": {}
+ "embedders": {},
+ "chat": {}
}
```
@@ -240,7 +242,8 @@ If the provided index does not exist, it will be created.
| **[`stopWords`](#stop-words)** | Array of strings | Empty | List of words ignored by Meilisearch when present in search queries |
| **[`synonyms`](#synonyms)** | Object | Empty | List of associated words treated similarly |
| **[`typoTolerance`](#typo-tolerance)** | Object | [Default object](#typo-tolerance-object) | Typo tolerance settings |
-| **[`embedders`](#embedders)** | Object of objects | [Default object](#embedders-object) | Embedder required for performing meaning-based search queries |
+| **[`embedders`](#embedders)** | Object of objects | [Default object](#embedders-object) | Embedder required for performing meaning-based search queries |
+| **[`chat`](#conversation)** | Object | [Default object](#chat-object) | Chat settings for performing conversation-based queries |
#### Example
@@ -2917,3 +2920,114 @@ To remove a single embedder, use the [update embedder settings endpoint](#update
```
You can use the returned `taskUid` to get more details on [the status of the task](/reference/api/tasks#get-one-task).
+
+## Conversation
+
+
+This is an experimental feature. Use the Meilisearch Cloud UI or the experimental features endpoint to activate it:
+
+```sh
+curl \
+ -X PATCH 'MEILISEARCH_URL/experimental-features/' \
+ -H 'Content-Type: application/json' \
+ --data-binary '{
+ "chatCompletions": true
+ }'
+```
+
+
+Conversational querying allows a more human-like interaction with your search engine. It enables you to ask questions and receive relevant answers based on the content of your documents.
+
+### Chat object
+
+The chat object in the index settings contains multiple settings to configure the conversational querying.
+
+```json
+{
+ "description": "Contains a bunch of movies from the IMdb database. Each movie has a title, overview, and rating.",
+ "documentTemplate": "A movie titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}",
+ "documentTemplateMaxBytes": 400,
+ "searchParameters": {
+ "hybrid": { "embedder": "my-embedder" },
+ "limit": 20,
+ }
+}
+```
+
+These embedder objects may contain the following fields:
+
+| Name | Type | Default Value | Description |
+| ------------------------------ | ------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------- |
+| **`description`** | String | Empty | The description of the index. Used to help the LLM decide which index to use when generating answers |
+| **`documentTemplate`** | String | `{% for field in fields %} {% if field.is_searchable and not field.value == nil %}{{ field.name }}: {{ field.value }} {% endif %} {% endfor %}` | Template defining the data Meilisearch sends to the LLM |
+| **`documentTemplateMaxBytes`** | Integer | 400 | Maximum allowed size of rendered document template |
+| **`searchParameters`** | Object | Empty | The search parameters to use when LLM is performing search requests |
+
+### Search parameters object
+
+Corresponds to a subset of the [search parameters object](/reference/api/search#search-parameters-object):
+ - **`hybrid`**
+ - **`limit`**
+ - **`sort`**
+ - **`distinct`**
+ - **`matchingStrategy`**
+ - **`attributesToSearchOn`**
+ - **`rankingScoreThreshold`**
+
+### Get index chat settings
+
+
+
+Get the index chat settings configured for an index.
+
+#### Path parameters
+
+| Name | Type | Description |
+| :---------------- | :----- | :------------------------------------------------------------------------ |
+| **`index_uid`** * | String | [`uid`](/learn/getting_started/indexes#index-uid) of the requested index |
+
+#### Example
+
+
+
+##### Response: `200 OK`
+
+```json
+{
+ "description": "",
+ "documentTemplate": "{% for field in fields %} {% if field.is_searchable and not field.value == nil %}{{ field.name }}: {{ field.value }} {% endif %} {% endfor %}",
+ "documentTemplateMaxBytes": 400,
+ "searchParameters": {}
+}
+```
+
+### Update index chat settings
+
+
+
+Partially update the index chat settings for an index.
+
+#### Path parameters
+
+| Name | Type | Description |
+| :---------------- | :----- | :------------------------------------------------------------------------ |
+| **`index_uid`** * | String | [`uid`](/learn/getting_started/indexes#index-uid) of the requested index |
+
+#### Body
+
+```json
+{
+ "description": ,
+ "documentTemplate": ,
+ "documentTemplateMaxBytes": ,
+ "searchParameters": {
+ "hybrid":