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

> ## Agent Instructions
> The Exa API is served at https://api.exa.ai. Authenticate with `Authorization: Bearer $EXA_API_KEY` (or `x-api-key: $EXA_API_KEY`); create keys at https://dashboard.exa.ai/api-keys?utm_source=docs&utm_medium=docs&utm_campaign=markdown_instructions.
> Prefer the official SDKs, `exa-py` (`pip install exa-py`) and `exa-js` (`npm install exa-js`); both read `EXA_API_KEY` from the environment.
> Tool-using agents can call Exa without writing code through the hosted MCP server at https://mcp.exa.ai/mcp, or install the Exa agent skill with `npx skills add exa-labs/agent-skills` (skill file: https://exa.ai/docs/skill.md).
> The OpenAPI specs at https://exa.ai/docs/exa-spec.yaml and https://exa.ai/docs/team-management-spec.yaml are the source of truth for request and response schemas.

# Fireworks

> Give open models on Fireworks live web search and page contents with Exa tool calling.

[Fireworks](https://fireworks.ai) serves open models such as Kimi, GLM, DeepSeek, and Qwen through an OpenAI-compatible API. Exa gives those models live web search and full page contents. Point the OpenAI SDK at Fireworks, pass it the Exa SDK's ready-made tools, and any Fireworks model that supports function calling can search the web and read the pages it finds.

## Get started

**1. Install the SDKs**

```bash Python theme={null}
pip install openai exa_py
```

```bash JavaScript theme={null}
npm install openai exa-js
```

**2. Set up your API keys**

Set the `EXA_API_KEY` and `FIREWORKS_API_KEY` environment variables. Create a Fireworks key in the [Fireworks dashboard](https://app.fireworks.ai/settings/users/api-keys) and an Exa key in the [Exa dashboard](https://dashboard.exa.ai/api-keys?utm_source=docs\&utm_medium=docs\&utm_campaign=integrations_fireworks).

> **[Get your Exa API key](https://dashboard.exa.ai/api-keys?utm_source=docs\&utm_medium=docs\&utm_campaign=get_key_card)**
>
> Create a key in the dashboard. New accounts start with free credits.

**3. Run the tool loop**

Create an OpenAI client with the Fireworks base URL and pass the Exa tools in `tools`. `handle_tool_calls` runs every Exa tool call in the model's message and returns the `role: "tool"` messages to append. Repeat until the model answers without tool calls.

```python Python theme={null}
import os

from exa_py import Exa
from openai import OpenAI

exa = Exa()  # reads EXA_API_KEY from the environment
fireworks = OpenAI(
    api_key=os.environ["FIREWORKS_API_KEY"],
    base_url="https://api.fireworks.ai/inference/v1",
)

MODEL = "accounts/fireworks/models/kimi-k3"
tools = [exa.openai.web_search(), exa.openai.get_contents()]
messages = [
    {"role": "user", "content": "What were the major AI announcements this week?"}
]

while True:
    completion = fireworks.chat.completions.create(
        model=MODEL,
        messages=messages,
        tools=tools,
    )
    message = completion.choices[0].message
    messages.append(message)
    if not message.tool_calls:
        break
    messages += exa.openai.handle_tool_calls(message)

print(message.content)
```

```javascript JavaScript theme={null}
import Exa from "exa-js";
import { OpenAI } from "openai";

const exa = new Exa(); // reads EXA_API_KEY from the environment
const fireworks = new OpenAI({
  apiKey: process.env.FIREWORKS_API_KEY,
  baseURL: "https://api.fireworks.ai/inference/v1",
});

const MODEL = "accounts/fireworks/models/kimi-k3";
const tools = [exa.openai.webSearch(), exa.openai.getContents()];
const messages = [
  { role: "user", content: "What were the major AI announcements this week?" },
];

while (true) {
  const completion = await fireworks.chat.completions.create({
    model: MODEL,
    messages,
    tools,
  });
  const message = completion.choices[0].message;
  messages.push(message);
  if (!message.tool_calls?.length) {
    console.log(message.content);
    break;
  }
  messages.push(...(await exa.openai.handleToolCalls(message)));
}
```

`web_search` finds pages the model has not seen. `get_contents` reads pages it already has URLs for, from an earlier search or from the user. Register either or both.

Any Fireworks model with function calling works. Swap `MODEL` for another ID from the [Fireworks model library](https://fireworks.ai/models), or for your own fine-tuned model or on-demand deployment.

## Configuring the tools

Calling the factories with no arguments gives Exa's recommended defaults. The search tool runs a `type="auto"` search with `contents={"highlights": True}`, which returns query-relevant excerpts from each result. The contents tool returns page text. Keyword arguments you pass to a factory override these defaults, and a custom `name` lets you run differently configured Exa tools side by side. See [OpenAI tool calling](https://exa.ai/docs/integrations/tool-calling/openai.md#configuring-the-tools) for every option, mixing in your own tools, and writing the loop by hand.

## Search first, then generate

When your code decides what to search, skip tool calling. Run one Exa search with contents and pass the results to a Fireworks model as numbered sources. This fits pipelines such as research briefs, monitoring digests, and dataset generation.

```python Python theme={null}
results = exa.search(
    "federated fine-tuning of LLMs with LoRA",
    type="auto",
    category="publication",
    num_results=10,
    contents={"highlights": True},
)

sources = "\n\n".join(
    f"[{i}] {r.title}\n{r.url}\n{' '.join(r.highlights)}"
    for i, r in enumerate(results.results, start=1)
)

completion = fireworks.chat.completions.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "Answer only from the numbered sources and cite them by number."},
        {"role": "user", "content": f"Sources:\n\n{sources}\n\nSummarize the main approaches and their tradeoffs."},
    ],
)
print(completion.choices[0].message.content)
```

Use `contents={"text": True}` instead of highlights when the model needs full page text. See [search best practices](https://exa.ai/docs/search/best-practices.md) for choosing a search type and filters.

## Pricing

Exa calls bill to your Exa account at standard [Exa pricing](https://exa.ai/pricing). Fireworks bills model tokens to your Fireworks account.

## Resources

> **[Fireworks tool calling](https://docs.fireworks.ai/guides/function-calling)**
>
> Tool definitions, supported models, and tool choice options on Fireworks.

> **[Cookbook](https://exa.ai/customers/fireworks)**
>
> Build a research assistant with Exa search and Fireworks models, with a runnable notebook.
