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 for activation instructions.

Prerequisites

Before starting, ensure you have:
  • Meilisearch instance running (v1.15.1 or later) with a master key (required for authentication)
  • 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
Important: You MUST start Meilisearch with a master key to enable authentication. Without it, the chat feature will not work properly.Example: meilisearch --master-key yourMasterKeyIn some versions, you may also need to add the --experimental-enable-chat flag when starting Meilisearch.

Quick start

Enable the chat completions feature

First, enable the chat completions experimental feature:
curl \
  -X PATCH 'http://localhost:7700/experimental-features/' \
  -H 'Authorization: Bearer <master-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 <master-key>"
Look for the key with “Default Chat API Key” in the description. You’ll use this key (or the master key) for chat endpoint requests.

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 <master-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 <master-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
  }'
Currently, only streaming responses (stream: true) are supported. Non-streaming responses are not yet available and will result in an error.

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:
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 the official OpenAI SDK. 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: 'YOUR_CHAT_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);
}

Enabling database search with Meilisearch tools

Critical: Without including the Meilisearch tools in your request, the chat will only use the LLM’s general knowledge and won’t search your actual Meilisearch indexes!
To make the chat search your Meilisearch indexes, you must include these special tools in your request:
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"
        }
      }
    ]
  }'
These tools enable:
  • _meiliSearchProgress: Shows users what searches are being performed
  • _meiliSearchSources: Provides the actual documents used to generate responses

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 <master-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 <master-key>"
    
  2. Update with valid API key:
    curl -X PUT http://localhost:7700/chats/my-assistant/settings \
      -H "Authorization: Bearer <master-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

Complete working example

Here’s a full example showing the complete setup process:

Step 1: Start Meilisearch with authentication

meilisearch --master-key myMasterKey123

Step 2: Enable experimental features

curl -X PATCH 'http://localhost:7700/experimental-features/' \
  -H 'Authorization: Bearer myMasterKey123' \
  -H 'Content-Type: application/json' \
  -d '{"chatCompletions": true}'

Step 3: Create and populate an index

# Create index
curl -X POST 'http://localhost:7700/indexes' \
  -H 'Authorization: Bearer myMasterKey123' \
  -H 'Content-Type: application/json' \
  -d '{"uid": "movies", "primaryKey": "id"}'

# Add documents
curl -X POST 'http://localhost:7700/indexes/movies/documents' \
  -H 'Authorization: Bearer myMasterKey123' \
  -H 'Content-Type: application/json' \
  -d '[
    {"id": 1, "title": "Interstellar", "description": "A team of explorers travel through a wormhole in space"},
    {"id": 2, "title": "The Martian", "description": "An astronaut becomes stranded on Mars"}
  ]'

Step 4: Configure index for chat

curl -X PATCH 'http://localhost:7700/indexes/movies/settings' \
  -H 'Authorization: Bearer myMasterKey123' \
  -H 'Content-Type: application/json' \
  -d '{
    "chat": {
      "description": "A movie database with titles and descriptions",
      "documentTemplate": "Title: {{ title }}\nDescription: {{ description }}\n",
      "documentTemplateMaxBytes": 400
    }
  }'

Step 5: Create chat workspace

curl -X PUT 'http://localhost:7700/chats/movie-advisor/settings' \
  -H 'Authorization: Bearer myMasterKey123' \
  -H 'Content-Type: application/json' \
  -d '{
    "source": "openAi",
    "apiKey": "sk-your-openai-key",
    "prompts": {
      "system": "You are a movie recommendation assistant. Help users find movies based on their preferences."
    }
  }'

Step 6: Get your chat API key

curl http://localhost:7700/keys \
  -H "Authorization: Bearer myMasterKey123" \
  | grep -A 5 "Default Chat API Key"

Step 7: Make a chat request with tools

curl -N -X POST 'http://localhost:7700/chats/movie-advisor/chat/completions' \
  -H 'Authorization: Bearer <your-chat-api-key>' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [{"role": "user", "content": "What space movies do you have?"}],
    "stream": true,
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "_meiliSearchProgress",
          "description": "Reports search progress"
        }
      },
      {
        "type": "function",
        "function": {
          "name": "_meiliSearchSources",
          "description": "Provides source documents"
        }
      }
    ]
  }'

Next steps