Web Search API
Operator-gated public web search. Chat uses these endpoints for Auto / Web answer modes. The deployment gate is WEB_SEARCH_ENABLED (default false). See Chat.
Both routes require a valid X-API-Key from API_KEY_CLIENTS. Responses set Cache-Control: private, no-store.
Capabilities
GET /web-search/capabilities
Reports the deployment gate without running a search.
Headers
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Valid API key from API_KEY_CLIENTS |
Response
{
"enabled": false
}
| Field | Description |
|---|---|
enabled | true when WEB_SEARCH_ENABLED=true |
curl http://localhost:8000/web-search/capabilities \
-H "X-API-Key: super-secret-key"
Search
POST /web-search
Runs one exact-query public web search. Unknown body fields are rejected.
Headers
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Valid API key from API_KEY_CLIENTS |
Content-Type | Yes | application/json |
Body
| Field | Type | Default | Description |
|---|---|---|---|
query | string | required | Exact query sent verbatim to the public provider (1–500 characters, not blank) |
limit | int | 5 | Maximum results to return (1–5) |
Response
{
"results": [
{
"source": "web",
"title": "Example title",
"url": "https://example.com/page",
"snippet": "Short excerpt from the page.",
"rank": 1
}
],
"meta": {
"provider": "ddgs",
"status": "ok",
"count": 1,
"query_time_ms": 42
}
}
| Result field | Description |
|---|---|
source | Always "web" |
title | Result title |
url | Result URL |
snippet | Short excerpt |
rank | 1-based rank |
meta.status | Meaning |
|---|---|
ok | Provider returned results |
no_results | Provider succeeded with an empty set |
timeout | Provider timed out |
rate_limited | Provider rate-limited the request |
unavailable | Gate off, provider missing, or service unavailable |
provider_error | Provider failed |
Fail-open: a disabled gate, missing provider, provider error, or timeout still returns HTTP 200 with results: [] and a non-ok meta.status. Chat can then keep a document-backed answer instead of erroring.
curl -X POST http://localhost:8000/web-search \
-H "X-API-Key: super-secret-key" \
-H "Content-Type: application/json" \
-d '{"query": "acme earnings", "limit": 5}'
Status codes
| Code | Description |
|---|---|
| 200 | Search or capabilities result (including fail-open empty results) |
| 401 | Missing or invalid API key |
| 422 | Invalid body (blank query, extra fields, limit out of range) |
| 429 | API rate limit exceeded |
When WEB_SEARCH_ENABLED=false, POST /web-search does not call the provider. It returns 200 with empty results and meta.status: "unavailable".