Start here
Getting started
Go from a new project to your first search in six steps. First, what Headband is.
What is Headband?
One search API in front of Meilisearch, Typesense, Elasticsearch and Visor. Each index picks its own engine, all in one project behind one key.
Per-index engines
Mix Meilisearch, Typesense, Elasticsearch and Visor in one project.
Bring your own engine
Point an index at your own cluster. Headband keeps how to reach it, not your documents.
Built for agents
llms.txt, RAG endpoints, and authenticated HTTP MCP.
Choose your path
Quick start
Get up and running in six steps. Every snippet runs as written against https://headband.dev; replace the placeholder keys with the keys from your project.
1. Create a project in the dashboard
You'll receive a project-scoped admin key (hb_adm_) and a search key (hb_src_) automatically.
2. Create an index
export ADMIN_KEY="hb_adm_..."
curl -X POST https://api.headband.dev/v1/indexes \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"uid": "products",
"primaryKey": "id",
"engine": "meilisearch"
}'3. Configure searchable, filterable, and sortable fields
This is the Meilisearch form. Each engine takes these differently, so check Engine compatibility for yours. A filter or sort on a field that is not set up fails the whole search.
API=https://api.headband.dev/v1
curl -X PATCH "$API/indexes/products/settings" \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"searchableAttributes": [
"title",
"description"
],
"filterableAttributes": [
"category",
"price"
],
"sortableAttributes": [
"price",
"createdAt"
]
}'4. Push your documents
A search key can read every field you send, so leave private fields out. One request body can be at most 4 MiB. See Split a large import.
API=https://api.headband.dev/v1
PARAMS="index=products&primaryKey=id"
curl -X POST "$API/documents?$PARAMS" \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"id": 1,
"title": "Widget",
"price": 9.99
},
{
"id": 2,
"title": "Gadget",
"price": 24.99
}
]'5. Poll returned task UIDs until async writes succeed
Task UIDs are numbered per engine, so pass the index the write went to. Replace {taskUid} with the taskUid from step 4.
# GET /v1/tasks/{taskUid}?index=products
API=https://api.headband.dev/v1
curl -H "Authorization: Bearer $ADMIN_KEY" \
"$API/tasks/{taskUid}?index=products"6. Search
export SEARCH_KEY="hb_src_..."
curl -X POST https://api.headband.dev/v1/search \
-H "Authorization: Bearer $SEARCH_KEY" \
-H "Content-Type: application/json" \
-d '{
"index": "products",
"q": "widget",
"filter": "price > 5",
"sort": ["price:asc"]
}'Data boundary
Headband stores routing metadata, encrypted engine configs, hashed API keys, usage, and analytics. Documents are indexed into the selected engine. BYOE keeps the search index in your engine; Platform Default uses a Headband-managed engine. Query analytics may include query text, filters, hit counts, latency, variants, and experiment metadata.