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" }| Status | Meaning |
|---|---|
400 | The request isn't valid. The message says why. |
401 | The API key is missing or invalid. |
402 | A plan limit: records, indexes, or monthly searches. |
403 | The key lacks the scope or index, or the origin isn't allowed. |
404 | The index, or a staged replacement, doesn't exist. |
409 | A conflict, such as a record version that changed or another write during a staged replacement. |
415 | The request body isn't sent as application/json. |
429 | A public search rate limit: 240 a minute per visitor, 6,000 per index. Wait for the Retry-After seconds. |
5xx | A temporary problem. Retry with a backoff. |
Search
| Method | Path | Scope | |
|---|---|---|---|
POST | /search | search | Search the index. |
The body is a search request, with up to 100 hits a request, and the response is a search response.
Browser search
POST /api/public/indexes/{publicId}/searchBrowser 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
| Method | Path | Scope | Body |
|---|---|---|---|
POST | /records | write | { "records": [...] }: add or replace 1 to 1,000 records. |
PUT | /records | write | { "records": [...] }: replace the catalog with up to 100,000 records. |
DELETE | /records/{objectID} | write | |
GET | /records/{objectID} | either | |
POST | /record-writes | write | A 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:
| Method | Path | Body |
|---|---|---|
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
| Method | Path | Scope | |
|---|---|---|---|
GET | /config | either | The settings, with a change in progress in rebuild. |
PUT | /config | write | Save the full settings. The response adds applied, rebuilt, and rebuild. |
GET | /fields | search | Field paths in the index's records, with their types. |
GET | /indexing | either | { "acceptedRevision", "indexedRevision", "recordCount" } |
Browser search access
| Method | Path | Scope | |
|---|---|---|---|
GET | /public-access | write | { "publicId", "allowedOrigins", "policy" } |
PUT | /public-access/policy | write | { "policy": { ... } }: see Security. |
DELETE | /public-access/policy | write | Remove the policy. |
Indexes, API keys, and allowed origins are managed in the dashboard.