Search API · PostgreSQL sync · Web console

Hosted search with an Elasticsearch-compatible API.

Index over REST or sync from PostgreSQL, then query with match, term, bool and range.

Get startedRead the API

POST/v1/movies/_search200 OK
Request

Authorization: ApiKey bsk_… Content-Type: application/json

{
  "query": {
    "match": { "title": "matrix reloaded" }
  },
  "size": 3
}
Response, hits.hits by _score

"total": { "value": 3, "relation": "eq" }

  1. { "_id": "2", "_score": 3.02, "_source": { "title": "The Matrix Reloaded", "year": 2003 } },
  2. { "_id": "1", "_score": 2.31, "_source": { "title": "The Matrix", "year": 1999 } },
  3. { "_id": "3", "_score": 1.74, "_source": { "title": "The Matrix Revolutions", "year": 2003 } },
Sample index and scores, for illustration. Add a word to the match clause and the order changes.

What you get

One API, one engine, one console.

  • Search API

    Create indexes, index documents one at a time or in bulk, and query them with match, term, bool and range clauses, sorting, pagination and aggregations.

    API reference
    POST /v1/movies/_search
    {
      "query": {
        "bool": {
          "must": [{ "match": { "title": "matrix" } }],
          "must_not": [{ "range": { "year": { "lt": 1990 } } }]
        }
      },
      "sort": [{ "year": { "order": "desc" } }],
      "size": 10
    }
  • PostgreSQL sync

    Point a job at a table or a SELECT. It polls for rows past a saved cursor and indexes them, and a scheduled resync can rebuild the index and swap it in.

    How sync works
    Sync articlesRunning

    public.articles → articles

    Total synced
    12,500
    Last cursor
    2026-01-01T00:00:00Z
    Errors
    0

    07:00:01 [info] polled public.articles, batch of 1000 rows

    07:00:01 [info] bulk indexed 1000 documents into articles

    07:00:02 [info] full batch returned, polling again

    07:00:03 [info] cursor saved

  • Web console

    Manage indexes, search documents in the Explorer, connect PostgreSQL databases, watch syncs, read search analytics and issue API keys from a browser.

    The console
    • Indices
    • Connections
    • Explorer
    • Analytics
    • API keys
    • Webhooks
  • Projects and keys

    Every project is isolated, with editor and viewer API keys, allowed origins for browser calls and its own prepaid credit balance.

    Roles and keys
    Backend servicebsk_a1b2c3…editorActive
    Search widgetbsk_d4e5f6…viewerActive

Your first search in three requests

Familiar Elasticsearch-style endpoints under /v1. Send Authorization: ApiKey bsk_…: the key selects its project, so no project header is needed, and it carries an editor or viewer role.

Base URL
https://api.boltsearch.app
Auth
Authorization: ApiKey bsk_…
Field types
text keyword integer float boolean date

Getting started · API reference

Request PUT /v1/{index}

curl -X PUT https://api.boltsearch.app/v1/movies \
  -H 'Authorization: ApiKey bsk_YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"mappings":{"properties":{
        "title":{"type":"text"},
        "year":{"type":"integer"},
        "genre":{"type":"keyword"}}}}'

Response

{
  "acknowledged": true,
  "index": "movies"
}

Request PUT /v1/{index}/_doc/{id}

curl -X PUT https://api.boltsearch.app/v1/movies/_doc/1 \
  -H 'Authorization: ApiKey bsk_YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"title":"The Matrix","year":1999,"genre":"sci-fi"}'

Response

{
  "_index": "movies",
  "_id": "1",
  "result": "created",
  "_version": 1
}

TypeScript

const client = new BoltSearchClient({
  baseUrl: 'https://api.boltsearch.app/v1',
  apiKey: process.env.BOLT_SEARCH_API_KEY,
})

const results = await client.search('movies', {
  query: { match: { title: 'matrix' } },
})

Install

No runtime dependencies: it uses native fetch (Node.js 18 or newer) and ships as ESM and CJS. An HTTP 402 arrives as a BoltSearchError. A Python SDK is also provided on request: from bolt_search import BoltSearch. Email support for SDK access.

How it works

One REST API in front of one search engine. The console and your code use the same calls.

The architecture and data flow

  • Each request is authenticated by key, resolved to a project and checked against the key’s role before it reaches the engine.
  • PostgreSQL rows reach the same index through a sync worker that polls your database.
  • Searches use credits. Indexing, sync and analytics do not.
Request path
  1. Callercurl, an SDK or the web consoleAuthorization: ApiKey bsk_…HTTPS
  2. REST APIauthenticate the keyresolve the project, check the rolecheck credits, prefix index namesgRPC
  3. Search engineparses the queryBM25 ranking, aggregationsreads
  4. Index filesone set per indexnamed with the project prefixkept on disk

Security and data handling

A few facts, described in full on the security page.

API keys
Shown once, stored only as SHA-256 hashes. Each key has one project and one role.
Isolation
Every project’s indexes are namespaced, and a key cannot manage projects, members or billing.
Your database
Sync jobs only run SELECT statements. The database password is write-only.
Payments
Card details are entered on Stripe-hosted checkout and never reach Techsstuff LLC.

Read about security

Pricing

Metered usage: every search attempt draws from prepaid credits, bought in packs from $10 to $210 USD. No subscription, and credits never expire. 1 credit = 10 search attempts. Above the $210 pack, contact sales.

Estimate your usage

Metered
Search, count and scroll requests
Not metered
Writes, indexing, sync and analytics
searches for $10
70,000
credits for $210
147,000
search attempts per credit
10
packs, no subscription
12

FAQ

Is it the same as Elasticsearch?

No. Bolt Search is a search engine built from scratch on Tantivy, with an Elasticsearch-compatible REST API. It supports a subset of the query language: match_all, match, term, bool and range, plus terms, metric and range aggregations.

Which databases can it sync from?

PostgreSQL. A sync job reads a table or a custom SELECT query and indexes every returned column. You can also push documents from any source with the REST API.

How does the sync know what is new?

You choose a cursor column that only increases, such as updated_at or an auto-increment id. Each poll fetches the rows beyond the saved cursor, and the cursor is saved after each successful batch.

Is there a client library?

Yes, a TypeScript SDK with no runtime dependencies and a Python SDK; email support for access. Any HTTP client works with the REST API.

How is usage counted?

Search, count and scroll requests are metered at 10 attempts per credit; an _msearch request counts one attempt per contained search. Writes, indexing, sync and analytics are not. See the pricing page for packs.

Create a project, make an API key and send your first search.

Get startedSee pricingTalk to us