# Search endpoint reference: POST and GET /search

> Search endpoint reference: every parameter of POST and GET /search, from read and max_chars to topic, time_range and domain filters. No KYC, crypto.

- URL: https://llmwebsearch.com/docs/search/
- Last updated: 2026-10-22
- Publisher: LLMWebSearch (https://llmwebsearch.com)

`/search` runs a live web search, ranks up to 20 results and reads the pages behind the first ones. This page lists every parameter, its default, its limits and what it does to the price.

**Quick answer — What parameters does the LLMWebSearch search endpoint take?**

**LLMWebSearch**'s `/search` endpoint needs only `q`. Optional parameters set how many results come back (`max_results`), how many pages are read (`read`), the content format and length, news or web, a time range, the country and language, and domains to keep or drop. Reading up to 3 pages costs 1 credit, from $1.20/1K searches as of October 2026. No KYC; pay in crypto.

## /search at a glance

| Attribute | Value |
| --- | --- |
| Methods | `POST` with a JSON body, or `GET` with the same names in the query string |
| URL | `https://llmwebsearch.com/api/v1/search` |
| Required | `q`: 1 to 400 characters; search operators are passed as written |
| Defaults | 5 results, the first 3 read, Markdown up to 6,000 characters per page |
| Billing | One credit pays for one search: up to 20 ranked results, with the pages of the first 3 read and returned as Markdown. Reading 4 to 10 pages makes it 2 credits. A call that ends in an error costs nothing |
| Results | Results come from a live web search run at the moment of your call, in the order the search engine ranks them; nothing is served from an old index |
| Filters | Choose the country and language of the results, a time range (past day, week, month or year), web or news results, and domains to include or exclude |
| Page reader | `LLMWebSearch/1.0 (+https://llmwebsearch.com/bot/)` |

## Search the web and read the top results (POST)

`POST /api/v1/search`

Runs a live web search and returns ranked results. The pages of the first `read` results are fetched in parallel and their main content is returned in `content`. The example asks how to rotate API keys; titles, dates and values are illustrative.

Authentication: API key in the `Authorization: Bearer API_KEY` header.

**Request body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `q` | string | Yes | The search query, 1 to 400 characters. Quotes and operators such as `site:` are kept as written. |
| `max_results` | integer | No | Number of ranked results, 1 to 20. Default 5. |
| `read` | integer | No | How many of the first results are read and returned with their content, 0 to 10. Default 3. From 4 upward the call costs 2 credits. |
| `format` | string | No | `markdown` (default) or `text` for the page content. |
| `max_chars` | integer | No | Length cap of each page's content, 500 to 50,000 characters. Default 6,000. |
| `topic` | string | No | `web` (default) or `news`. |
| `time_range` | string | No | `day`, `week`, `month` or `year`. No default: any date. |
| `country` | string | No | Two-letter country code (ISO 3166-1 alpha-2) for where the search runs. Default `us`. |
| `language` | string | No | Language of the results, such as `en`, `de` or `pt-BR`. Default `en`. |
| `include_domains` | string[] | No | Up to 20 domains; only results from these domains and their subdomains are kept. |
| `exclude_domains` | string[] | No | Up to 20 domains whose results are dropped. |

*Example: five results, the top three read as Markdown*

```json
{
  "q": "how to rotate api keys without downtime",
  "max_results": 5,
  "read": 3,
  "max_chars": 6000
}
```

*Example: news of the past week from two sites, nothing read*

```json
{
  "q": "open source license change",
  "topic": "news",
  "time_range": "week",
  "include_domains": [
    "news.example.com",
    "example.org"
  ],
  "read": 0
}
```

**Response** `200`

```json
{
  "query": "how to rotate api keys without downtime",
  "created_at": "2026-10-22T10:15:04Z",
  "credits_used": 1,
  "results": [
    {
      "position": 1,
      "title": "Rotating API keys",
      "url": "https://docs.example.com/security/key-rotation",
      "host": "docs.example.com",
      "snippet": "Create a second key, deploy it everywhere, then revoke the first one.",
      "published_at": "2026-09-30",
      "content_status": "ok",
      "content": "# Rotating API keys\n\n## Zero-downtime rotation\n\n1. Create a second key.\n2. Deploy it to every service.\n3. Revoke the old key.",
      "word_count": 948
    },
    {
      "position": 2,
      "title": "Key rotation checklist",
      "url": "https://blog.example.org/key-rotation-checklist",
      "host": "blog.example.org",
      "snippet": "Keep two keys active during the switch and alert on the old one.",
      "content_status": "blocked_by_robots"
    },
    {
      "position": 3,
      "title": "Secrets management basics",
      "url": "https://security.example.net/secrets-basics",
      "host": "security.example.net",
      "snippet": "Never commit keys to a repository.",
      "published_at": "2026-06-12",
      "content_status": "ok",
      "content": "# Secrets management basics\n\n**Never** commit keys to a repository...",
      "word_count": 1310
    },
    {
      "position": 4,
      "title": "API key best practices",
      "url": "https://dev.example.com/api-key-best-practices",
      "host": "dev.example.com",
      "snippet": "Scope each key to one service and one environment.",
      "content_status": "not_requested"
    }
  ]
}
```

*curl*

```bash
curl -s "https://llmwebsearch.com/api/v1/search" \
  -H "Authorization: Bearer $LLMWEBSEARCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q": "how to rotate api keys without downtime", "max_results": 5, "read": 3}'
```

*Python*

```python
import os
import requests

resp = requests.post(
    "https://llmwebsearch.com/api/v1/search",
    headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
    json={"q": "how to rotate api keys without downtime", "max_results": 5, "read": 3},
    timeout=60,
)
resp.raise_for_status()
for r in resp.json()["results"]:
    print(r["position"], r["content_status"], r["url"])
```

*Node.js*

```javascript
const res = await fetch('https://llmwebsearch.com/api/v1/search', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LLMWEBSEARCH_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ q: 'how to rotate api keys without downtime', max_results: 5, read: 3 }),
});
const { results } = await res.json();
for (const r of results) console.log(r.position, r.content_status, r.url);
```

## Search the web (GET)

`GET /api/v1/search`

The same search with the parameters in the query string, URL-encoded. Lists such as `include_domains` are written as one comma-separated value. Handy for a quick test or for tools that only send GET requests. The example asks for results only (`read=0`).

Authentication: API key in the `Authorization: Bearer API_KEY` header.

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `q` | query | string | Yes | The search query, URL-encoded, 1 to 400 characters. |
| `max_results` | query | integer | No | 1 to 20. Default 5. |
| `read` | query | integer | No | 0 to 10. Default 3; 4 or more costs 2 credits. |
| `format` | query | string | No | `markdown` (default) or `text`. |
| `max_chars` | query | integer | No | 500 to 50,000 per page. Default 6,000. |
| `topic` | query | string | No | `web` (default) or `news`. |
| `time_range` | query | string | No | `day`, `week`, `month` or `year`. |
| `country` | query | string | No | ISO 3166-1 alpha-2 code. Default `us`. |
| `language` | query | string | No | Language code. Default `en`. |
| `include_domains` | query | string | No | Comma-separated list, up to 20 domains. |
| `exclude_domains` | query | string | No | Comma-separated list, up to 20 domains. |
| `api_key` | query | string | No | Your key, when you do not send the `Authorization` header. |

**Response** `200`

```json
{
  "query": "postgres connection pooling",
  "created_at": "2026-10-22T10:21:47Z",
  "credits_used": 1,
  "results": [
    {
      "position": 1,
      "title": "Connection pooling explained",
      "url": "https://docs.example.com/db/pooling",
      "host": "docs.example.com",
      "snippet": "A pool keeps a few database connections open and lends them to requests.",
      "content_status": "not_requested"
    },
    {
      "position": 2,
      "title": "Sizing a connection pool",
      "url": "https://blog.example.org/pool-size",
      "host": "blog.example.org",
      "snippet": "Start small: the right size depends on cores and disk, not on traffic.",
      "published_at": "2026-03-04",
      "content_status": "not_requested"
    }
  ]
}
```

*curl*

```bash
curl -sG "https://llmwebsearch.com/api/v1/search" \
  -H "Authorization: Bearer $LLMWEBSEARCH_API_KEY" \
  --data-urlencode "q=postgres connection pooling" \
  -d max_results=10 -d read=0
```

*Python*

```python
import os
import requests

resp = requests.get(
    "https://llmwebsearch.com/api/v1/search",
    headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
    params={"q": "postgres connection pooling", "max_results": 10, "read": 0},
    timeout=60,
)
print([r["url"] for r in resp.json()["results"]])
```

*Node.js*

```javascript
const params = new URLSearchParams({ q: 'postgres connection pooling', max_results: '10', read: '0' });
const res = await fetch(`https://llmwebsearch.com/api/v1/search?${params}`, {
  headers: { Authorization: `Bearer ${process.env.LLMWEBSEARCH_API_KEY}` },
});
console.log((await res.json()).results.map((r) => r.url));
```

## How do I get results without any page content?

Set `read` to `0`. Every result then comes back with its title, URL, host, snippet and date, and `content_status: "not_requested"`. The response is much smaller, which helps when the agent only needs to choose which links matter.

The price stays at 1 credit, the same as reading up to 3 pages. A common pattern is a `read=0` search to shortlist, then an [extract call](https://llmwebsearch.com/docs/extract/) on the two or three URLs the model picked.

## When does a search cost 2 credits?

When `read` is between 4 and 10. Reading more pages takes more work on our side, so the price doubles once, and stays at 2 credits up to the maximum of 10 pages.

`credits_used` in every response shows what the call cost. A page that could not be read, for a robots.txt rule or a refusal, does not lower or raise that price. If you only need a few full pages most of the time, keep `read` at 3 and call `/extract` for the rare extra page.

## How do I search recent news?

Send `topic: "news"` and a `time_range`. The results then come from news articles, and `time_range` keeps only those from the past `day`, `week`, `month` or `year`. `published_at` is filled in when the article or the search result states a date.

The same freshness filter works with `topic: "web"`. It is useful for questions such as recent releases or price changes, where an old page would mislead the model.

*News from the past week, top 3 articles read*

```bash
curl -s "https://llmwebsearch.com/api/v1/search" \
  -H "Authorization: Bearer $LLMWEBSEARCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q": "database release security fix", "topic": "news", "time_range": "week", "read": 3}'
