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 on an instance created after v1.15.1, it automatically generates a “Default Chat API Key” with chatCompletions
and search
permissions on all indexes. Check if you have the key using:
curl http://localhost:7700/keys \
-H "Authorization: Bearer MEILISEARCH_KEY"
Look for the key with the description “Default Chat API Key” Use this key when querying the /chats
endpoint.
Troubleshooting: Missing default chat API key
If your instance does not have a Default Chat API Key, create one manually:
curl \
-X POST 'http://localhost:7700/keys' \
-H 'Authorization: Bearer MEILISEARCH_KEY' \
-H 'Content-Type: application/json' \
--data-binary '{
"name": "Chat API Key",
"description": "API key for chat completions",
"actions": ["search", "chatCompletions"],
"indexes": ["*"],
"expiresAt": null
}'
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.
Create a workspace with your LLM provider settings. Here are examples for different providers:
openAi
azureOpenAi
mistral
gemini
vLlm
curl \
-X PATCH '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:
JavaScript
Python
TypeScript
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:
Restart Meilisearch with a master key: meilisearch --master-key yourKey
Enable experimental features (see setup instructions above)
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:
Check workspace configuration:
curl http://localhost:7700/chats/my-assistant/settings \
-H "Authorization: Bearer MEILISEARCH_KEY"
Update with valid API key:
curl -X PATCH 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