This guide walks you through implementing Meilisearch’s chat completions feature to create conversational search experiences in your application.

Prerequisites

Before starting, ensure you have:
  • A secure Meilisearch >= v1.15.1 project
  • An API key from an LLM provider
  • At least one index with searchable content

Enable the chat completions feature

First, enable the chat completions experimental feature:
curl \
  -X PATCH 'http://localhost:7700/experimental-features/' \
  -H 'Authorization: Bearer MEILISEARCH_KEY' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "chatCompletions": true
  }'

Find your chat API key

When Meilisearch runs with a master key, it automatically creates a “Default Chat API Key” with chatCompletions permission. Find it using:
curl http://localhost:7700/keys \
  -H "Authorization: Bearer MEILISEARCH_KEY"
Look for the key with “Default Chat API Key” in the description. Use this key when queryin the /chats endpoint.

Configure your indexes for chat

Each index that you want to be searchable through chat needs specific configuration:
curl \
  -X PATCH 'http://localhost:7700/indexes/movies/settings' \
  -H 'Authorization: Bearer MEILISEARCH_KEY' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "chat": {
      "description": "A comprehensive movie database containing titles, descriptions, genres, and release dates to help users find movies",
      "documentTemplate": "{% for field in fields %}{% if field.is_searchable and field.value != nil %}{{ field.name }}: {{ field.value }}\n{% endif %}{% endfor %}",
      "documentTemplateMaxBytes": 400,
      "searchParameters": {}
    }
  }'
The description field helps the LLM understand what data is in the index, improving search relevance.

Configure a chat completions workspace

Create a workspace with your LLM provider settings. Here are examples for different providers:
curl \
  -X PUT 'http://localhost:7700/chats/my-assistant/settings' \
  -H 'Authorization: Bearer MEILISEARCH_KEY' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "source": "openAi",
    "apiKey": "sk-abc...",
    "baseUrl": "https://api.openai.com/v1",
    "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. Note the -N flag for handling streaming responses:
curl -N \
  -X POST 'http://localhost:7700/chats/my-assistant/chat/completions' \
  -H 'Authorization: Bearer <chat-api-key>' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "model": "gpt-3.5-turbo",
    "messages": [
      {
        "role": "user",
        "content": "What movies do you have about space exploration?"
      }
    ],
    "stream": true,
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "_meiliSearchProgress",
          "description": "Reports real-time search progress to the user"
        }
      },
      {
        "type": "function",
        "function": {
          "name": "_meiliSearchSources",
          "description": "Provides sources and references for the information"
        }
      }
    ]
  }'
Take particular note of the tools array. These settings ensure Meilisearch includes the relevant information in its database in the chat queries:
  • _meiliSearchProgress: Shows users what searches are being performed
  • _meiliSearchSources: Provides the actual documents used to generate responses
If you do not include any tools in your request, the chat will only use the LLM’s general knowledge and will not search your actual Meilisearch indexes.

Build a chat interface using the OpenAI SDK

Since Meilisearch’s chat endpoint is OpenAI-compatible, you can use the official OpenAI SDK:
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'http://localhost:7700/chats/my-assistant',
  apiKey: 'YOUR_CHAT_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 || '');
}

Error handling

When using the OpenAI SDK with Meilisearch’s chat completions endpoint, errors from the streamed responses are natively handled by OpenAI. This means you can use the SDK’s built-in error handling mechanisms without additional configuration:
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'http://localhost:7700/chats/my-assistant',
  apiKey: 'OPENAI_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);
}

Troubleshooting

Common issues and solutions

Empty reply from server (curl error 52)

Causes:
  • Meilisearch not started with a master key
  • Experimental features not enabled
  • Missing authentication in requests
Solution:
  1. Restart Meilisearch with a master key: meilisearch --master-key yourKey
  2. Enable experimental features (see setup instructions above)
  3. Include Authorization header in all requests

”Invalid API key” error

Cause: Using the wrong type of API key Solution:
  • Use either the master key or the “Default Chat API Key”
  • Don’t use search or admin API keys for chat endpoints
  • Find your chat key: curl http://localhost:7700/keys -H "Authorization: Bearer MEILISEARCH_KEY"

”Socket connection closed unexpectedly”

Cause: Usually means the OpenAI API key is missing or invalid in workspace settings Solution:
  1. Check workspace configuration:
    curl http://localhost:7700/chats/my-assistant/settings \
      -H "Authorization: Bearer MEILISEARCH_KEY"
    
  2. Update with valid API key:
    curl -X PUT http://localhost:7700/chats/my-assistant/settings \
      -H "Authorization: Bearer MEILISEARCH_KEY" \
      -H "Content-Type: application/json" \
      -d '{"apiKey": "your-valid-api-key"}'
    

Chat not searching the database

Cause: Missing Meilisearch tools in the request Solution:
  • Include _meiliSearchProgress and _meiliSearchSources tools in your request
  • Ensure indexes have proper chat descriptions configured

”stream: false is not supported” error

Cause: Trying to use non-streaming responses Solution:
  • Always set "stream": true in your requests
  • Non-streaming responses are not yet supported

Next steps