Connect Any App

Every CelerSearch instance runs Meilisearch and speaks its standard API, so the official SDKs and any HTTP client work as they are. You need two values: the endpoint URL and the API key.

1. Get your connection details

In app.celersearch.com, open your instance. The Connection details card shows:

  • Endpoint URL: your instance's https:// address
  • API key: click the eye icon to reveal it, or copy it directly

Store both as environment variables on your server:

.env
Shell
CELERSEARCH_URL=https://your-endpoint-url
CELERSEARCH_API_KEY=your-api-key

The API key has full access

The instance API key is the instance's master key: it can read, change and delete everything. Keep it on your server, in environment variables or a secrets manager, and never ship it in browser or mobile app code. If it leaks, contact us and we'll rotate it.

2. Check the connection

Shell
curl -H "Authorization: Bearer $CELERSEARCH_API_KEY" "$CELERSEARCH_URL/health"
# {"status":"available"}

Every request needs the Authorization: Bearer header, including /health, which is public on a self-hosted Meilisearch.

The examples below add two documents to a movies index (created automatically on the first write) and run a search with a typo in it.

JavaScript / TypeScript

Shell
npm install meilisearch
search.mjs
JavaScript
import { Meilisearch } from 'meilisearch'

const client = new Meilisearch({
  host: process.env.CELERSEARCH_URL,
  apiKey: process.env.CELERSEARCH_API_KEY,
})

const movies = client.index('movies')

// Writes are asynchronous tasks; waitTask() resolves once it's processed.
await movies.addDocuments([
  { id: 1, title: 'Carol', genres: ['Romance', 'Drama'] },
  { id: 2, title: 'Wonder Woman', genres: ['Action', 'Adventure'] },
]).waitTask()

const { hits } = await movies.search('wondr woman')
console.log(hits)

PHP

Shell
composer require meilisearch/meilisearch-php guzzlehttp/guzzle http-interop/http-factory-guzzle:^1.0
search.php
PHP
<?php

require_once __DIR__ . '/vendor/autoload.php';

use Meilisearch\Client;

$client = new Client(getenv('CELERSEARCH_URL'), getenv('CELERSEARCH_API_KEY'));
$movies = $client->index('movies');

$task = $movies->addDocuments([
    ['id' => 1, 'title' => 'Carol', 'genres' => ['Romance', 'Drama']],
    ['id' => 2, 'title' => 'Wonder Woman', 'genres' => ['Action', 'Adventure']],
]);
$client->waitForTask($task['taskUid']);

print_r($movies->search('wondr woman')->getHits());

Python

Shell
pip install meilisearch
search.py
PYTHON
import os

import meilisearch

client = meilisearch.Client(os.environ["CELERSEARCH_URL"], os.environ["CELERSEARCH_API_KEY"])
movies = client.index("movies")

task = movies.add_documents([
    {"id": 1, "title": "Carol", "genres": ["Romance", "Drama"]},
    {"id": 2, "title": "Wonder Woman", "genres": ["Action", "Adventure"]},
])
client.wait_for_task(task.task_uid)

print(movies.search("wondr woman")["hits"])

Other languages

Official Meilisearch SDKs also exist for Go, Ruby, Rust, Java, .NET, Swift and Dart. Configure them the same way: the endpoint URL is the host and the API key is the key. Plain HTTP works too; the Meilisearch API reference applies as written.

Search from the browser

Because the API key has full access, browser search goes through your backend. A small endpoint receives the visitor's query, searches with the key on the server, and returns only what you choose to expose:

server.mjs
JavaScript
import express from 'express'
import { Meilisearch } from 'meilisearch'

const client = new Meilisearch({
  host: process.env.CELERSEARCH_URL,
  apiKey: process.env.CELERSEARCH_API_KEY,
})

const app = express()

app.get('/api/search', async (req, res) => {
  const { hits } = await client.index('movies').search(String(req.query.q ?? ''), {
    limit: 20,
    attributesToRetrieve: ['id', 'title', 'genres'],
  })
  res.json(hits)
})

app.listen(3000)
JavaScript
const hits = await fetch(`/api/search?q=${encodeURIComponent(query)}`).then((r) => r.json())

Your endpoint decides which index and fields visitors can reach, the same job a search-only key does elsewhere. Building with InstantSearch? The Next.js guide shows a proxy that works with instant-meilisearch.

Custom API keys and tenant tokens

Keys you create with the /keys endpoint, and tenant tokens, can't be used to connect to a CelerSearch instance yet: requests that use them are rejected with 401. Use the instance API key from your backend, as shown above.

How it differs from self-hosted Meilisearch

  • Authentication: send the instance API key as Authorization: Bearer <key> on every request.
  • Dumps and snapshots: POST /dumps and POST /snapshots are disabled. Your data is protected by encrypted backups you manage from the portal.
  • Engine version: you choose it and apply upgrades from the portal when you're ready.
  • Document limit: your plan sets how many documents the instance holds across all indexes. Searches are always unlimited.

When you reach the document limit

Requests that add or update documents (POST or PUT on /indexes/{uid}/documents) are refused with 429:

JSON
{
  "error": "document_quota_exceeded",
  "message": "Document quota exceeded for this instance",
  "current_documents": 100000,
  "max_documents": 100000
}

Searches, reads and deletions keep working. Delete documents or move to a larger plan to write again. The document count refreshes periodically, so after deleting documents it can take a few minutes before writes are accepted again.

Responses from the platform

These come from CelerSearch rather than from Meilisearch, so they use error and message fields instead of Meilisearch's usual error object. The SDKs raise them as API errors with the HTTP status.

StatuserrorMeaning
401missing_api_keyNo Authorization: Bearer header
401invalid_api_keyThe key isn't an instance API key
403endpoint_disabledDumps and snapshots are managed for you
429document_quota_exceededThe plan's document limit is reached
503instance_stoppedThe instance isn't running

Next steps