# REST API reference

The native API lives under `/v1` at `https://api.warpsearch.io`. The complete, machine-readable
description is the OpenAPI document at
[https://api.warpsearch.io/v1/openapi.yaml](https://api.warpsearch.io/v1/openapi.yaml). This page
is the short version.

## Authentication

Every request authenticates. Nothing is served anonymously. Send your API key (`ws_live_...`) in
any of these forms:

| Form | Example |
| --- | --- |
| Bearer token | `Authorization: Bearer ws_live_...` |
| Key header | `X-API-Key: ws_live_...` |
| ApiKey scheme | `Authorization: ApiKey ws_live_...` |
| HTTP Basic | the key as the password, with any username |

Elasticsearch clients can also send their base64 `id:secret` form. Roles are monitor, read, write
and admin, and a key sees only the collections it holds a role on. See
[Access control](access-control.md). `GET /v1/auth/me` shows who you are and what you may do.

## Routes

| Method and path | Role | Purpose |
| --- | --- | --- |
| `POST /v1/collections/{collection}/search` | read | Search a collection. Add `?format=es` for an Elasticsearch-shaped response. |
| `GET /v1/collections/{collection}/search` | read | Quick search with `q`, `limit`, `offset`, `sort` and `fields`. |
| `POST /v1/search` | read | Search where the collection comes from the body, or from `FROM` in SQL. |
| `POST /v1/translate` | read | Show the native form of a query without running it. |
| `POST /v1/collections/{collection}/count` | read | Count matching documents. |
| `GET /v1/collections` | monitor | List the collections you can access. |
| `PUT /v1/collections/{collection}` | admin, plus permission to create collections | Create a collection, with an optional mapping, description and metadata. |
| `GET /v1/collections/{collection}` | monitor | Describe a collection and its fields. |
| `PATCH /v1/collections/{collection}` | admin | Change the description and metadata. |
| `DELETE /v1/collections/{collection}` | admin | Delete a collection and its documents. |
| `PUT /v1/collections/{collection}/mapping` | admin | Add or replace field definitions. |
| `POST /v1/collections/{collection}/refresh` | write | Make pending writes searchable. |
| `POST /v1/collections/{collection}/documents` | write | Index documents (JSON array, `{"docs": [...]}` or NDJSON). Add `?commit=true` to search them right away. |
| `GET /v1/collections/{collection}/documents/{id}` | read | Get one document. |
| `DELETE /v1/collections/{collection}/documents/{id}` | write | Delete one document. |
| `POST /v1/collections/{collection}/documents/_delete` | write | Delete several documents by id. |
| `GET /v1/usage` | needs the view usage permission | Your usage counters and plan limits. |
| `GET /v1/auth/me` | any | The caller, its permissions and its role on each collection. |

A search request names its `language` (`sql`, `es`, `lucene`, `grafana`, `logql`, `luxir` or
`solr`) and carries the `query`, plus optional `filters`, `facets`, `metrics`, `sort`, `limit`,
`offset`, `fields` and `time_range`. See [Searching](searching.md) and
[Query languages](query-languages.md).

## Conventions

- **Strict JSON.** Request bodies are decoded strictly, so an unknown field is rejected instead
  of ignored. Collection names start with a lowercase letter and contain only lowercase letters,
  digits and `_`.
- **Errors.** Failures use RFC 9457 `application/problem+json` bodies with `type`, `title`,
  `status`, `detail`, a stable machine-readable `code` and a `request_id`. Branch on `code`, not
  on the text. See [Limits and errors](limits-and-errors.md).
- **Request IDs.** Every response carries an `X-Request-Id`. Send your own to have it kept.
  Quote it when you [contact us](/contact).
- **Rate limits.** A rate-limited or overloaded request answers `429` with a `Retry-After`
  header. Wait that long before retrying. A collection that is loading answers `503` with
  `Retry-After` too.
- **Warnings.** When a query is approximated or part of it is ignored, the response carries a
  `Warning: 299` header, and `/v1` responses also list the messages in `warnings`.
- **Partial indexing.** An ingest request where some documents fail answers `207`, with the
  failures listed in `errors`.

## Compatible APIs and agents

The same key works on the compatible APIs, so existing clients keep working:

- [Elasticsearch](compat-elasticsearch.md) at `/compat/es`
- [OpenSearch](compat-opensearch.md) at `/compat/opensearch`
- [Solr](compat-solr.md) at `/compat/solr`
- [Loki and LogQL](compat-loki-logql.md)

Agents connect to the MCP server at `https://api.warpsearch.io/mcp`. See the
[Guide for AI agents](agents.md).
