Integrations
Connect the tools you already use.
Your Meilisearch, Typesense or Elasticsearch client already works with Headband. Around it: a CLI, Vercel previews, React and Postgres Sync.
Already have an account? Sign in.
Jump to a section
What you can connect
- MeilisearchYour client, new host and key
- TypesenseYour client, new host and key
- ElasticsearchIts version 8 client
- VisorOver HTTP, with fetch or curl
- Laravel ScoutMeilisearch or Typesense
- Railsmeilisearch-rails
- Vercel previewsA copy of search per preview
- CLIIndex, push and search
- ReactSearch box, hits and facets
- Postgres SyncEarly access
- MCPLet an agent search
- Any other stack5 framework recipes
01Native clients
Keep your client. Change the host and the key.
Headband serves each engine's own API, untranslated. Point the Meilisearch, Typesense or Elasticsearch client you already use at api.headband.dev and give it your Headband key.
- One key per environment. A branch key reaches every engine on its branch, so a catalog on Meilisearch and autocomplete on Typesense share it.
- Elasticsearch takes its version 8 client. The version 9 client does not work with it yet.
- Visor answers over HTTP. Call it with fetch or curl.
meilisearch (Node)
import { Meilisearch } from "meilisearch"; const host = "https://api.headband.dev"; const client = new Meilisearch({ host: `${host}/meilisearch`, apiKey: process.env.HEADBAND_API_KEY,}); const { hits } = await client .index("movies") .search("wonder");typesense (Node)
import Typesense from "typesense"; const client = new Typesense.Client({ nodes: [{ host: "api.headband.dev", port: 443, protocol: "https", path: "/typesense", }], apiKey: process.env.HEADBAND_API_KEY,}); const { hits } = await client .collections("movies") .documents() .search({ q: "wonder", query_by: "title", });@elastic/elasticsearch@8 (Node)
import { Client } from "@elastic/elasticsearch"; const host = "https://api.headband.dev"; const client = new Client({ node: `${host}/elasticsearch`, auth: { apiKey: process.env.HEADBAND_API_KEY, },}); const result = await client.search({ index: "movies", query: { match: { title: "wonder" } },});02Laravel and Rails
Laravel Scout and Rails work as they are.
Scout on Meilisearch needs two environment variables: the host and the key. Scout's Typesense driver works too. Scout writes, so it takes an admin key.
In Rails, meilisearch-rails and the meilisearch gem need only the host and the key.
Run against production with Laravel 13, Scout 11 and meilisearch-rails 0.17.
Laravel Scout docs.env
SCOUT_DRIVER=meilisearchMEILISEARCH_HOST=https://api.headband.dev/meilisearchMEILISEARCH_KEY=hb_adm_....env
SCOUT_DRIVER=typesenseTYPESENSE_HOST=api.headband.devTYPESENSE_PORT=443TYPESENSE_PROTOCOL=httpsTYPESENSE_PATH=/typesenseTYPESENSE_API_KEY=hb_adm_...config/initializers/meilisearch.rb
host = "https://api.headband.dev" Meilisearch::Rails.configuration = { meilisearch_url: "#{host}/meilisearch", meilisearch_api_key: ENV["HEADBAND_API_KEY"]} class Book < ApplicationRecord include Meilisearch::Rails meilisearch do attribute :title endend Book.search("eloquent")03Vercel previews
A copy of search for every preview.
One command in your Vercel build forks your production search for the preview, mints keys for the fork and writes them to .env.production. The same host reaches the copy. Only the key changes.
- Forks in seconds. Meilisearch and Elasticsearch engines fork. Typesense and Visor do not yet.
- Cleans up after itself. Each push reuses the branch, and it is deleted with its engines and keys 7 days after the last push.
Build command, preview builds only
$ npx -y @headband/cli@0.7 \ branch ensure \ "preview/$VERCEL_GIT_COMMIT_REF" \ --project "$HEADBAND_PROJECT" \ --expires-in 7d \ --env-out .env.production04CLI
Index, push and search from a terminal.
headband login approves the CLI in your browser, so no key is pasted into a terminal. Then create an index, push documents and search.
The same CLI runs preview branches, keys, engines and Sync.
CLI docsTerminal
$ npm install -g @headband/cli$ headband login$ headband indexes create products \ --engine meilisearch$ headband docs push products.json \ --index products$ headband search products "red wine"05React
Search UI for React.
@headband/react gives you hooks and ready components: a search box, hits, facets, sorting and pagination.
It runs in the browser on a search key. A search key can only search, so it is safe to ship.
@headband/react
import { headband, HeadbandProvider, SearchBox, Hits,} from "@headband/react"; const client = headband( "https://api.headband.dev", "hb_src_YOUR_SEARCH_KEY"); export default function Search() { return ( <HeadbandProvider client={client} index="products" > <SearchBox placeholder="Search products..." /> <Hits hitComponent={({ hit }) => ( <p>{hit.title}</p> )} /> </HeadbandProvider> );}06Postgres SyncEarly access
Keep an index in step with Postgres.
Sync reads committed changes from your database's replication slot, renders each changed document with SQL you write, and writes it to your engine. You never push documents yourself.
It is in early access, turned on per organization.
How it works
- 1Add a sourceThe connection to your Postgres database.
- 2Create a synced indexA definition says which table, which SQL renders a document, and which engine it lands on.
- 3Run the setup SQLSync backfills the index, then streams each change as it commits.
Without early access
Sync from Drizzle ORM yourself: your app records each change in an outbox, and a worker you run writes it to Headband. Self-hosted sync
Other sources
MySQL, Shopify and Stripe: import scripts you run on your own schedule. Sync connectors
07MCP
Let an agent search your indexes.
Headband runs an MCP server over HTTP. Add it to Claude Code with one command. The docs list the four MCP clients we have tested.
It is read-only. Its search_org tool searches up to ten indexes a key can see, across engines, and returns one ranked list.
Terminal
$ KEY=hb_src_YOUR_SEARCH_KEY$ claude mcp add \ --transport http \ headband \ https://headband.dev/api/mcp \ --header "Authorization: Bearer $KEY"08Framework recipes
Any other stack calls the REST API.
From server code, POST /v1/search with a search key. Each recipe is a working search page.
Next.js + React
Use @headband/react in App Router or Pages Router search surfaces.
Remix / React Router
Call /v1/search from a loader, with the search key kept on the server.
Astro
Call /v1/search from a server-rendered page, with the search key kept on the server.
SvelteKit
Call /v1/search from a server load function, with the search key kept on the server.
Rails / Laravel / Django
Send your records with the admin key from a job, and search with the search key from a controller or view.
Start on Free, with no card.
Sign up with GitHub or Google. Free has a hard cap, so it never sends a bill.
Already have an account? Sign in.