# Create web

URL: https://docs.hanzo.ai/docs/openapi/ask/research-web

> Researches a question on the live web and answers it with its sources cited.

`POST /v1/ask/web`

> [Ask →](https://docs.hanzo.ai/docs/openapi/ask) · [All API references →](https://docs.hanzo.ai/docs/openapi) · [Get started →](https://docs.hanzo.ai/docs/guides)

|               |                                        |
| ------------- | -------------------------------------- |
| **Address**   | `https://api.hanzo.ai/v1/ask/web`      |
| **Method**    | `POST`                                 |
| **Operation** | `research_web`                         |
| **Auth**      | `Authorization: Bearer $HANZO_API_KEY` |

Researches a question on the live web and answers it with its
sources cited.

This is the DEEP one. It plans the question into topics, runs several web
searches, FETCHES AND READS the pages it finds, ranks them, and writes a
grounded answer with inline markdown citations. Use it for anything that needs
evidence, comparison or current fact — "what changed in X", "compare A and B",
"is this claim true". For a plain list of links, use search\_web instead; for
one page you already have the URL of, use read\_page.

`mode` buys depth: `search` is a single fast pass, `news` biases to recency,
`research` plans and iterates, `deep` surveys widest. `sources` narrows the
evidence to `web`, `news`, `academic`, `github`, `reddit` or `x` — each becomes
a site-scoped search, which is how this reaches X/Twitter posts.

EVERY CITATION IS A PAGE THIS CALL FETCHED. That is a property of the text and
not an instruction to the model: each source is fenced with a per-request nonce
so a crawled page cannot print itself a source number, and every markdown link
in the answer is checked against the gathered set before it is returned. So a
link in `answer` always appears in `sources`, and a page that was not read
cannot be cited.

It is BOUNDED and it degrades rather than failing: a mode's rounds, wall clock
and token ceiling all cap it, and a search that finds little or a page that
will not load yields a thinner answer, never an error. A validated principal is
required, and the answer is billed once to that principal's org.

## Request

5 fields, body `application/json` (required).

| Field         | In   | Type            | Required | Description                                                                                                                                            |
| ------------- | ---- | --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `language`    | body | string          | —        | Language narrows the search to a locale, BCP-47-ish ("en", "ja").                                                                                      |
| `max_sources` | body | integer (int64) | —        | MaxSources caps how many pages are read.                                                                                                               |
| `mode`        | body | string          | —        | Mode is how much work to do: `search` (fast, one pass), `news` (recency biased), `research` (a plan and several rounds) or `deep` (the widest survey). |
| `q`           | body | string          | —        | Q is the question, in plain language.                                                                                                                  |
| `sources`     | body | string\[]       | —        | Sources narrows where the evidence comes from: any of `web`, `news`, `academic`, `github`, `reddit`, `x`.                                              |

## Response

| Status    | Body            | Meaning |
| --------- | --------------- | ------- |
| `200`     | ask.Report      | ok      |
| `default` | problem-details | refused |

`200` body — 10 fields.

| Field               | In   | Type          | Always | Description                                                                                                                       |
| ------------------- | ---- | ------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------- |
| `answer`            | body | string        | —      | Answer is the grounded prose, with inline markdown citations.                                                                     |
| `follow_ups`        | body | string\[]     | —      | FollowUps are the questions worth asking next.                                                                                    |
| `mode`              | body | string        | —      | Mode is the profile that ran: search, news, research or deep.                                                                     |
| `model`             | body | string        | —      | Model is the model that synthesized the answer.                                                                                   |
| `sources`           | body | ask.Source\[] | —      | Sources are the pages the answer was written from, deduplicated and ranked.                                                       |
| `sources[].engine`  | body | string        | —      | Engine is the search backend the hit came from: bing, ddg, mojeek or brave.                                                       |
| `sources[].favicon` | body | string        | —      | Favicon is a 64px icon URL derived from the host for the client to render beside the citation.                                    |
| `sources[].snippet` | body | string        | —      | Snippet is the engine's summary of the page, clipped to 600 runes.                                                                |
| `sources[].title`   | body | string        | —      | Title is the page title the engine reported, stripped of the bracketed furniture engines staple on ("\[PDF]", "(Official Site)"). |
| `sources[].url`     | body | string        | —      | URL is the page, absolute, exactly as the engine gave it.                                                                         |

Failure carries the platform error shape — see [Errors](https://docs.hanzo.ai/docs/errors).

## Examples

**CLI**

```bash
hanzo ask web
```

**SDK**

**.ts**

```ts
import { Configuration, AskApi } from 'hanzoai';

const api = new AskApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.researchWeb({ language: "<language>", max_sources: 0 });
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import AskApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = AskApi(client).research_web(language="<language>", max_sources=0)
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.AskAPI.ResearchWeb(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, ask_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = ask_api::research_web(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.AskApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new AskApi(client).researchWeb();
```

**HTTP**

```bash
curl -X POST https://api.hanzo.ai/v1/ask/web \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "language": "<language>",
       "max_sources": 0
     }'
```

**MCP**

Tool `ask`, op `research_web` — POST the JSON-RPC envelope to `https://api.hanzo.ai/v1/mcp`.

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "ask",
         "arguments": {
           "op": "research_web",
           "input": {
             "language": "<language>",
             "max_sources": 0
           }
         }
       }
     }'
```

---

[Ask API](https://docs.hanzo.ai/docs/openapi/ask) · [All Hanzo APIs](https://docs.hanzo.ai/docs/openapi) · [Interactive reference](https://docs.hanzo.ai/docs/openapi/reference)
