Using Your API

Once you have created an API, defined your models, set up endpoints, and deployed the API version, you can start making requests. All requests go to a subdomain-based URL and require an API key in the header.

Base URL

Every request targets a specific endpoint within an API version:

https://{subdomain}.searchapi.net/{api-name}/{version}/{endpoint-path}
  • {subdomain} — your company subdomain, set during company setup
  • {api-name} — the API slug (e.g. catalog)
  • {version} — the API version (e.g. v1)
  • {endpoint-path} — the path configured for the endpoint (e.g. products)

Example:

https://acme.searchapi.net/catalog/v1/products

Authentication

Every request must include an X-API-KEY header. API keys are scoped per endpoint type — a key may allow GET but not POST. Requests with a missing or invalid key are rejected.

X-API-KEY: your-api-key-here
HTTP Status Cause
401 X-API-KEY header is missing
403 Key exists but does not have permission for this request type
422 The endpoint type (e.g. POST) was not enabled for this model

Response Format

All responses follow a consistent JSON envelope:

{
  "status": "success" | "error" | "warning",
  "type":   "ok" | "created" | "no_content" | "bad_request" | ...,
  "code":   200,
  "message": "...",
  "data":   { ... }
}

The type field gives a machine-readable classification. The data field is present only when there is a payload to return.

Endpoints

GET — List / Search

GET https://{subdomain}.searchapi.net/{api}/{version}/{endpoint-path}

Returns a paginated list of documents. Supports full-text search, field filtering, and sorting.

Query parameters

Parameter Description
q Full-text search across all searchable fields. Max 200 characters. When q is set, field filters are ignored.
sort Sort by a field. Prefix with - for descending. Example: sort=-created_at. Nested and object fields are not sortable.
{field}={value} Filter by exact field value. Multiple filters are combined with AND. Example: ?status=active&category_id=5

Range filters — for numeric and date fields use bracket notation with from / to:

?price[from]=10&price[to]=50
?created_at[from]=2024-01-01&created_at[to]=2024-12-31

Object field filters — pass a JSON object; each key filters the matching sub-field:

?address={"city":"New York"}
?address={"city":"New York","zip":"10001"}

Nested field filters — pass a JSON string or pipe-delimited JSON objects:

?tags=[{"id":1}]
?tags={"id":1}|{"id":5}

GET — Fetch by ID

GET https://{subdomain}.searchapi.net/{api}/{version}/{endpoint-path}/{id}

Returns a single document by its primary key. Returns 404 if not found.

POST — Create Document

POST https://{subdomain}.searchapi.net/{api}/{version}/{endpoint-path}
Content-Type: application/json

Creates a new document. The request body must be a JSON object. Required fields must be present and non-empty. Returns 201 Created with the created document, or 409 Conflict if a document with the same primary key already exists.

Relational fields (object / nested)

For fields that reference another model, send an object containing only the primary key. The API looks up the related document and embeds it automatically — including all configured visible fields.

Field type Send Example
Object (single relation) Object with primary key only "category": {"id": 5}
Nested (multiple relations) Array of objects, each with primary key only "tags": [{"id": 1}, {"id": 3}]

Extra fields beyond the primary key are silently ignored — no error is returned, but any additional data you include is discarded. The stored value is always replaced with what the API fetches from the related index.

Date field formats

Field type Expected format Example
Date YYYY-MM-DD 2025-06-15
Date + Time YYYY-MM-DDTHH:MM:SS 2025-06-15T14:30:00

PUT — Full Update

PUT https://{subdomain}.searchapi.net/{api}/{version}/{endpoint-path}/{id}
Content-Type: application/json

Replaces an existing document. The request body must be a JSON object. Required fields must be present. Returns 201 with the updated document, or 404 if the document does not exist.

Update confirmation for relational fields

If the record is referenced by other models and the update touches a field that is embedded in those models, the API requires explicit confirmation before applying the change.

1

Send the PUT request normally

If confirmation is needed, the API returns 409 with type: "confirmation_required", a one-time token, and a list of affected models and record counts.

{
  "status": "warning",
  "type": "confirmation_required",
  "code": 409,
  "message": "Update requires confirmation because this record is referenced by existing models.",
  "meta": {
    "update_confirmation_token": "abc123...",
    "impact": [
      { "modelName": "products", "count": 42 }
    ]
  }
}
2

Re-send with the confirmation token

Re-send the exact same request body — every field name and value must be identical to the first request. Only add update_confirmation_token; do not change anything else. The API hashes the payload to detect tampering; any modification invalidates the token.

{
  "id": 5,
  "name": "Sports",
  "slug": "sports",
  "update_confirmation_token": "abc123..."
}

Field order does not matter — the API normalises field order before comparing. Only the values are checked.

The token is single-use and expires after a short time. If the token is invalid, expired, or any field value differs from the first request, the API returns 410 Gone. Re-send the original PUT without a token to get a fresh token. If the document is already being updated by another request, a 409 Conflict with type: "conflict" is returned — retry after a moment.

PATCH — Partial Update

PATCH https://{subdomain}.searchapi.net/{api}/{version}/{endpoint-path}/{id}
Content-Type: application/json

Updates only the fields included in the request body. The request body must be a JSON object. Fields omitted from the body are left unchanged. Returns 201 with the updated document, or 404 if the document does not exist.

If the patched fields include a relational field that is embedded in other models, PATCH triggers the same confirmation flow as PUT. Re-send the same partial body with update_confirmation_token added.

DELETE — Remove Document

DELETE https://{subdomain}.searchapi.net/{api}/{version}/{endpoint-path}/{id}

Deletes a document by its primary key. Returns 204 No Content on success, 404 if not found. If the document is currently referenced by other documents, the delete is rejected with 422 and a list of the models that hold references.

Error Reference

Code type When it happens
400bad_requestMalformed request, type mismatch, invalid sort field
401unauthorizedX-API-KEY header missing
403forbiddenKey does not have permission for this request type
404not_foundDocument or index not found
409confirmation_requiredPUT touches relational fields — confirmation token required
409conflictDocument locked (another update in progress) or primary key already exists (POST)
410goneConfirmation token expired, invalid, or payload changed
422validation_errorRequired fields missing/empty, endpoint type not enabled, document referenced on DELETE
503service_unavailableElasticsearch cluster unreachable, or authentication to the cluster failed (invalid credentials or API key)