# Web search API quick start: your first search in two minutes

> Web search API quick start: get a key, run your first search with curl, Python or Node.js, and read the top pages as Markdown. No KYC, pay in crypto.

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

One endpoint does the work: send a question to `/search` and get ranked results back, with the first pages already read and cleaned into Markdown. This page goes from an empty balance to a working call, then points to every other page of the docs.

**Quick answer — How do I run my first search with a web search API for AI agents?**

Send your question to `POST https://llmwebsearch.com/api/v1/search` with your API key as a Bearer token. **LLMWebSearch** runs a live web search and returns up to 20 ranked results, with the first 3 pages read and returned as Markdown. One credit pays for that whole call, from $1.20/1K searches as of October 2026. No KYC; pay in crypto.

## The API on one card

| Attribute | Value |
| --- | --- |
| Base URL | `https://llmwebsearch.com/api/v1` |
| Search | `POST` or `GET https://llmwebsearch.com/api/v1/search` |
| Read URLs you already have | `POST https://llmwebsearch.com/api/v1/extract` |
| Credits left | `GET https://llmwebsearch.com/api/v1/credits`, free of charge |
| Authentication | Pass your API key as a Bearer token in the Authorization header, or as the api_key query parameter |
| 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 |
| Our page reader | `LLMWebSearch/1.0 (+https://llmwebsearch.com/bot/)`, robots.txt token `LLMWebSearch` |
| Smallest pack | 5,000 searches for $9.25; credits never expire |

## How do I get an API key?

There is no sign-up form. Waiting for the blockchain to confirm your top-up is the longest part.

1. **Fund your balance in crypto** — Send at least $25 in BTC, USDT, USDC, ETH, SOL, LTC. Sign in with an account number; an email address is optional.
2. **Buy a pack of searches** — 5,000 searches for $9.25 is plenty to wire search into one agent and try every option.
3. **Copy the key** — Once your crypto top-up is confirmed and a pack is bought, your API key is waiting in the dashboard. Keep it in an environment variable called LLMWEBSEARCH_API_KEY.

## What does the first search look like?

It is one HTTPS POST with a small JSON body. Only `q` is required: the question or keywords, as a person would type them. The defaults already suit most agents. You get 5 ranked results, and the pages behind the first 3 are read and returned as Markdown of up to 6,000 characters each.

The three snippets below send the same search. Pick the one that matches your stack, set `LLMWEBSEARCH_API_KEY` in your shell, and run it.

*curl: one search, top 3 pages read*

```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: list the sources and their size*

```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()
data = resp.json()
print("credits used:", data["credits_used"])
for r in data["results"]:
    size = r.get("word_count", 0)
    print(r["position"], r["title"], r["url"], r["content_status"], size, "words")

```

*Node.js 18+: print the first page that was read*

```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 data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
const first = data.results.find((r) => r.content_status === 'ok');
console.log(first ? `${first.title}\n${first.url}\n\n${first.content.slice(0, 600)}` : 'No page could be read.');

```

## What comes back?

A JSON object with your `query`, the time of the call in `created_at`, the price in `credits_used`, and a `results` array in ranked order. Every result has its `position`, `title`, `url`, `host` and `snippet`, plus `published_at` when the date is known.

The field to watch is `content_status`. When it says `ok`, the page was read and its main content sits in `content`, with a `word_count`. Results beyond `read` say `not_requested`. A page that could not be read says why, for example `blocked_by_robots`. The [response format](https://llmwebsearch.com/docs/response/) page explains every field.

## Which parameters will I change most often?

Six parameters cover nearly every agent. All of them are optional.

| Parameter | What it changes |
|---|---|
| `max_results` | How many ranked results come back, from 1 to 20 |
| `read` | How many of the first results are read, from 0 to 10 |
| `max_chars` | The length cap of each page's content, 500 to 50,000 characters |
| `topic` and `time_range` | News instead of web pages, and a freshness window |
| `include_domains` | Results only from the sites you list |
| `country` and `language` | Where and in which language the search runs |

The [search reference](https://llmwebsearch.com/docs/search/) documents each one with an example, plus `format` and `exclude_domains`.

## How many credits does a call use?

Most calls use one. The full rule set:

- **Search reading 0 to 3 pages: 1 credit.** That includes up to 20 ranked results.
- **Search reading 4 to 10 pages: 2 credits.**
- **Extract:** Reading pages whose URLs you already have costs 1 credit for each started group of 3 pages returned with content, up to 20 URLs per call; refused or failed URLs are not counted.
- **Errors: 0 credit.** A bad parameter, a wrong key, an empty balance or a failed search costs nothing.
- **A page that could not be read** inside a successful search does not change its price.
- **Checking your balance** with `GET https://llmwebsearch.com/api/v1/credits` is free.

