Framework Recipes
Headband adoption starts with the stack you already ship. The React SDK is live; other framework paths use the same stable REST API and are documented as recipes. Copyable slices live in examples/ for Next.js, Remix, SvelteKit, Astro, Rails, Laravel, and Django.
Next.js + React
liveUse @headband/react in App Router or Pages Router search surfaces.
npm i @headband/reactExample: examples/nextjs-app-router/components/product-search.tsx
Setup: examples/nextjs-app-router/package.json
Remix / React Router
recipeCall the REST API from loaders/actions and hydrate client-side refinements.
fetch('/v1/search', { method: 'POST' })Example: examples/remix/app/routes/products.tsx
Setup: examples/remix/package.json
Astro
recipeRender static catalog shells and hydrate Headband search islands only where needed.
fetch('/v1/search', { method: 'POST' })Example: examples/astro/src/components/SearchIsland.astro
Setup: examples/astro/package.json
SvelteKit
recipeUse fetch against /v1/search from load functions or progressive-enhanced forms.
fetch('/v1/search', { method: 'POST' })Example: examples/sveltekit/package.json
Setup: examples/sveltekit/svelte.config.js
Rails / Laravel / Django
recipeIndex relational records with sync scripts, then render server-owned search pages.
curl https://headband.dev/v1/searchExample: examples/rails/app/controllers/search_controller.rb
Setup: examples/rails/Gemfile
Sync Connectors
Connector recipes move source records into Headband indexes through the bulk API. Hosted scheduling, retries, and secret storage are roadmap runtime concerns unless you deploy the script or webhook worker yourself.
Postgres / Neon / Supabase
recipeRun a scheduled SQL export into /v1/bulk, then validate with /v1/search.
Model: script
Schedule: Every 15 minutes for active catalogs; hourly or nightly for slower back-office data.
Health checks: sync log success event, dead-letter file is empty, optional HEADBAND_RECONCILE count check
MySQL / PlanetScale
recipeExport MySQL rows through the mysql CLI and batch them into Headband.
Model: script
Schedule: Every 15-60 minutes for product/search tables; nightly for low-change operational data.
Health checks: mysql CLI exits 0, sync log success event, optional HEADBAND_RECONCILE count check
Shopify
recipeMirror Shopify products/variants into a searchable catalog index.
Model: script
Schedule: Every 5-15 minutes for product catalogs; combine with app-owned webhooks for hot product deltas.
Health checks: Admin API page completed, dead-letter file is empty, sample search validation passes
Stripe catalog
recipeMirror products/prices into an index for account portals, docs, and internal tools.
Model: script
Schedule: Hourly for active catalogs; nightly when products/prices only change through release workflows.
Health checks: Stripe list completed, explicit deletes applied, optional HEADBAND_RECONCILE count check
BataDB Search add-on
recipeBlueprint for a paid BataDB add-on: BataDB owns billing and product UX; Headband owns retrieval, indexing, and analytics.
Model: script
Schedule: Every 5-15 minutes for paid add-on tenants; nightly reconciliation for low-change tables.
Health checks: field projection applied, dead-letter file is empty, tenant usage/count reconciliation passes
Hosted connector scheduler
roadmapManaged scheduling, retries, logs, and secret storage belong in the connector runtime roadmap.
Model: managed-roadmap
Schedule: Tenant-configurable once hosted connector scheduling ships.
Health checks: managed run history, managed retry/dead-letter queue, connector health alerts
A/B/C Testing
Headband supports retrieval experiments by using separate indexes or settings profiles as variants. Apps can request hosted assignment from Headband or assign locally with SDK helpers; search calls can include experimentKey, variant, and sessionId; Headband records search quality, variant views, clicks, and conversion events so the dashboard can compare outcome signals next to zero-result rate, latency, and advisory promote/rollback recommendations.
Engine A/B/C test
Split traffic across Meilisearch, Typesense, and Elasticsearch indexes for the same corpus.
Metrics: conversion, zero_result_rate, p95_latency_ms, reformulation_rate
Ranking rules test
Compare synonyms, typo tolerance, filters, and boosts without changing client code.
Metrics: click_through_rate, add_to_cart_rate, search_exit_rate
Hybrid/RAG quality test
Compare lexical, vector, and hybrid retrieval before rolling a RAG flow to everyone.
Metrics: answer_acceptance, grounding_failure, latency_ms
Experiment Event API
/v1/experiments/eventsRecord app-owned retrieval experiment views, clicks, conversions, or custom events under the project attached to an index.
Your app owns allocation and full-funnel attribution. Headband stores retrieval-specific events beside search quality metrics.
{
"eventType": "conversion",
"experimentKey": "engine-ab-test",
"variant": "typesense-products",
"indexUid": "products_typesense",
"sessionId": "sess_123",
"query": "trail shoes",
"conversionValue": 1299,
"metadata": { "orderId": "ord_123" }
}{
"data": {
"accepted": true,
"eventType": "conversion",
"experimentKey": "engine-ab-test",
"variant": "typesense-products",
"indexUid": "products_typesense"
}
}Managed Experiment Rules API
The authenticated dashboard stores rollout weights, status, and kill-switch flags for each project. Runtime code can request hosted assignment through /v1/experiments/assign, or mirror rules into local SDK assignment when offline or app-owned bucketing is required. The React SDK exposes assignExperiment for the hosted endpoint, getExperimentConfigs plus deterministic local assignment helpers, and recordExperimentEvent for outcome telemetry.
/api/projects/:projectId/experimentsStore a validated experiment rule set for a project. The latest config event per experimentKey is treated as the current rule.
Variant weights must add to 100. Use killSwitch=true to preserve a dashboard-managed stop flag for application rollout code.
{
"experimentKey": "engine-ab-test",
"name": "Products engine A/B/C test",
"status": "active",
"trafficPercent": 25,
"killSwitch": false,
"primaryMetric": "conversion_rate",
"guardrailMetric": "p95_latency_ms",
"variants": [
{ "key": "baseline", "indexUid": "products", "weight": 50 },
{ "key": "candidate", "indexUid": "products_typesense", "weight": 50 }
]
}{
"data": {
"experiment": {
"experimentKey": "engine-ab-test",
"status": "active",
"trafficPercent": 25,
"killSwitch": false
}
}
}/v1/experiments/config?indexUid=products&experimentKey=engine-ab-testRead current managed experiment rules with a search/admin key so runtime code can consume rollout weights and kill-switch state.
Project-scoped keys infer the project. Org-scoped keys must provide projectId or indexUid.
{
"data": {
"experiments": [
{
"experimentKey": "engine-ab-test",
"status": "active",
"trafficPercent": 25,
"killSwitch": false,
"variants": [
{ "key": "baseline", "indexUid": "products", "weight": 50 },
{ "key": "candidate", "indexUid": "products_typesense", "weight": 50 }
]
}
]
}
}/v1/experiments/assignAsk Headband to apply the latest active managed rule to a stable subject/session and return the selected variant/index.
Project-scoped keys infer the project. Org-scoped keys must provide projectId or indexUid. assigned=false is returned when a rule is paused, killed, outside rollout, or has no usable variant weight.
{
"indexUid": "products",
"experimentKey": "engine-ab-test",
"subjectId": "user_123",
"sessionId": "sess_123"
}{
"data": {
"assigned": true,
"experimentKey": "engine-ab-test",
"variant": "candidate",
"indexUid": "products_typesense",
"sessionId": "sess_123",
"config": {
"status": "active",
"trafficPercent": 25,
"killSwitch": false
}
}
}Connector Catalog API
/v1/connectorsReturn public framework, sync connector, and experiment recipe metadata. This endpoint exposes no tenant data or secrets.
Use this for docs automation, integration pages, and internal adoption checklists.
{
"data": {
"frameworks": [{ "slug": "nextjs-react", "status": "live" }],
"connectors": [{ "slug": "postgres", "status": "recipe" }],
"experiments": [{ "slug": "engine-ab-test", "status": "recipe" }]
}
}