# STELQ Search API

Live web search on every request — never cached, never stale. Send a query, get back ranked results with titles, URLs and snippets. Synchronous: one request, one response.

- **Endpoint:** `POST https://api.stelq.com/v1/search/query`
- **Auth:** `Authorization: Bearer $STELQ_KEY`
- **Price:** $0.001 / query
- **Mode:** synchronous
- **Canonical URL:** https://stelq.com/api/docs/search (public, no auth, always current)

## Authentication

Every request needs a bearer token: `Authorization: Bearer $STELQ_KEY`. Create and scope keys in the console under API Keys — the secret is shown once. In the in-console Playground the key is injected for you; copied payloads reference the `$STELQ_KEY` environment variable, so set it in your agent's environment instead of pasting a live secret into a prompt.

## Request

`POST /v1/search/query`

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `query` | string | yes | The search query. Or send `queries` (an array of strings) for a batched multi-query search. |
| `limit` | integer | no | Results to return, 1–50 (default 10). Values over 50 are clamped — an X-Result-Limit-Applied header reports the value used. |
| `search_mode` | enum | no | One of auto, web, news, academic (default auto). |
| `freshness_days` | integer | no | Only results from the last N days. Omit or 0 for no recency filter. |
| `preferred_domains` | string[] | no | Bias results toward these domains. |
| `excluded_domains` | string[] | no | Drop results from these domains. |

```json
{
  "query": "best ai search infra 2026",
  "limit": 10,
  "search_mode": "auto"
}
```

## Response

```json
{
  "query": "best ai search infra 2026",
  "count": 10,
  "results": [
    {
      "title": "Building AI-native search in 2026",
      "url": "https://example.com/ai-search",
      "snippet": "An overview of live-index search infrastructure…",
      "published": "2026-05-31"
    }
  ]
}
```

## Errors

| Status | Meaning |
| --- | --- |
| 400 | Invalid request — a field is missing or malformed (the body says which). |
| 401 | Missing or invalid API key. |
| 402 | Insufficient balance — top up credits to continue. |
| 429 | Rate limited — back off and retry after the Retry-After header. |
| 502 | Upstream temporarily unavailable — safe to retry; not charged. |

## Rate limits

Up to 50 requests/second per key. 429 with a Retry-After header when exceeded.
