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

# Exa integration guide

[Exa](https://exa.ai) is a web search API built for AI applications. It returns clean, ready-to-use page content with every result, making it easy to ground SambaNova model responses in current web data.

## Prerequisites

Before starting, ensure you have:

* A [SambaCloud](https://cloud.sambanova.ai?utm_source=exa\&utm_medium=external\&utm_campaign=cloud_signup) account and [API key](https://cloud.sambanova.ai/apis?utm_source=exa\&utm_medium=external\&utm_campaign=cloud_signup)
* An [Exa](https://dashboard.exa.ai/api-keys) account and API key
* Python 3.9+ or Node.js 18+

## Setup

Follow the steps below to install the required dependencies and configure your environment.

<Steps>
  <Step title="Install dependencies">
    Install the required SDKs for your preferred language.

    <Tabs>
      <Tab title="Python">
        ```bash theme={null}
        pip install "exa-py>=2.0" openai python-dotenv
        ```
      </Tab>

      <Tab title="Node.js">
        ```bash theme={null}
        npm install exa-js openai dotenv
        ```
      </Tab>
    </Tabs>

    <Note>
      The Node.js examples use ES modules and top-level `await`. Save them with a `.mjs` extension (or set `"type": "module"` in your `package.json`).
    </Note>
  </Step>

  <Step title="Configure API keys">
    Create a `.env` file in your project directory:

    ```bash theme={null}
    SAMBANOVA_API_KEY=your-sambanova-api-key
    EXA_API_KEY=your-exa-api-key
    ```
  </Step>

  <Step title="Search the web with Exa">
    Use Exa to retrieve relevant web content and highlights for your query.

    <Tabs>
      <Tab title="Python">
        ```python theme={null}
        from dotenv import load_dotenv
        from exa_py import Exa
        import os

        load_dotenv()

        exa = Exa(api_key=os.environ["EXA_API_KEY"])

        results = exa.search(
            "latest developments in AI agents",
            type="auto",
            num_results=10,
            contents={"highlights": True},
        )
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={null}
        import 'dotenv/config';
        import Exa from 'exa-js';

        const exa = new Exa(process.env.EXA_API_KEY);

        const results = await exa.search(
          'latest developments in AI agents',
          {
            type: 'auto',
            numResults: 10,
            contents: { highlights: true },
          }
        );
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Ground a SambaNova model with search results">
    Using the `results` from the previous step, format the Exa search results as context and pass them to a SambaNova-hosted model.

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

        load_dotenv()

        client = OpenAI(
            api_key=os.environ["SAMBANOVA_API_KEY"],
            base_url="https://api.sambanova.ai/v1",
        )

        context = "\n\n".join(
            f"Source: {result.url}\n{' '.join(result.highlights or [])}"
            for result in results.results
        )

        response = client.chat.completions.create(
            model="MiniMax-M2.7",
            messages=[
                {
                    "role": "system",
                    "content": "Using only the provided search results, write a short summary.",
                },
                {
                    "role": "user",
                    "content": f"Search results:\n\n{context}",
                },
            ],
        )

        print(response.choices[0].message.content)
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={null}
        import 'dotenv/config';
        import OpenAI from 'openai';

        const client = new OpenAI({
          apiKey: process.env.SAMBANOVA_API_KEY,
          baseURL: 'https://api.sambanova.ai/v1',
        });

        const context = results.results
          .map(
            (result) =>
              `Source: ${result.url}\n${(result.highlights || []).join(' ')}`
          )
          .join('\n\n');

        const response = await client.chat.completions.create({
          model: 'MiniMax-M2.7',
          messages: [
            {
              role: 'system',
              content:
                'Using only the provided search results, write a short summary.',
            },
            {
              role: 'user',
              content: `Search results:\n\n${context}`,
            },
          ],
        });

        console.log(response.choices[0].message.content);
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="(Optional) Enable tool calling with Exa">
    For agentic workflows, expose Exa search as a function tool so the model can decide when to search the web.

    <Tabs>
      <Tab title="Python">
        ```python theme={null}
        from dotenv import load_dotenv
        from exa_py import Exa
        from openai import OpenAI
        import os
        import json

        load_dotenv()

        exa = Exa(api_key=os.environ["EXA_API_KEY"])
        client = OpenAI(
            api_key=os.environ["SAMBANOVA_API_KEY"],
            base_url="https://api.sambanova.ai/v1",
        )

        tools = [
            {
                "type": "function",
                "function": {
                    "name": "exa_search",
                    "description": "Search the web using Exa and return grounded results.",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "query": {
                                "type": "string",
                                "description": "The search query.",
                            }
                        },
                        "required": ["query"],
                    },
                },
            }
        ]

        messages = [
            {"role": "user", "content": "What are the latest developments in AI agents?"}
        ]

        response = client.chat.completions.create(
            model="MiniMax-M2.7",
            messages=messages,
            tools=tools,
        )

        if response.choices[0].finish_reason == "tool_calls":
            tool_call = response.choices[0].message.tool_calls[0]
            args = json.loads(tool_call.function.arguments)

            search_results = exa.search(
                args["query"],
                type="auto",
                num_results=5,
                contents={"highlights": True},
            )

            context = "\n\n".join(
                f"Source: {r.url}\n{' '.join(r.highlights or [])}"
                for r in search_results.results
            )

            messages.append(response.choices[0].message)
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": context,
            })

            final_response = client.chat.completions.create(
                model="MiniMax-M2.7",
                messages=messages,
                tools=tools,
            )

            print(final_response.choices[0].message.content)
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={null}
        import 'dotenv/config';
        import Exa from 'exa-js';
        import OpenAI from 'openai';

        const exa = new Exa(process.env.EXA_API_KEY);
        const client = new OpenAI({
          apiKey: process.env.SAMBANOVA_API_KEY,
          baseURL: 'https://api.sambanova.ai/v1',
        });

        const tools = [
          {
            type: 'function',
            function: {
              name: 'exa_search',
              description: 'Search the web using Exa and return grounded results.',
              parameters: {
                type: 'object',
                properties: {
                  query: { type: 'string', description: 'The search query.' },
                },
                required: ['query'],
              },
            },
          },
        ];

        const messages = [
          { role: 'user', content: 'What are the latest developments in AI agents?' },
        ];

        const response = await client.chat.completions.create({
          model: 'MiniMax-M2.7',
          messages,
          tools,
        });

        if (response.choices[0].finish_reason === 'tool_calls') {
          const toolCall = response.choices[0].message.tool_calls[0];
          const args = JSON.parse(toolCall.function.arguments);

          const searchResults = await exa.search(args.query, {
            type: 'auto',
            numResults: 5,
            contents: { highlights: true },
          });

          const context = searchResults.results
            .map((r) => `Source: ${r.url}\n${(r.highlights || []).join(' ')}`)
            .join('\n\n');

          messages.push(response.choices[0].message);
          messages.push({
            role: 'tool',
            tool_call_id: toolCall.id,
            content: context,
          });

          const finalResponse = await client.chat.completions.create({
            model: 'MiniMax-M2.7',
            messages,
            tools,
          });

          console.log(finalResponse.choices[0].message.content);
        }
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

## Search modes and freshness controls

Exa supports multiple search strategies:

| Search type | Best for                                        |
| ----------- | ----------------------------------------------- |
| `auto`      | Recommended. Best balance of quality and speed. |
| `fast`      | Lowest-latency search experience.               |
| `deep`      | Most comprehensive search coverage.             |

Use `max_age_hours` (Python) or `maxAgeHours` (Node.js) to control how recent the returned content must be. Setting this to `0` forces Exa to fetch only live content, while `24` permits results up to one day old.

## Example use cases

Here are some common use cases this integration enables:

* Ground chatbot responses with current web information
* Build research assistants with source citations
* Retrieve recent news and developments
* Add web search capabilities to AI agents
* Create retrieval-augmented generation (RAG) workflows without maintaining your own search infrastructure

## Additional resources

* [Exa Documentation](https://exa.ai/docs): Full reference for the Exa Python and Node.js SDKs
* [Exa Search API Reference](https://exa.ai/docs/reference/search): Detailed API parameters and response schemas
* [SambaNova Documentation](/en/): Model options, API endpoints, and usage guides
