Developers

Build search into your product.

Create a project, make an API key and send your first request in a few minutes. This page is about the hosted service.

Quickstart

From nothing to a search result. Replace bsk_YOUR_API_KEY with your own key; the base URL for the hosted service is https://api.boltsearch.app.

  1. Create an account. Sign up or sign in at the Bolt Search app, with an email and password or with Google. Signing up creates your account and a project that you own.
  2. Add credits. Searches use credits, and a new project has none, so search requests answer HTTP 402 until you buy a pack from the project’s Billing page. Creating indexes and indexing documents work without credits. See pricing.
  3. Create an API key. In the project, open Settings, then API Keys, choose a name and a role, editor to write and search or viewer to search only, and copy the key. It is shown once.
  4. Create an index. Declare your fields and their types. fast on a keyword makes it available for aggregations.

    Request

    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", "fast": true }
          }
        }
      }'

    Response

    HTTP 200
    {
      "acknowledged": true,
      "index": "movies"
    }
  5. Index a document. The id in the path is yours to choose. Indexing the same id again replaces the document.

    Request

    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

    HTTP 201
    {
      "_index": "movies",
      "_id": "1",
      "result": "created",
      "_version": 1
    }
  6. Search. The first hit is the best match by BM25 score.

    Request

    curl -X POST https://api.boltsearch.app/v1/movies/_search \
      -H 'Authorization: ApiKey bsk_YOUR_API_KEY' \
      -H 'Content-Type: application/json' \
      -d '{
        "query": { "match": { "title": "matrix" } },
        "size": 10
      }'

    Response

    HTTP 200
    {
      "took": 2,
      "hits": {
        "total": { "value": 1, "relation": "eq" },
        "hits": [{
          "_index": "movies",
          "_id": "1",
          "_score": 1.0,
          "_source": { "title": "The Matrix", "year": 1999, "genre": "sci-fi" }
        }]
      }
    }

Every endpoint, query clause and aggregation is in the API reference. To keep a PostgreSQL table searchable without writing indexing code, see PostgreSQL sync.

Authentication

Send the key in the Authorization header on every request.

Authorization: ApiKey bsk_a1b2c3d4e5f6…
  • A key is scoped to one project and carries a role, viewer or editor. It cannot be an owner. Because the key selects the project, you send no project header.
  • Keys cannot create or delete projects, change members or manage keys and billing. Those actions need a signed-in user in the web console.
  • The console itself uses a user’s access token, which expires after 15 minutes by default, together with an X-Project-ID header. Programs should use API keys.
  • Only the SHA-256 hash of a key is stored, so a lost key cannot be shown again. Create a new one and revoke the old one.
RoleCan
viewerSearch, count, get documents and indexes, list indexes, read sync jobs and analytics.
editorEverything a viewer can, plus create and delete indexes, index, delete and bulk documents, manage data sources and sync jobs, and record clicks.

TypeScript SDK

A typed client with no runtime dependencies. It uses the built-in fetch of Node.js 18 or newer and ships as both ES modules and CommonJS. Any HTTP client works with the REST API too.

TypeScript

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

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

Notes

baseUrl is the API base URL and defaults to https://api.boltsearch.app/v1; the SDK appends paths such as /movies/_search. Keep the key on the server.

The Python SDK is provided on request too: from bolt_search import BoltSearch, then BoltSearch(api_key=…). Its default base URL is https://api.boltsearch.app/v1.

SDK access is provided on request: email support@techsstuff.com.

  • Groups: indices, documents, bulk, cluster and analytics, plus search, count, scroll and clearScroll on the client.
  • retries defaults to 0 and retryDelay to one second, with exponential back-off and jitter. Only connection errors and 5xx responses are retried, never a 402. A retry is a new attempt for metering.
  • timeout defaults to 30 seconds. onRequest and onResponse hooks help with logging.
Error classHTTP statusWhen thrown
ValidationError400Invalid body or parameters
NotFoundError404Index or document does not exist
ConflictError409Index already exists
ConnectionError—Server unreachable or request timed out
BoltSearchErrorAny otherBase class; statusCode 402 means credits are exhausted or billing is suspended

Errors and status codes

Errors use the Elasticsearch shape, so existing error handling for it carries over.

Example error

HTTP 403
{
  "error": {
    "status": 403,
    "type": "security_exception",
    "reason": "insufficient project permissions"
  },
  "status": 403
}

Notes

Read error.type to decide what to do and error.reason to log. A request id is returned in the X-Request-ID header: include it when you contact support.

StatusTypeWhenSDK error
400parse_exceptionThe body is not valid JSON, or a search body could not be parsed.ValidationError
400illegal_argument_exceptionsize or from is above 10,000, a multi-index search names more than 20 indexes, or the engine rejected an argument.ValidationError
400invalid_index_name_exceptionThe index name contains __, which is reserved.ValidationError
400validation_exceptionA required field of a data source or sync job is missing or invalid, including a custom query the service refuses.ValidationError
401security_exceptionThe key is missing, unknown or revoked.BoltSearchError
402insufficient_credits or billing_suspendedA search, count or scroll request on a project without credits, or whose billing is suspended. A project that has never bought credits gets insufficient_credits.BoltSearchError, never retried
403security_exceptionThe key’s role is too low for the endpoint, for example a viewer key that indexes a document.BoltSearchError
404resource_not_found_exceptionThe index, document, data source or sync job does not exist in this project.NotFoundError
409resource_already_exists_exceptionThe index already exists. Resetting a sync job that is not stopped answers 409 with illegal_state_exception.ConflictError
503billing_unavailable or unavailable_exceptionBilling could not be checked for a metered request, or the search engine was unavailable.BoltSearchError, retried if retries are set

Sign-in and account endpoints are rate limited per IP address and answer 429 with the code RATE_LIMITED. Those endpoints are used by the console, not by API keys.

Limits

Search request body
10 MB
Single document body
10 MB
Bulk request body
50 MB
from and size on a search
10,000 each
Indexes in one multi-index search
20, comma separated: /v1/movies,books/_search
Index name
Must not contain __
Analytics page size
size defaults to 20 and is capped at 1,000; the range defaults to the last 7 days

Searching is limited by your credits. See how long data is kept.

Usage and credits

Search, count and scroll requests are metered at 10 attempts per credit, and an _msearch request counts one attempt per contained search. Everything else is free to call.

  • A multi-index search is one attempt. A request that fails after it was admitted still counts, and so does every retry you send.
  • Without credits, a metered request answers HTTP 402 and the SDK does not retry it. Add credits on the project’s Billing page and searches work again.
  • Writes, indexing, PostgreSQL sync, analytics and index administration are not metered. Clearing a scroll is free.
  • A search from the console’s Explorer is a normal attempt, even when it finds nothing.

Pricing and the estimator · How metering works

Calling from a browser

A page on another website can call your project directly only if its origin is listed.

  • Settings, Allowed Origins lists the websites that may call the project from a browser. An empty list allows same-origin requests only.
  • Browsers may send Accept, Authorization, Content-Type, X-Request-ID, X-Project-ID and Idempotency-Key, with GET, POST, PUT, DELETE and OPTIONS.
  • Anyone who loads the page can read a key that is placed in it. For a public search box, use a viewer key and keep writes on your server.

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

Get startedSee pricing