App Search

App Search is in beta with design partners. Endpoints roll out per tenant.

Captain App Search powers the search box inside an application or website: product search on a store, listing search on a marketplace, article search on a help center, or record search inside a SaaS product.

Captain File Search is a separate product for files and their contents. It uses collections, documents and chunks. App Search uses indexes and records.

Vocabulary

TermMeaning
TenantOne customer’s dedicated App Search deployment, with its own endpoint.
IndexA searchable set of records, such as products, stores or articles.
RecordOne product, article, listing or other entity in an index.
Query, filter, facetThe usual search terms: the text searched, the conditions every result must meet, and the counts per field value.

How a request finds its data

Each customer gets a dedicated deployment and a dedicated hostname, for example https://acme.captain.dev.

  • The hostname selects the tenant.
  • The path selects the index: /v1/indexes/products/search.
  • The key grants access to that tenant’s indexes and operations.

Requests carry no tenant id, and there is no /tenants/... path. Two tenants may each have an index called products. A key issued for one tenant does not work against another tenant’s endpoint.

What Captain manages

Captain creates each tenant and its keys, and tunes ranking and index settings with the customer. The customer’s application creates indexes, keeps their records up to date, searches, and sends click and conversion events. Keys lists which key calls which operation.

Endpoint

Onboarding provides two things: the tenant endpoint, for example https://acme.captain.dev, and the keys for this tenant. The Quickstart creates a first index from there.

Every App Search route sits under that endpoint:

https://acme.captain.dev/v1/indexes/products/search
https://acme.captain.dev/v1/indexes/articles/search

Keys

KeyUse it forWhere it lives
Search keySearching, reading records, sending events and reading analytics.Safe in a browser or mobile app.
Scoped keySearching on behalf of one end user, when an index has per-record access control. Minted from an issuer key and short lived.Safe in a browser, once minted.
Write keyCreating indexes, adding, updating and deleting records, importing, and reading import jobs. It cannot search.Server side only.

Captain issues every key at onboarding and keeps the admin key. Deleting indexes, changing ranking or index settings, and issuing or revoking keys go through Captain.

Which key calls which operation

OperationSearch keyScoped keyWrite key
Search, typeahead, browse, similar, multiple searchesYesYesNo
Get recordsYesYesNo
List filtersYesYesNo
Send eventsYesYesNo
Read analyticsYesNoNo
Create an indexNoNoYes
Add, replace, update and delete recordsNoNoYes
Get an index’s status and update statusNoNoYes
Import from Algolia, and get its jobNoNoYes

A tenant’s keys work on every index in that tenant, including indexes created later. A key can also be limited to some indexes. A request for any other index returns 403, the same answer as for an index that does not exist.

Sending the key

Every endpoint takes its key the same way, as a bearer token in the Authorization header. Each endpoint’s reference page names the kind of key it needs.

curl -X POST "https://acme.captain.dev/v1/indexes/products/search" \
-H "Authorization: Bearer $CAPTAIN_SEARCH_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "waterproof hiking boots",
"k": 3
}'

A missing or unknown key returns 401. A key without access to the index or operation returns 403, and so does an index the key cannot see, whether or not that index exists.

Errors

Every error reply has the same shape: a machine code in error and a readable message.

{"error": "FILTER_INVALID", "message": "filter: unknown field colour", "position": 0, "expected": ["brand", "color", "price"]}
StatusCommon codesMeaning
400VALIDATION_ERROR, FILTER_INVALID, FACET_UNKNOWN, PAGE_TOO_DEEPThe request is malformed or names something the index lacks.
401UNAUTHORIZEDThe key is missing or unknown.
403FORBIDDEN, ACCESS_DENIEDThe key may not use this index or operation.
404DOCUMENT_NOT_FOUND, JOB_NOT_FOUNDThe record or job does not exist.
409INDEX_EXISTS, JOB_RUNNING, INDEX_NOT_READY, IDEMPOTENCY_KEY_REUSEDAn index with that name already exists, an import is already running, the index has no records yet, or an idempotency key was reused with a different body.
413PAYLOAD_TOO_LARGEThe request body is too large.
429RATE_LIMITEDToo many requests for this key. Retry after the time in Retry-After.
503UNAVAILABLEThe service is briefly unavailable. Retry with backoff.

Limits

LimitValue
Records per add request1,000 as a JSON array, 100,000 as NDJSON or CSV
Records per update or delete request1,000
Records per get request100
Events per request1,000
Searches per multi-search request10

Machine-readable guides

Each tenant publishes its own reference:

https://acme.captain.dev/v1/openapi.json
https://acme.captain.dev/llms.txt

llms.txt is a short plain-text guide for coding assistants. Both reflect the version deployed on that tenant.

Next steps

© 2026 Captain