---
title: "Search API: web and news retrieval"
description: "Provider-neutral POST /v1/search for web and news retrieval through configured Lazu search backends."
source: https://lazu.ai/docs/endpoints/search
updated: 2026-10-02
---

# Search

**POST** `/v1/search`

Run provider-neutral web or news search through Lazu. Hosted api.lazu.ai currently enables Tavily, Serper and Jina; self-hosted operators can add Exa or Brave through the same search-backend system.

## Example request

```bash
curl https://api.lazu.ai/v1/search \
  -H "Authorization: Bearer $LAZU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "latest OpenAI web search API changes",
    "type": "web",
    "max_results": 5,
    "backend": "auto"
  }'
```

## Example response

```json
{
  "query": "latest OpenAI web search API changes",
  "results": [
    {
      "title": "OpenAI ships web search API",
      "url": "https://example.com/news",
      "snippet": "…",
      "score": 0.92,
      "source": "tavily"
    }
  ],
  "usage": {
    "web_search_requests": 1,
    "web_search_billable_units": 1
  },
  "provider_trace": { "backend": "tavily" },
  "route_receipt": {
    "selection": "auto",
    "selected_backend": "search_tavily",
    "chose_provider": "tavily",
    "candidates": ["search_tavily"],
    "decision_reason": "matched web_search capability"
  }
}
```

## What it returns

- **Normalized results** — Every backend maps into `title`, `url`,
  `snippet`, optional `content`,
  `published_at`, `score` and `source`.
- **Auditable routing** — The response includes the selected backend and route receipt. Request logs
  store the same routing metadata for support and billing reconciliation.

## Hosted configuration

The `/v1/search` implementation supports Tavily, Serper, Exa, Jina and Brave,
but the hosted Lazu deployment is configured with this active set:

| Backend     | Hosted status | Capabilities                        | Notes                                                                 |
| ----------- | ------------- | ----------------------------------- | --------------------------------------------------------------------- |
| Tavily      | Enabled       | `web_search`, `web_fetch`, `answer` | Supports `include_answer` and `search_depth`; `advanced` is 2 units.  |
| Serper      | Enabled       | `web_search`                        | Maps `country` / `region`, `language` and `time_range` when provided. |
| Jina        | Enabled       | `web_search`, `web_fetch`           | Uses `https://s.jina.ai`; best for retrieval-style snippets.          |
| Exa / Brave | Supported     | `web_search` after operator setup   | Available for self-hosted or admin-configured deployments.            |

Hosted backends currently use the default backend policy: up to 10 results per
request and an 8s upstream timeout. If you send a larger `max_results`, Lazu
clips it to the selected backend policy.

## Request body

- `query` `string` (required) — Search query. The MVP supports one query per request.
- `type` `string` (optional) — Search vertical. Defaults to `web`. One of: `web`, `news`
- `backend` `string` (optional) — `auto`, a provider name such as `tavily` or&#x20;
  `serper`, or a configured backend ID/name. Defaults to&#x20;
  `auto`.
- `region` `string` (optional) — Region hint. Serper maps this to `gl`; other providers may ignore
  unsupported regions.
- `language` `string` (optional) — Language hint such as `en` or `zh-CN`.
- `time_range` `string` (optional) — Freshness hint. Providers that cannot map the value may ignore it. One of: `day`, `week`, `month`, `year`
- `max_results` `integer` (optional) — Number of results to return. Defaults to `10` and is capped by
  the selected backend policy.
- `search_depth` `string` (optional) — Provider depth hint. Tavily `advanced` uses two billable credits. One of: `basic`, `advanced`
- `include_answer` `boolean` (optional) — Include a provider answer when the selected backend returns one. Lazu does
  not generate its own final answer in this endpoint.
- `include_raw_content` `boolean` (optional) — Include raw or cleaned content when the provider returns it. Defaults to
  `false`.
- `include_domains` `string[]` (optional) — Restrict results to domains. Token-level domain allowlists still apply.
- `exclude_domains` `string[]` (optional) — Exclude domains when supported by the selected backend.
- `include_provider_payload` `boolean` (optional) — Return the provider-native payload for debugging. Defaults to
  `false`.
- `provider_options` `object` (optional) — Advanced provider passthrough. Only the selected provider's object is used,
  for example `{"serper":{"tbs":"qdr:d"}}`.

## Response

**Search response**

```json
{
"query": "latest OpenAI web search API changes",
"results": [
  {
    "title": "Web search - OpenAI API",
    "url": "https://platform.openai.com/docs/guides/tools-web-search",
    "snippet": "Use web search in the Responses API...",
    "content": null,
    "published_at": null,
    "score": 0.91,
    "source": "web"
  }
],
"usage": {
  "web_search_requests": 1,
  "web_search_billable_units": 1
},
"provider_trace": {
  "backend": "tavily"
},
"route_receipt": {
  "selection": "auto",
  "selected_backend": "tavily",
  "chose_provider": "tavily",
  "candidates": ["tavily:Tavily"],
  "rejected": [],
  "downgraded": false,
  "fallback_count": 0,
  "decision_reason": "selected"
}
}
```

- `results[]` `object[]` — Normalized search result list. `content` is only populated when
  raw content was requested and returned by the backend.
- `usage.web_search_requests` `integer` — Lazu search request count, normally `1`.
- `usage.web_search_billable_units` `integer` — Provider billing units used for the charge. Tavily basic is 1 unit, Tavily
  advanced is 2 units, and Serper or Jina is normally 1 successful query.
- `provider_trace.backend` `string` — Actual provider selected after routing.
- `route_receipt` `object` (optional) — Candidate, fallback and rejection metadata. The same data is stored in the
  request log.

## Billing

Search backends are priced from their configured `search_price`.
The value is the USD price per provider billing unit, not always per HTTP
request.

Check the currently displayed search price and reconcile the `web_search` line item in request details. Do not infer a free service from an old example or deployment configuration.

| Backend | Unit mapping                               |
| ------- | ------------------------------------------ |
| Tavily  | `basic` = 1 credit; `advanced` = 2 credits |
| Serper  | 1 successful query = 1 unit                |
| Jina    | 1 successful query = 1 unit                |

Failed upstream calls, timeouts and invalid requests are refunded according to
the normal Lazu billing rules.

## See also

- [How pricing works](https://lazu.ai/docs/billing)
- [Request details](https://lazu.ai/docs/endpoints/usage-requests)
- [Model catalog](https://lazu.ai/docs/models/catalog)