Search credits have no expiry date: what you do not use this month is still there next year.

## What happens when a site does not want to be read?

The result still appears, with its title, URL and snippet, but without the page content. Our reader respects robots.txt: it introduces itself as LLMWebSearch, follows the rules a site writes for it or for all robots, and leaves out the content of any page it is not allowed to read. A site that sets Content-Signal: ai-input=no in its robots.txt keeps its pages out of your results' content.

When a site answers our reader with a refusal, the result carries `content_status: "target_refused"` and the site's own HTTP status in `target_status`. When a site turns our reader away, the result comes back without content and with the site's status: we never solve CAPTCHAs, sign in to accounts or work around a block or a paywall. The [errors page](https://llmwebsearch.com/docs/errors/) lists every status and the ones worth a retry.

## Where do I go next?

- [Search endpoint](https://llmwebsearch.com/docs/search/) — Every parameter of /search, with examples
- [Extract endpoint](https://llmwebsearch.com/docs/extract/) — Read 1 to 20 URLs you already have
- [Response format](https://llmwebsearch.com/docs/response/) — Each field and every content_status
- [Errors](https://llmwebsearch.com/docs/errors/) — HTTP errors, page statuses, retry rules
- [Python](https://llmwebsearch.com/docs/python/) — requests, async httpx, an answer with citations
- [Node.js](https://llmwebsearch.com/docs/node/) — fetch, a small pool, the same citation loop
- [curl and jq](https://llmwebsearch.com/docs/curl/) — Terminal recipes
- [MCP server](https://llmwebsearch.com/docs/mcp/) — search_web for Claude Code and Claude Desktop
- [LangChain and LlamaIndex](https://llmwebsearch.com/docs/langchain/) — A tool and a retriever
- [OpenAI function calling](https://llmwebsearch.com/docs/openai/) — Tool schema, loop and Agents SDK
- [n8n](https://llmwebsearch.com/docs/n8n/) — HTTP Request tool for an AI Agent
- [OpenClaw](https://llmwebsearch.com/docs/openclaw/) — Our search through MCP

## Quick start: common questions

### Do I need an SDK?

No. LLMWebSearch is a plain HTTPS API, so any HTTP client works. These docs give copy-paste code for Python, Node.js and curl, and tool definitions for MCP, LangChain, LlamaIndex, OpenAI function calling, n8n and OpenClaw. We publish no package.

### Does the API write the answer for me?

No. The API returns sources, not a written answer: your own model reads the pages, writes the reply and cites the URLs. That keeps you free to choose the model, the prompt and the citation style.

### Can I put the key in the URL?

Yes, as the `api_key` query parameter of `GET /search`. The `Authorization` header is the safer choice, because URLs end up in logs and shell history. Make one API key per agent, app or teammate and revoke any of them from the dashboard without touching the others.

### Is there a free tier to try it?

No. There is no free tier: the 5,000-search pack is the way to try it, bought from the minimum top-up; whatever you added only to reach that minimum comes back on request within 30 days, in USDT or USDC, as long as it is unspent.

---

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.
