## Индекс документации
Получите полный индекс документации по адресу: https://api.vega.chat/docs/llms.txt  
Используйте этот файл, чтобы узнать о всех доступных страницах перед дальнейшим изучением.

# Веб‑поиск

> Интеграция поиска в реальном времени с Responses API

Responses API поддерживает интеграцию веб‑поиска, позволяя моделям получать актуальную информацию из интернета и предоставлять ответы с правильными ссылками и аннотациями.

<Warning>
  **Устаревший подход к плагинам**

  Плагин веб‑поиска (`plugins: [{ id: "web" }]`), показанный ниже, устарел. Вместо него используйте [`openrouter:web_search` server tool](/docs/guides/features/server-tools/web-search), который работает как с Chat Completions, так и с Responses API через массив `tools`.
</Warning>

## Плагин веб‑поиска

Включите веб‑поиск с помощью параметра `plugins`:

<CodeGroup>
  ```typescript title="TypeScript" lines theme={null}
  const response = await fetch('https://openrouter.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/o4-mini',
      input: 'What is OpenRouter?',
      plugins: [{ id: 'web', max_results: 3 }],
      max_output_tokens: 9000,
    }),
  });

  const result = await response.json();
  console.log(result);
  ```

  ```python title="Python" lines theme={null}
  import requests

  response = requests.post(
      'https://openrouter.ai/api/v1/responses',
      headers={
          'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
          'Content-Type': 'application/json',
      },
      json={
          'model': 'openai/o4-mini',
          'input': 'What is OpenRouter?',
          'plugins': [{'id': 'web', 'max_results': 3}],
          'max_output_tokens': 9000,
      }
  )

  result = response.json()
  print(result)
  ```

  ```bash title="cURL" lines theme={null}
  curl -X POST https://openrouter.ai/api/v1/responses \
    -H "Authorization: Bearer YOUR_OPENROUTER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/o4-mini",
      "input": "What is OpenRouter?",
      "plugins": [{"id": "web", "max_results": 3}],
      "max_output_tokens": 9000
    }'
  ```
</CodeGroup>

## Конфигурация плагина

Настройте поведение веб‑поиска:

| Параметр            | Тип       | Описание                                                                                 |
| ------------------- | --------- | ------------------------------------------------------------------------------------------ |
| `id`                | string    | **Обязательно.** Должно быть `"web"`                                                       |
| `engine`            | string    | Поисковый движок: `"native"`, `"exa"`, `"firecrawl"`, `"parallel"` или опустить для авто |
| `max_results`       | integer   | Максимальное количество результатов (1–25; 1–20 для Perplexity; по умолчанию 5)            |
| `include_domains`   | string[]  | Ограничить результаты указанными доменами (поддерживает подстановки, например `*.substack.com`) |
| `exclude_domains`   | string[]  | Исключить результаты из указанных доменов                                                |

Смотрите [документацию плагина Web Search](/docs/guides/features/plugins/web-search) для полного описания выбора движка, совместимости фильтров доменов и цен.

## Фильтры X‑поиска (только SpaceXAI)

При использовании моделей SpaceXAI (например, `x-ai/grok-4.1-fast`) можно передать `x_search_filter` как параметр верхнего уровня запроса для фильтрации результатов поиска X/Twitter:

```json lines theme={null}
{
  "model": "x-ai/grok-4.1-fast",
  "input": "What are people saying about AI?",
  "plugins": [{ "id": "web" }],
  "x_search_filter": {
    "allowed_x_handles": ["OpenRouterAI"],
    "from_date": "2025-01-01",
    "enable_image_understanding": true
  }
}
```

| Параметр                    | Тип       | Описание                                          |
| --------------------------- | --------- | ------------------------------------------------- |
| `allowed_x_handles`         | string[]  | Включить только сообщения от этих аккаунтов (max 20) |
| `excluded_x_handles`        | string[]  | Исключить сообщения от этих аккаунтов (max 20)   |
| `from_date`                 | string    | Дата начала (ISO 8601, например `"2025-01-01"`)   |
| `to_date`                   | string    | Дата окончания (ISO 8601, например `"2025-12-31"`) |
| `enable_image_understanding`| boolean   | Анализировать изображения в постах               |
| `enable_video_understanding`| boolean   | Анализировать видео в постах                     |

