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

# Quickstart

> Get started with Foil in 5 minutes

# Quickstart

This guide will get you from zero to traced AI calls in under 5 minutes.

## Prerequisites

* A Foil account ([sign up here](https://app.getfoil.ai))
* An API key from the Foil dashboard
* Node.js 18+ or Python 3.8+

## Option A: Use the Foil Wizard (Recommended)

The fastest way to integrate. The Foil Wizard is an AI agent that scans your codebase and automatically adds Foil instrumentation.

```bash theme={null}
npx @getfoil/wizard
```

<Note>
  The wizard edits your source files. We recommend running it on a separate branch.
</Note>

The wizard will install the SDK, identify your LLM calls and agent patterns, and add tracing automatically. Review the changes, test, and merge when you're happy.

<Card title="Wizard Documentation" icon="wand-magic-sparkles" href="/features/wizard">
  Full guide on what the wizard instruments, troubleshooting, and rate limits
</Card>

***

## Option B: Manual Integration

Prefer to wire things up yourself? Follow the steps below.

## Step 1: Install the SDK

<Tabs>
  <Tab title="JavaScript">
    ```bash theme={null}
    npm install @getfoil/foil-js
    ```
  </Tab>

  <Tab title="Python">
    ```bash theme={null}
    pip install foil-sdk
    ```
  </Tab>
</Tabs>

## Step 2: Initialize Foil

<Tabs>
  <Tab title="JavaScript">
    The primary SDK — works with **any LLM provider** and gives you nested span trees.

    ```javascript theme={null}
    const { Foil } = require('@getfoil/foil-js');

    const foil = new Foil({
      apiKey: process.env.FOIL_API_KEY,
      agentName: 'my-first-agent',
    });
    ```
  </Tab>

  <Tab title="JavaScript (Auto-Instrumentation)">
    Zero-code tracing for supported providers (OpenAI, Anthropic, etc.).

    ```javascript theme={null}
    const OpenAI = require('openai');
    const { Foil } = require('@getfoil/foil-js');

    const foil = new Foil({
      apiKey: process.env.FOIL_API_KEY,
      agentName: 'my-first-agent',
      instrumentModules: { openAI: OpenAI },
    });
    ```
  </Tab>

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

    foil = Foil(api_key=os.environ['FOIL_API_KEY'])
    ```
  </Tab>
</Tabs>

## Step 3: Trace Your First Call

<Tabs>
  <Tab title="JavaScript">
    Use `foil.trace()` and `ctx.llmCall()` for full control over your span tree.

    ```javascript theme={null}
    const { Foil } = require('@getfoil/foil-js');
    const OpenAI = require('openai');

    const openai = new OpenAI();
    const foil = new Foil({
      apiKey: process.env.FOIL_API_KEY,
      agentName: 'my-first-agent',
    });

    const result = await foil.trace(async (ctx) => {
      // Create an LLM span
      const response = await ctx.llmCall('gpt-4o', async () => {
        return await openai.chat.completions.create({
          model: 'gpt-4o',
          messages: [{ role: 'user', content: 'What is the capital of France?' }],
        });
      });

      return response.choices[0].message.content;
    }, { name: 'capital-query' });

    console.log(result); // "Paris"
    await foil.shutdown();
    ```
  </Tab>

  <Tab title="JavaScript (Auto-Instrumentation)">
    Auto-instrumentation traces LLM calls automatically. Combine with `ctx.executeTools()` for agentic tool calling:

    ```javascript theme={null}
    const OpenAI = require('openai');
    const { Foil } = require('@getfoil/foil-js');

    const foil = new Foil({
      apiKey: process.env.FOIL_API_KEY,
      agentName: 'my-first-agent',
      instrumentModules: { openAI: OpenAI },
    });

    const openai = new OpenAI();

    // Define tools the LLM can call
    const tools = [{
      type: 'function',
      function: {
        name: 'get_capital',
        description: 'Get the capital city of a country',
        parameters: {
          type: 'object',
          properties: { country: { type: 'string' } },
          required: ['country'],
        },
      },
    }];

    const toolMap = {
      get_capital: async (args) => ({ capital: 'Paris', country: args.country }),
    };

    const result = await foil.trace(async (ctx) => {
      const messages = [{ role: 'user', content: 'What is the capital of France?' }];

      // LLM call is auto-traced — no wrapper needed
      let response = await openai.chat.completions.create({
        model: 'gpt-4o',
        messages,
        tools,
      });

      // LLM decides to call tools — executeTools traces each one
      while (response.choices[0].message.tool_calls) {
        const toolMessages = await ctx.executeTools(response, toolMap);
        messages.push(response.choices[0].message, ...toolMessages);
        response = await openai.chat.completions.create({
          model: 'gpt-4o', messages, tools,
        });
      }

      return response.choices[0].message.content;
    }, { name: 'capital-query' });

    console.log(result);
    await foil.shutdown();
    ```
  </Tab>

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

    client = OpenAI()
    foil = Foil(api_key=os.environ['FOIL_API_KEY'])

    # Wrap OpenAI client - all calls automatically traced
    wrapped_client = foil.wrap_openai(client)

    # Make the API call - automatically traced
    response = wrapped_client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': 'What is the capital of France?'}]
    )

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

## Step 4: View Your Trace

1. Go to the [Foil Dashboard](https://app.getfoil.ai)
2. Navigate to **Traces**
3. Click on your trace to see the full span details

You'll see:

* The input and output of your LLM call
* Token usage breakdown
* Latency metrics
* Any errors or warnings

## What's Next?

<CardGroup cols={2}>
  <Card title="Foil Wizard" icon="wand-magic-sparkles" href="/features/wizard">
    AI-powered automatic instrumentation
  </Card>

  <Card title="JavaScript SDK" icon="js" href="/sdks/javascript/index">
    Nested spans, tools, signals, and feedback
  </Card>

  <Card title="Auto-Instrumentation" icon="circle-nodes" href="/sdks/javascript/index#auto-instrumentation">
    Zero-code tracing for supported providers
  </Card>

  <Card title="Set Up Alerts" icon="bell" href="/features/alerting">
    Get notified when issues occur
  </Card>

  <Card title="Record Feedback" icon="thumbs-up" href="/concepts/signals">
    Capture user feedback on your AI outputs
  </Card>
</CardGroup>

<Tip>
  **More examples**: Browse complete, runnable examples at [github.com/getfoil/foil-examples](https://github.com/getfoil/foil-examples) — including auto-instrumentation, custom evaluations, semantic search, and real-world agent scenarios.
</Tip>

## Complete Example

Here's a full working example with an agentic tool-calling loop — the LLM decides which tools to call:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    // app.js
    const { Foil } = require('@getfoil/foil-js');
    const OpenAI = require('openai');

    const openai = new OpenAI();
    const foil = new Foil({
      apiKey: process.env.FOIL_API_KEY,
      agentName: 'quickstart-agent',
      instrumentModules: { openAI: OpenAI },
    });

    // Define tools the LLM can call
    const tools = [{
      type: 'function',
      function: {
        name: 'web_search',
        description: 'Search the web for information',
        parameters: {
          type: 'object',
          properties: { query: { type: 'string' } },
          required: ['query'],
        },
      },
    }];

    // Map tool names to implementations
    const toolMap = {
      web_search: async (args) => {
        // Replace with your actual search implementation
        return { results: [`Top result for "${args.query}": Paris is the capital of France...`] };
      },
    };

    async function main() {
      const result = await foil.trace(async (ctx) => {
        const messages = [
          { role: 'system', content: 'You are a helpful research assistant. Use the web_search tool to find information before answering.' },
          { role: 'user', content: 'What are the top attractions in Paris?' },
        ];

        // LLM calls are auto-instrumented, no ctx.llmCall() needed
        let response = await openai.chat.completions.create({
          model: 'gpt-4o',
          messages,
          tools,
        });

        // Agentic loop — LLM decides which tools to call
        while (response.choices[0].message.tool_calls) {
          const toolMessages = await ctx.executeTools(response, toolMap);
          messages.push(response.choices[0].message, ...toolMessages);

          response = await openai.chat.completions.create({
            model: 'gpt-4o',
            messages,
            tools,
          });
        }

        return response.choices[0].message.content;
      }, { name: 'paris-research' });

      console.log(result);
      await foil.shutdown();
    }

    main();
    ```

    This produces a span tree like:

    ```
    Trace: paris-research
    ├── llm (gpt-4o) — auto-captured, returns tool_calls
    │   └── tool (web_search) — via ctx.executeTools()
    └── llm (gpt-4o) — auto-captured, final answer
    ```

    Run it:

    ```bash theme={null}
    FOIL_API_KEY=your-key OPENAI_API_KEY=your-key node app.js
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # app.py
    from openai import OpenAI
    from foil import Foil
    import os

    foil = Foil(api_key=os.environ['FOIL_API_KEY'])
    client = foil.wrap_openai(OpenAI())

    response = client.chat.completions.create(
        model='gpt-4o',
        messages=[
            {'role': 'system', 'content': 'You are a helpful assistant.'},
            {'role': 'user', 'content': 'Write a haiku about programming.'},
        ]
    )

    print(response.choices[0].message.content)
    ```

    Run it:

    ```bash theme={null}
    FOIL_API_KEY=your-key OPENAI_API_KEY=your-key python app.py
    ```
  </Tab>
</Tabs>
