> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nano-gpt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Direct Web Search API

> Run direct web search requests with explicit query control, provider-specific options, and Sofya search, fetch, extract, and research operations

## Overview

Use `POST /api/web` when you want direct control over search requests and output formatting.

You can also call this tool through the unified [Data API](/api-reference/endpoint/data-api) at `POST /api/v1/data/web/search`. The Data API preserves this endpoint's request body, response body, billing, and provider behavior while adding discovery and dispatch metadata.

For chat-first workflows, use `POST /api/v1/chat/completions` with model suffixes like `:online`, `:online/linkup`, or `:online/sofya`, including provider-specific suffixes such as `:online/exa-instant`, `:online/exa-deep-reasoning`, `:online/brave`, and `:online/valyu-web-deep`. See [Model Suffixes](/api-reference/miscellaneous/model-suffixes#web-search-suffixes).

Sofya can do more than search on this endpoint. Set `provider: "sofya"` and choose the `search`, `fetch`, `extract`, or `research` operation.

## When to use which endpoint

| Use case                                                                                               | Endpoint                                       |
| ------------------------------------------------------------------------------------------------------ | ---------------------------------------------- |
| You want the model to answer with web context in one call                                              | `POST /api/v1/chat/completions` + `:online...` |
| You want one discoverable endpoint family for data tools                                               | `POST /api/v1/data/web/search`                 |
| You need explicit control over `query`, `outputType`, domain/date filters, or structured schema output | `POST /api/web`                                |
| You need OpenAI-native web search                                                                      | `POST /api/v1/chat/completions` only           |

## Authentication

Either auth header is supported:

<ParamField header="Authorization" type="string">
  Bearer `YOUR_API_KEY`
</ParamField>

<ParamField header="x-api-key" type="string">
  `YOUR_API_KEY`
</ParamField>

## Accountless x402 Payment

For accountless payment, prefer the public Data API path:

```bash theme={null}
curl -i https://nano-gpt.com/api/v1/data/web/search \
  -H "Content-Type: application/json" \
  -H "x-x402: true" \
  -d '{
    "query": "What happened in AI this week?",
    "provider": "linkup",
    "depth": "standard",
    "outputType": "sourcedAnswer"
  }'
```

To request an accountless x402 quote, send the API request without `Authorization` or `x-api-key`, and include `x-x402: true`. NanoGPT will return `402 Payment Required` with available payment options. This endpoint supports accountless x402 payments where listed by `GET /api/v1/x402/endpoints`, including Lightning L402 when advertised. See [Accountless x402 API Payments](/api-reference/miscellaneous/x402) for the full flow.

If you receive `401 missing_api_key` immediately, check that the initial quote request includes `x-x402: true`. Without that header, NanoGPT does not enter the x402 quote flow.

## Request body

<ParamField body="query" type="string">
  Search or research query. Required for every provider's search operation and for Sofya research. Not used by Sofya fetch or extract.
</ParamField>

<ParamField body="provider" type="string" default="linkup">
  Search provider: `linkup`, `tavily`, `exa`, `kagi`, `perplexity`, `valyu`, `brave`, `sofya`, or `firecrawl`. `openai-native` is not allowed on `/api/web`.
</ParamField>

<ParamField body="operation" type="string" default="search">
  Sofya operation: `search`, `fetch`, `extract`, or `research`. Other providers support `search` only.
</ParamField>

<ParamField body="depth" type="string" default="standard">
  Search depth. For Linkup: `standard` or `deep`.
</ParamField>

<Note>
  For Linkup, `depth: "standard"` is executed as Linkup `fast` under the hood.
</Note>

<ParamField body="outputType" type="string" default="searchResults">
  Output mode. Allowed values: `searchResults`, `sourcedAnswer`, `structured`.
</ParamField>

<ParamField body="structuredOutputSchema" type="string">
  Required when `outputType` is `structured`. Pass a JSON schema string.
</ParamField>

<ParamField body="includeImages" type="boolean" default={false}>
  Include image results.
</ParamField>

<ParamField body="fromDate" type="string">
  Earliest result date (`YYYY-MM-DD`).
</ParamField>

<ParamField body="toDate" type="string">
  Latest result date (`YYYY-MM-DD`).
</ParamField>

<ParamField body="includeDomains" type="string[]">
  Restrict results to these domains.
</ParamField>

<ParamField body="excludeDomains" type="string[]">
  Exclude these domains.
</ParamField>

<Note>
  Linkup supports `outputType: "searchResults"`, `"sourcedAnswer"`, and `"structured"`.
  Non-Linkup providers currently support only `outputType: "searchResults"`.
</Note>

### Sofya operations

Sofya Search returns extracted page content instead of snippets alone. The other operations let you fetch known URLs, extract requested information from one page, or produce a cited multi-source research report.

#### Search

Use `operation: "search"` or omit `operation`.

* `query` (string, required)
* `maxResults` (integer, 1-20; default 10)
* `topic` (`general` or `news`)
* `freshness` (`day`, `week`, `month`, `year`, or `YYYY-MM-DD:YYYY-MM-DD`)
* `includeDomains` / `excludeDomains` (up to 10 strings each)

#### Fetch

Use `operation: "fetch"` with:

* `urls` (array of 1-10 URL strings, required)
* `includeRawHtml` or `include_raw_html` (boolean)

#### Extract

Use `operation: "extract"` with:

* `url` (string, required)
* `prompt` (string, required), describing what to extract

#### Research

Use `operation: "research"` with:

* `query` (string, required)
* `topic` (`general` or `news`)
* `freshness` (`day`, `week`, `month`, `year`, or `YYYY-MM-DD:YYYY-MM-DD`)
* `maxSources` or `max_sources` (integer, 5-30)

## Response shape

<ResponseField name="data" type="array|object">
  Provider-formatted payload.
</ResponseField>

<ResponseField name="metadata" type="object">
  <Expandable title="metadata">
    <ResponseField name="query" type="string">
      Executed query.
    </ResponseField>

    <ResponseField name="provider" type="string">
      Resolved provider (for example, `linkup`).
    </ResponseField>

    <ResponseField name="operation" type="string">
      Resolved operation. This is `search` except for Sofya fetch, extract, or research requests.
    </ResponseField>

    <ResponseField name="depth" type="string">
      Resolved depth.
    </ResponseField>

    <ResponseField name="outputType" type="string">
      Resolved output type.
    </ResponseField>

    <ResponseField name="timestamp" type="string">
      ISO-8601 timestamp.
    </ResponseField>

    <ResponseField name="cost" type="number">
      Request cost in USD.
    </ResponseField>
  </Expandable>
</ResponseField>

For `searchResults`, `data` is normally an array of normalized results. Sofya extract and research return an object, while Sofya fetch returns an array.
For `sourcedAnswer` and `structured`, `data` is the provider response object.

### Example response

```json theme={null}
{
  "data": "... provider-formatted payload ...",
  "metadata": {
    "query": "string",
    "provider": "linkup",
    "depth": "standard",
    "outputType": "sourcedAnswer",
    "timestamp": "ISO-8601",
    "cost": 0.006
  }
}
```

## Pricing (hosted key)

| Mode            | Price             |
| --------------- | ----------------- |
| Linkup standard | \$0.006           |
| Linkup deep     | \$0.06            |
| Sofya search    | \$0.01575         |
| Sofya fetch     | \$0.00525 per URL |
| Sofya extract   | \$0.02625         |
| Sofya research  | \$0.13125         |

## Error codes

| HTTP status | Meaning                           |
| ----------- | --------------------------------- |
| `400`       | Invalid parameters                |
| `401`       | Invalid session or auth           |
| `402`       | Insufficient balance or usage cap |
| `429`       | Rate limited                      |
| `503`       | Provider key missing              |
| `504`       | Search failed or timed out        |

## Examples

<CodeGroup>
  ```bash cURL (Authorization) theme={null}
  curl -X POST https://nano-gpt.com/api/web \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "What happened in AI this week?",
      "provider": "linkup",
      "depth": "standard",
      "outputType": "sourcedAnswer"
    }'
  ```

  ```bash cURL (x-api-key) theme={null}
  curl -X POST https://nano-gpt.com/api/web \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "Latest OpenAI announcements",
      "provider": "linkup",
      "depth": "deep",
      "outputType": "searchResults"
    }'
  ```

  ```bash cURL (structured output) theme={null}
  curl -X POST https://nano-gpt.com/api/web \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "Top 5 AI coding tools in 2026 with pricing",
      "provider": "linkup",
      "depth": "standard",
      "outputType": "structured",
      "structuredOutputSchema": "{\"type\":\"object\",\"properties\":{\"tools\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"},\"price\":{\"type\":\"string\"}},\"required\":[\"name\"]}}},\"required\":[\"tools\"]}"
    }'
  ```

  ```bash cURL (chat completions with Linkup) theme={null}
  curl -X POST https://nano-gpt.com/api/v1/chat/completions \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gpt-4o:online/linkup",
      "messages": [
        { "role": "user", "content": "Summarize today'\''s top AI headlines." }
      ]
    }'
  ```

  ```bash cURL (chat completions with Sofya) theme={null}
  curl -X POST https://nano-gpt.com/api/v1/chat/completions \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gpt-4o:online/sofya",
      "messages": [
        { "role": "user", "content": "Summarize today'\''s top AI headlines." }
      ]
    }'
  ```
</CodeGroup>

### Sofya examples

<CodeGroup>
  ```bash cURL (search) theme={null}
  curl -X POST https://nano-gpt.com/api/web \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "provider": "sofya",
      "operation": "search",
      "query": "NanoGPT API documentation",
      "maxResults": 10,
      "topic": "general"
    }'
  ```

  ```bash cURL (fetch) theme={null}
  curl -X POST https://nano-gpt.com/api/web \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "provider": "sofya",
      "operation": "fetch",
      "urls": ["https://sofya.co/docs"],
      "includeRawHtml": false
    }'
  ```

  ```bash cURL (extract) theme={null}
  curl -X POST https://nano-gpt.com/api/web \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "provider": "sofya",
      "operation": "extract",
      "url": "https://sofya.co/pricing",
      "prompt": "Extract the available plans and their prices."
    }'
  ```

  ```bash cURL (research) theme={null}
  curl -X POST https://nano-gpt.com/api/web \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "provider": "sofya",
      "operation": "research",
      "query": "Compare current AI web search APIs",
      "maxSources": 15
    }'
  ```
</CodeGroup>

## Related docs

* [Chat Completion](/api-reference/endpoint/chat-completion)
* [Data API](/api-reference/endpoint/data-api)
* [Web Search in Text Generation Guide](/api-reference/text-generation)
* [Model Suffixes](/api-reference/miscellaneous/model-suffixes)
