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 are optional, but greatly improve user experience:
  • _meiliSearchProgress: shows users what searches are being performed
  • _meiliSearchSources: displays the actual documents used to generate responses

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: 'MEILISEARCH_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