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

# Web Search BYOK

> Use your own Tavily, Exa, or Valyu API key for online search in chat completions.

**Bring Your Own Key (BYOK)** lets you use your own search provider credentials when using [Online Search](/guides/chat-completions/server-tools) (`@online`). Successful BYOK searches are not billed by Routeway for search usage — you pay the provider directly.

<Info>
  BYOK only affects **search** billing. Chat model token costs still apply as usual.
</Info>

***

## Platform search vs BYOK

By default, Routeway handles search for you when you append `@online` to a model ID. Daily limits and optional overage billing apply — see [Server Tools pricing](/guides/chat-completions/server-tools#pricing).

With BYOK, Routeway calls your chosen provider (Tavily, Exa, or Valyu) using credentials you supply. When BYOK is used successfully, Routeway does not charge for that search.

| Search path                      | Routeway daily limit | Routeway search charge                           |
| :------------------------------- | :------------------- | :----------------------------------------------- |
| **BYOK** (Tavily, Exa, or Valyu) | Not counted          | **\$0**                                          |
| **Platform search** (default)    | Yes                  | Free tier included; paid overage after daily cap |

If BYOK is attempted but fails (invalid key, provider error, etc.), Routeway falls back to platform search. Standard platform search limits and billing apply for that search.

Up to **3 search rounds** can run per chat request when the model needs multiple lookups.

***

## Supported providers

| Provider   | Value    | Notes                         |
| :--------- | :------- | :---------------------------- |
| **Tavily** | `tavily` | Keys often start with `tvly-` |
| **Exa**    | `exa`    |                               |
| **Valyu**  | `valyu`  |                               |

You can save one key per provider per account. Get API keys from your provider's dashboard:

* [Tavily](https://tavily.com)
* [Exa](https://exa.ai)
* [Valyu](https://valyu.ai)

***

## Quick start

1. Open [Dashboard → Settings](https://routeway.ai/dashboard/settings) and scroll to **Web Search Keys**.
2. Add a key for Tavily, Exa, or Valyu.
3. Enable **Prefer BYOK** so saved keys are used automatically on `@online` requests.

Then use `@online` as usual — no extra headers needed:

```python theme={null}
from openai import OpenAI

client = OpenAI(
    base_url="https://api.routeway.ai/v1",
    api_key=os.getenv("ROUTEWAY_API_KEY"),
)

response = client.chat.completions.create(
    model="gpt-4o@online",
    messages=[{"role": "user", "content": "What happened in AI this week?"}],
)
```

***

## How search is chosen

```mermaid theme={null}
flowchart TD
  start["Chat request with @online"]
  headerKey{"X-Web-Search-API-Key set?"}
  useRequest["Use request key + provider"]
  prefer{"Prefer BYOK enabled?"}
  stored{"Saved key for provider?"}
  byok["Call your provider"]
  platform["Platform search"]
  bill["Routeway limits + overage"]
  free["No Routeway search billing"]

  start --> headerKey
  headerKey -->|yes| useRequest --> byok
  headerKey -->|no| prefer
  prefer -->|yes| stored
  prefer -->|no| platform --> bill
  stored -->|yes| byok
  stored -->|no| platform --> bill
  byok -->|success| free
  byok -->|fail| platform --> bill
```

**Resolution order (highest priority first):**

1. **Per-request key** — `X-Web-Search-API-Key` (+ optional `X-Web-Search-Provider`)
2. **Saved key** — only when **Prefer BYOK** is enabled in [Settings](https://routeway.ai/dashboard/settings), or via the `X-Prefer-Web-Search-BYOK` header
3. **Platform search** — default fallback

***

## Per-request headers

For integrations that need to pass a key on each request (for example, multi-tenant apps), add these headers to `POST /v1/chat/completions` alongside your normal Routeway auth.

| Header                     | Required                     | Values                   | Purpose                                                          |
| :------------------------- | :--------------------------- | :----------------------- | :--------------------------------------------------------------- |
| `X-Web-Search-API-Key`     | For one-off BYOK             | Provider API key         | Use this key for search on **this request only**. Not stored.    |
| `X-Web-Search-Provider`    | Recommended with request key | `tavily`, `exa`, `valyu` | Which provider to call.                                          |
| `X-Prefer-Web-Search-BYOK` | Optional                     | `true` / `false`         | Override the **Prefer BYOK** dashboard setting for this request. |

**Behavior details:**

* **`X-Web-Search-API-Key` present** → BYOK is used for that request. **Prefer BYOK** does not need to be enabled.
* **`X-Web-Search-Provider` omitted** with a request key → Tavily is assumed; keys starting with `tvly-` are inferred as Tavily.
* **`X-Web-Search-Provider` only** (no API key) → selects which **saved** key to use, but only if **Prefer BYOK** is enabled (in Settings or via header).
* Headers are **case-insensitive** (`x-web-search-api-key` works).

If multiple providers are saved and no `X-Web-Search-Provider` is set, priority is: **tavily → exa → valyu**.

### Example: one-off Tavily key

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl https://api.routeway.ai/v1/chat/completions \
      -H "Authorization: Bearer $ROUTEWAY_API_KEY" \
      -H "X-Web-Search-API-Key: tvly-your-tavily-key" \
      -H "X-Web-Search-Provider: tavily" \
      -H "Content-Type: application/json" \
      -d '{
        "model": "gpt-4o@online",
        "messages": [
          {"role": "user", "content": "What happened in AI this week?"}
        ]
      }'
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import os
    from openai import OpenAI

    client = OpenAI(
        base_url="https://api.routeway.ai/v1",
        api_key=os.getenv("ROUTEWAY_API_KEY"),
        default_headers={
            "X-Web-Search-API-Key": os.getenv("TAVILY_API_KEY"),
            "X-Web-Search-Provider": "tavily",
        },
    )

    response = client.chat.completions.create(
        model="gpt-4o@online",
        messages=[{"role": "user", "content": "What happened in AI this week?"}],
    )
    ```
  </Tab>
</Tabs>

<Tip>
  Per-request keys are ideal for multi-tenant apps where each end user has their own search provider key. Keys sent in headers are never stored on Routeway's servers.
</Tip>

***

## Typical setups

<CardGroup cols={1}>
  <Card title="Dashboard — save key, always BYOK" icon="user">
    1. Add your provider key under [Settings → Web Search Keys](https://routeway.ai/dashboard/settings)
    2. Enable **Prefer BYOK**
    3. Call chat with `model: "...@online"` — no extra headers needed
  </Card>

  <Card title="Server integration — key per request" icon="server">
    Send `X-Web-Search-API-Key` (+ `X-Web-Search-Provider`) on each `@online` chat request. Good for multi-tenant apps where each end user has their own search key.
  </Card>

  <Card title="Default platform search — no BYOK" icon="globe">
    Use `@online` with no BYOK headers and **Prefer BYOK** turned off. Routeway handles search; normal daily limits and overage apply. See [Server Tools](/guides/chat-completions/server-tools#online-search).
  </Card>
</CardGroup>

***

## Security

Routeway treats search provider keys as sensitive credentials. Here's how they're handled:

<CardGroup cols={2}>
  <Card title="Encrypted at rest" icon="lock">
    Keys saved in the dashboard are encrypted before storage and are never stored in plain text. They are decrypted only in memory when required to perform a search request and are not logged in plaintext.
  </Card>

  <Card title="Masked after save" icon="eye-off">
    After you add a key, only the last four characters are shown in the dashboard. The full value cannot be retrieved later.
  </Card>

  <Card title="Separate from API keys" icon="key">
    Search provider keys are stored independently from your Routeway `sk-` API keys.
  </Card>

  <Card title="Per-request keys aren't stored" icon="timer">
    Keys sent via `X-Web-Search-API-Key` are used only for that request and are not saved to your account.
  </Card>
</CardGroup>

<Note>
  Routeway does not log or cache decrypted search provider keys. Keys are decrypted only when needed to make a search request to your chosen provider.
</Note>

### Best practices

* **Use the dashboard or headers** — save keys in [Settings → Web Search Keys](https://routeway.ai/dashboard/settings), or pass them via `X-Web-Search-API-Key`. Never include provider keys in chat messages, prompts, or model strings.
* **Use environment variables** — load keys from a secrets manager or environment variables in your application, not hardcoded in source code.
* **Rotate if exposed** — if a key may have been leaked, update it immediately in the dashboard. The old key is replaced as soon as you save a new one.
* **Scope keys at the provider** — create separate search API keys per environment (production, staging) in your provider's dashboard when possible.

***

## FAQ

<AccordionGroup>
  <Accordion title="Do I still pay for chat tokens when using BYOK?">
    Yes. BYOK only affects search billing. Model input and output tokens are billed at the usual rates for your chosen model.
  </Accordion>

  <Accordion title="What happens if my BYOK key fails?">
    Routeway falls back to platform search for that request. Standard platform search limits and billing apply for the fallback search.
  </Accordion>

  <Accordion title="Can I save keys for multiple providers?">
    Yes — one key per provider in [Settings → Web Search Keys](https://routeway.ai/dashboard/settings). If multiple are saved and no `X-Web-Search-Provider` is set, Routeway tries them in order: tavily → exa → valyu.
  </Accordion>

  <Accordion title="Where should I put my provider API key?">
    Save keys in the dashboard under **Web Search Keys**, or pass them per request via the `X-Web-Search-API-Key` header. **Do not** put provider keys in the chat message body or model string.
  </Accordion>

  <Accordion title="How do I rotate a saved key?">
    Open [Dashboard → Settings](https://routeway.ai/dashboard/settings), scroll to **Web Search Keys**, and update the key for your provider. The old key is replaced immediately.
  </Accordion>

  <Accordion title="Is it safe to save my search provider key in Routeway?">
    Yes. Saved keys are encrypted at rest and only decrypted when needed to perform a search. The full key is never shown again after you save it — only a short hint (last four characters) is displayed in the dashboard. Routeway does not log decrypted keys.
  </Accordion>
</AccordionGroup>