```

## How do I keep results to certain sites?

List them in `include_domains`, up to 20 entries. Only results whose host is one of those domains, or one of their subdomains, are kept: `example.com` also matches `docs.example.com`. Use `exclude_domains` the other way round, for example to drop your own site from the results.

In a POST body both fields are JSON arrays. In a GET request, write them as one comma-separated value. The query itself can also carry a `site:` operator; it is passed to the search as written.

## What do country and language change?

`country` sets where the search runs, with a two-letter code such as `us`, `de` or `br`. Rankings differ by country, especially for local services, prices and regulations. `language` sets the language of the results, such as `en`, `fr` or `pt-BR`.

Both default to the United States and English. Set them together when the agent works for users in one market: a German user asking about tax rules wants `country: "de"` and `language: "de"`.

## How much page text comes back?

Up to `max_chars` characters per page, 6,000 by default and anywhere from 500 to 50,000. The cap protects the model's context window: three pages at 6,000 characters is roughly 4,500 tokens of English.

`word_count` counts the whole extracted text, before the cut, so you can tell when a page was trimmed. When an answer needs one long document, search with a low cap first, then fetch that page alone through `/extract` with a higher one. A slow page is not waited for indefinitely: after 15 seconds it comes back as `fetch_timeout`, without content.

## Search endpoint: common questions

### Should I use POST or GET?

POST in code, because JSON arrays and long queries are simpler in a body. GET suits a quick test in a terminal or a tool that only sends query strings. Both return the same response and cost the same.

### Can I ask for more than 20 results?

No. 20 is the maximum per call. Agents rarely need more: a second search with a reworded query usually brings better sources than a long list.

### Are the pages read one after the other?

No, in parallel. A page that does not answer within 15 seconds is returned without content, as `fetch_timeout`, so one slow site does not hold the whole response.

### Which search engine produces the results?

Results come from a live web search run at the moment of your call, in the order the search engine ranks them; nothing is served from an old index. We do not publish which upstream providers run the search.

---

LLMWebSearch: LLMWebSearch is a web search API for AI agents that returns ranked results with the content of the top pages in Markdown, paid in crypto with no ID upload. Prepaid credits from $1.20/1K searches never expire. No KYC — no ID, no selfie, no documents. Pay in crypto.
