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.
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 }
]
}
}
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 |
|---|---|---|
400 | bad_request | Malformed request, type mismatch, invalid sort field |
401 | unauthorized | X-API-KEY header missing |
403 | forbidden | Key does not have permission for this request type |
404 | not_found | Document or index not found |
409 | confirmation_required | PUT touches relational fields — confirmation token required |
409 | conflict | Document locked (another update in progress) or primary key already exists (POST) |
410 | gone | Confirmation token expired, invalid, or payload changed |
422 | validation_error | Required fields missing/empty, endpoint type not enabled, document referenced on DELETE |
503 | service_unavailable | Elasticsearch cluster unreachable, or authentication to the cluster failed (invalid credentials or API key) |