SemiLayerDocs

REST API Reference

The SemiLayer REST API is available at https://api.semilayer.com. All endpoints accept and return JSON. Authentication is via API key in the Authorization header.

Authentication

Authorization: Bearer {apiKey}

Use sk_ keys for server-side calls. Use pk_ keys for client-side calls — they enforce Lens access rules.

For per-user access control, also pass the user JWT:

X-User-Token: {userJwt}

Base URL

https://api.semilayer.com

Search the vector index for a given query. Does not hit your source database.

POST /v1/search/:lens

Request Body

FieldTypeRequiredDescription
querystringSearch query
limitnumberMax results. Default: 10
minScorenumberMinimum similarity score (0-1). Default: 0
modestringsemantic | keyword | hybrid. Default: lens config then semantic

Response

{
  "results": [
    {
      "id": "emb_abc123",
      "sourceRowId": "42",
      "content": "Lightweight running shoe with responsive foam ...",
      "metadata": { "id": 42, "name": "Air Glide 3", "category": "footwear", "price": 89.99 },
      "score": 0.94
    }
  ],
  "meta": {
    "lens": "products",
    "query": "lightweight running shoes",
    "mode": "semantic",
    "count": 10,
    "durationMs": 18
  }
}

Example

curl -X POST https://api.semilayer.com/v1/search/products \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"query":"lightweight running shoes","limit":10,"mode":"hybrid"}'

Similar

Find records similar to a given record using its stored vector.

POST /v1/similar/:lens

Request Body

FieldTypeRequiredDescription
idstringSource record primary key (as string)
limitnumberMax results. Default: 10
minScorenumberMinimum similarity score. Default: 0

Response

Same shape as Search: { results: SearchResult[], meta: {...} }

Example

curl -X POST https://api.semilayer.com/v1/similar/products \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"id":"42","limit":5}'

Query

Read directly from your source database through the Bridge.

⚠️

Must be explicitly enabled in the Lens config with rules.query. Returns 403 Forbidden if not enabled.

POST /v1/query/:lens

Request Body

FieldTypeRequiredDescription
whereobjectEquality filters. Keys are output field names
orderByobject | array{ field, dir? } or array of same
limitnumberDefault: 100
offsetnumberRow offset
cursorstringOpaque pagination cursor from previous response
selectstring[]Field names to include in response

Response

{
  "rows": [
    { "id": 42, "name": "Air Glide 3", "category": "footwear", "price": 89.99 }
  ],
  "meta": {
    "lens": "products",
    "total": 142,
    "nextCursor": "eyJpZCI6NTB9",
    "count": 20,
    "durationMs": 12
  }
}

Example

curl -X POST https://api.semilayer.com/v1/query/products \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "where": { "category": "footwear" },
    "orderBy": { "field": "price", "dir": "asc" },
    "limit": 20
  }'

Paginate with cursor:

curl -X POST https://api.semilayer.com/v1/query/products \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "where": { "category": "footwear" },
    "orderBy": { "field": "price", "dir": "asc" },
    "limit": 20,
    "cursor": "eyJpZCI6NTB9"
  }'

Ingest Webhook

Trigger an ingest job from your application. Use an ik_ key.

POST /v1/ingest/:lens

Request Body

FieldTypeRequiredDescription
modestringincremental | full | records

Mode incremental — time-windowed sync using changeTrackingColumn:

{ "mode": "incremental" }

Mode full — re-index all records from scratch:

{ "mode": "full" }

Mode records — sync specific records:

{
  "mode": "records",
  "changes": [
    { "action": "upsert", "id": "42" },
    { "action": "delete", "id": "17" }
  ]
}

Response

{
  "jobId": "job_abc123",
  "status": "queued",
  "lens": "products",
  "mode": "incremental"
}

Example

curl -X POST https://api.semilayer.com/v1/ingest/products \
  -H "Authorization: Bearer ik_live_..." \
  -H "Content-Type: application/json" \
  -d '{"mode":"incremental"}'

Error Responses

All errors return a JSON body with an error field:

{ "error": "Access denied by lens rules" }
StatusWhen
400Invalid request body
401Missing or invalid API key
403Key does not have permission for this operation
404Lens not found
429Rate limit exceeded (SaaS only) — Retry-After header included
502Embedding provider error

Streaming (WebSocket)

See HTTP & WebSocket for the full WebSocket protocol reference, including connection setup, op frames, event frames, heartbeat handling, and close codes.

GET wss://api.semilayer.com/v1/stream/:lens?key={apiKey}&userToken={userJwt}