<Warning>
  `allowed_x_handles` и `excluded_x_handles` **взаимоисключающие**. Подробнее см. в [документации плагина Web Search](/docs/guides/features/plugins/web-search#x-search-filters-spacexai-only).
</Warning>

## Структурированное сообщение с веб‑поиском

Используйте структурированные сообщения для более сложных запросов:

<CodeGroup>
  ```typescript title="TypeScript" expandable lines theme={null}
  const response = await fetch('https://openrouter.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/o4-mini',
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: 'What was a positive news story from today?',
            },
          ],
        },
      ],
      plugins: [{ id: 'web', max_results: 2 }],
      max_output_tokens: 9000,
    }),
  });

  const result = await response.json();
  console.log(result);
  ```

  ```python title="Python" expandable lines theme={null}
  import requests

  response = requests.post(
      'https://openrouter.ai/api/v1/responses',
      headers={
          'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
          'Content-Type': 'application/json',
      },
      json={
          'model': 'openai/o4-mini',
          'input': [
              {
                  'type': 'message',
                  'role': 'user',
                  'content': [
                      {
                          'type': 'input_text',
                          'text': 'What was a positive news story from today?',
                      },
                  ],
              },
          ],
          'plugins': [{'id': 'web', 'max_results': 2}],
          'max_output_tokens': 9000,
      }
  )

  result = response.json()
  print(result)
  ```
</CodeGroup>

## Онлайн‑варианты моделей

<Warning>
  **Устарело**

  Вариант `:online` устарел. Вместо него используйте [`openrouter:web_search` server tool](/docs/guides/features/server-tools/web-search).
</Warning>

Некоторые модели имеют встроенные возможности веб‑поиска через вариант `:online`:

<CodeGroup>
  ```typescript title="TypeScript" lines theme={null}
  const response = await fetch('https://openrouter.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/o4-mini:online',
      input: 'What was a positive news story from today?',
      max_output_tokens: 9000,
    }),
  });

  const result = await response.json();
  console.log(result);
  ```

  ```python title="Python" lines theme={null}
  import requests

  response = requests.post(
      'https://openrouter.ai/api/v1/responses',
      headers={
          'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
          'Content-Type': 'application/json',
      },
      json={
          'model': 'openai/o4-mini:online',
          'input': 'What was a positive news story from today?',
          'max_output_tokens': 9000,
      }
  )

  result = response.json()
  print(result)
  ```
</CodeGroup>

## Ответ с аннотациями

Ответы веб‑поиска включают аннотации‑цитаты:

```json expandable lines theme={null}
{
  "id": "resp_1234567890",
  "object": "response",
  "created_at": 1234567890,
  "model": "openai/o4-mini",
  "output": [
    {
      "type": "message",
      "id": "msg_abc123",
      "status": "completed",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "OpenRouter is a unified API for accessing multiple Large Language Model providers through a single interface. It allows developers to access 100+ AI models from providers like OpenAI, Anthropic, Google, and others with intelligent routing and automatic failover.",
          "annotations": [
            {
              "type": "url_citation",
              "url": "https://openrouter.ai/docs",
              "start_index": 0,
              "end_index": 85
            },
            {
              "type": "url_citation",
              "url": "https://openrouter.ai/models",
              "start_index": 120,
              "end_index": 180
            }
          ]
        }
      ]
    }
  ],
  "usage": {
    "input_tokens": 15,
    "output_tokens": 95,
    "total_tokens": 110
  },
  "status": "completed"
}
```

## Типы аннотаций

Ответы веб‑поиска могут включать разные типы аннотаций:

### URL‑цитата

```json lines theme={null}
{
  "type": "url_citation",
  "url": "https://example.com/article",
  "start_index": 0,
  "end_index": 50,
  "content": "Excerpt from the web page..."
}
```

## Сложные поисковые запросы

Обработка многочастных запросов:

<CodeGroup>
  ```typescript title="TypeScript" expandable lines theme={null}
  const response = await fetch('https://openrouter.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/o4-mini',
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: 'Compare OpenAI and Anthropic latest models',
            },
          ],
        },
      ],
      plugins: [{ id: 'web', max_results: 5 }],
      max_output_tokens: 9000,
    }),
  });

  const result = await response.json();
  console.log(result);
  ```

  ```python title="Python" expandable lines theme={null}
  import requests

  response = requests.post(
      'https://openrouter.ai/api/v1/responses',
      headers={
          'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
          'Content-Type': 'application/json',
      },
      json={
          'model': 'openai/o4-mini',
          'input': [
              {
                  'type': 'message',
                  'role': 'user',
                  'content': [
                      {
                          'type': 'input_text',
                          'text': 'Compare OpenAI and Anthropic latest models',
                      },
                  ],
              },
          ],
          'plugins': [{'id': 'web', 'max_results': 5}],
          'max_output_tokens': 9000,
      }
  )

  result = response.json()
  print(result)
  ```
</CodeGroup>

## Веб‑поиск в диалоге

Включите веб‑поиск в многошаговых беседах:

<CodeGroup>
  ```typescript title="TypeScript" expandable lines theme={null}
  const response = await fetch('https://openrouter.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/o4-mini',
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: 'What is the latest version of React?',
            },
          ],
        },
        {
          type: 'message',
          id: 'msg_1',
          status: 'in_progress',
          role: 'assistant',
          content: [
            {
              type: 'output_text',
              text: 'Let me search for the latest React version.',
              annotations: [],
            },
          ],
        },
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: 'Yes, please find the most recent information',
            },
          ],
        },
      ],
      plugins: [{ id: 'web', max_results: 2 }],
      max_output_tokens: 9000,
    }),
  });

  const result = await response.json();
  console.log(result);
  ```

  ```python title="Python" expandable lines theme={null}
  import requests

  response = requests.post(
      'https://openrouter.ai/api/v1/responses',
      headers={
          'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
          'Content-Type': 'application/json',
      },
      json={
          'model': 'openai/o4-mini',
          'input': [
              {
                  'type': 'message',
                  'role': 'user',
                  'content': [
                      {
                          'type': 'input_text',
                          'text': 'What is the latest version of React?',
                      },
                  ],
              },
              {
                  'type': 'message',
                  'id': 'msg_1',
                  'status': 'in_progress',
                  'role': 'assistant',
                  'content': [
                      {
                          'type': 'output_text',
                          'text': 'Let me search for the latest React version.',
                          'annotations': [],
                      },
                  ],
              },
              {
                  'type': 'message',
                  'role': 'user',
                  'content': [
                      {
                          'type': 'input_text',
                          'text': 'Yes, please find the most recent information',
                      },
                  ],
              },
          ],
          'plugins': [{'id': 'web', 'max_results': 2}],
          'max_output_tokens': 9000,
      }
  )

  result = response.json()
  print(result)
  ```
</CodeGroup>

## Потоковый веб‑поиск

Отслеживание прогресса веб‑поиска в режиме стриминга:

<CodeGroup>
  ```typescript title="TypeScript" expandable lines theme={null}
  const response = await fetch('https://openrouter.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/o4-mini',
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: 'What is the latest news about AI?',
            },
          ],
        },
      ],
      plugins: [{ id: 'web', max_results: 2 }],
      stream: true,
      max_output_tokens: 9000,
    }),
  });

  const reader = response.body?.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    const chunk = decoder.decode(value);
    const lines = chunk.split('\n');

    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const data = line.slice(6);
        if (data === '[DONE]') return;

        try {
          const parsed = JSON.parse(data);
          if (parsed.type === 'response.output_item.added' &&
              parsed.item?.type === 'message') {
            console.log('Message added');
          }
          if (parsed.type === 'response.completed') {
            const annotations = parsed.response?.output
              ?.find(o => o.type === 'message')
              ?.content?.find(c => c.type === 'output_text')
              ?.annotations || [];
            console.log('Citations:', annotations.length);
          }
        } catch (e) {
          // Skip invalid JSON
        }
      }
    }
  }
  ```

  ```python title="Python" expandable lines theme={null}
  import requests
  import json

  response = requests.post(
      'https://openrouter.ai/api/v1/responses',
      headers={
          'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
          'Content-Type': 'application/json',
      },
      json={
          'model': 'openai/o4-mini',
          'input': [
              {
                  'type': 'message',
                  'role': 'user',
                  'content': [
                      {
                          'type': 'input_text',
                          'text': 'What is the latest news about AI?',
                      },
                  ],
              },
          ],
          'plugins': [{'id': 'web', 'max_results': 2}],
          'stream': True,
          'max_output_tokens': 9000,
      },
      stream=True
  )

  for line in response.iter_lines():
      if line:
          line_str = line.decode('utf-8')
          if line_str.startswith('data: '):
              data = line_str[6:]
              if data == '[DONE]':
                  break
              try:
                  parsed = json.loads(data)
                  if (parsed.get('type') == 'response.output_item.added' and
                      parsed.get('item', {}).get('type') == 'message'):
                      print('Message added')
                  if parsed.get('type') == 'response.completed':
                      output = parsed.get('response', {}).get('output', [])
                      message = next((o for o in output if o.get('type') == 'message'), {})
                      content = message.get('content', [])
                      text_content = next((c for c in content if c.get('type') == 'output_text'), {})
                      annotations = text_content.get('annotations', [])
                      print(f'Citations: {len(annotations)}')
              except json.JSONDecodeError:
                  continue
  ```
</CodeGroup>

## Обработка аннотаций

Извлечение и обработка информации о цитатах:

<CodeGroup>
  ```typescript title="TypeScript" lines theme={null}
  function extractCitations(response: any) {
    const messageOutput = response.output?.find((o: any) => o.type === 'message');
    const textContent = messageOutput?.content?.find((c: any) => c.type === 'output_text');
    const annotations = textContent?.annotations || [];

    return annotations
      .filter((annotation: any) => annotation.type === 'url_citation')
      .map((annotation: any) => ({
        url: annotation.url,
        text: textContent.text.slice(annotation.start_index, annotation.end_index),
        startIndex: annotation.start_index,
        endIndex: annotation.end_index,
      }));
  }

  const result = await response.json();
  const citations = extractCitations(result);
  console.log('Found citations:', citations);
  ```

  ```python title="Python" expandable lines theme={null}
  def extract_citations(response_data):
      output = response_data.get('output', [])
      message_output = next((o for o in output if o.get('type') == 'message'), {})
      content = message_output.get('content', [])
      text_content = next((c for c in content if c.get('type') == 'output_text'), {})
      annotations = text_content.get('annotations', [])
      text = text_content.get('text', '')

      citations = []
      for annotation in annotations:
          if annotation.get('type') == 'url_citation':
              citations.append({
                  'url': annotation.get('url'),
                  'text': text[annotation.get('start_index', 0):annotation.get('end_index', 0)],
                  'start_index': annotation.get('start_index'),
                  'end_index': annotation.get('end_index'),
              })

      return citations

  result = response.json()
  citations = extract_citations(result)
  print(f'Found citations: {citations}')
  ```
</CodeGroup>

## Лучшие практики

1. **Ограничьте количество результатов**: используйте подходящее `max_results` для баланса качества и скорости.  
2. **Обрабатывайте аннотации**: используйте цитатные аннотации для корректного указания источников.  
3. **Конкретность запросов**: формулируйте запросы точно, чтобы получать более релевантные результаты.  
4. **Обработка ошибок**: учитывайте случаи, когда веб‑поиск может завершиться неудачей.  
5. **Ограничения по частоте**: соблюдайте лимиты запросов к поисковому сервису.

## Следующие шаги

* Узнайте о интеграции [Tool Calling](./tool-calling)  
* Исследуйте возможности [Reasoning](./reasoning)  
* Ознакомьтесь с основами [Basic Usage](./basic-usage)