Reference

HTTP API

Every endpoint the SDKs use, for calling Findlane from any language.

Requests

The API is at https://api.findlane.dev. Requests and responses are JSON: send Content-Type: application/json with every request body.

Index endpoints are under the workspace and index:

/api/teams/{workspaceId}/indexes/{index}

Authenticate with an API key as a bearer token:

API=https://api.findlane.dev
curl "$API/api/teams/$FINDLANE_WORKSPACE_ID/indexes/products/search" \
  -H "Authorization: Bearer $FINDLANE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "q": "trail shoe", "facets": ["brand.name"], "limit": 10 }'

Errors

Failed requests answer with an HTTP status and a message:

{ "error": "Filter field color is not configured" }
StatusMeaning
400The request isn't valid. The message says why.
401The API key is missing or invalid.
402A plan limit: records, indexes, or monthly searches.
403The key lacks the scope or index, or the origin isn't allowed.
404The index, or a staged replacement, doesn't exist.
409A conflict, such as a record version that changed or another write during a staged replacement.
415The request body isn't sent as application/json.
429A public search rate limit: 240 a minute per visitor, 6,000 per index. Wait for the Retry-After seconds.
5xxA temporary problem. Retry with a backoff.
MethodPathScope
POST/searchsearchSearch the index.

The body is a search request, with up to 100 hits a request, and the response is a search response.

POST /api/public/indexes/{publicId}/search

Browser search needs no key. It answers only requests whose Origin header is one of the index's allowed origins, returns up to 50 hits a request, and follows the index's public search policy. It supports CORS, so browsers call it directly.

Records

MethodPathScopeBody
POST/recordswrite{ "records": [...] }: add or replace 1 to 1,000 records.
PUT/recordswrite{ "records": [...] }: replace the catalog with up to 100,000 records.
DELETE/records/{objectID}write
GET/records/{objectID}either
POST/record-writeswriteA conditional write, below.

Writes answer 202 with a receipt, and are searchable when they do:

{ "acceptedRevision": 42, "indexedRevision": 42, "recordCount": 18230 }

GET /records/{objectID} answers { "objectID", "version", "record" }, where record is null if the record doesn't exist.

Conditional writes

{
  "operation": "upsert",
  "objectID": "sku-1042",
  "record": { "objectID": "sku-1042", "title": "Trail running shoe", "price": 119 },
  "expectedVersion": 3,
  "idempotencyKey": "price-update-8f14e45f"
}

The write applies only if the record's version is expectedVersion (0 for a record that doesn't exist), and answers 409 otherwise. operation is upsert or delete; a delete has no record. Repeating a request with the same idempotencyKey (1 to 64 letters, digits, _, or -) returns the first receipt instead of writing again.

Staged replacements

A staged replacement uploads a catalog in batches and switches the index to it in one commit. stageId and batchId are 1 to 64 letters, digits, _, or -.

The paths are under /staged-replacements/{stageId}, and need the write scope:

MethodPathBody
POST/staged-replacements/{stageId}Start the stage, or get its status.
POST…/batches/{batchId}{ "records": [...] }: 1 to 1,000 records.
POST…/commit{ "expectedBatches": 12, "expectedRecords": 11408 }
DELETE/staged-replacements/{stageId}Abort the stage.

Uploading a batch again with the same records has no effect; with different records it fails with 409. The commit checks the batch and record counts, and fails with 409 if other writes reached the index since the stage started. Committing again returns the first receipt.

Settings

MethodPathScope
GET/configeitherThe settings, with a change in progress in rebuild.
PUT/configwriteSave the full settings. The response adds applied, rebuilt, and rebuild.
GET/fieldssearchField paths in the index's records, with their types.
GET/indexingeither{ "acceptedRevision", "indexedRevision", "recordCount" }

Browser search access

MethodPathScope
GET/public-accesswrite{ "publicId", "allowedOrigins", "policy" }
PUT/public-access/policywrite{ "policy": { ... } }: see Security.
DELETE/public-access/policywriteRemove the policy.

Indexes, API keys, and allowed origins are managed in the dashboard.