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

# Tracing

> Automatically capture all LLM calls with sessions, costs, and latency

Fallom automatically traces all your LLM calls, capturing tokens, costs, latency, and full prompt/completion content.

## TypeScript SDK

<Tabs>
  <Tab title="OpenAI">
    Wrap your OpenAI client for automatic tracing:

    ```typescript theme={null}
    import fallom from "@fallom/trace";
    import OpenAI from "openai";

    await fallom.init({ apiKey: process.env.FALLOM_API_KEY });

    // Create a session for this conversation/request
    const session = fallom.session({
      configKey: "my-app",
      sessionId: "session-123",
      customerId: "user-456",
    });

    const openai = session.wrapOpenAI(new OpenAI());

    const response = await openai.chat.completions.create({
      model: "gpt-4o",
      messages: [{ role: "user", content: "Hello!" }],
    });
    ```
  </Tab>

  <Tab title="Anthropic">
    Wrap your Anthropic client:

    ```typescript theme={null}
    import fallom from "@fallom/trace";
    import Anthropic from "@anthropic-ai/sdk";

    await fallom.init({ apiKey: process.env.FALLOM_API_KEY });

    const session = fallom.session({
      configKey: "my-app",
      sessionId: "session-123",
      customerId: "user-456",
    });

    const anthropic = session.wrapAnthropic(new Anthropic());

    const response = await anthropic.messages.create({
      model: "claude-sonnet-4-20250514",
      max_tokens: 1024,
      messages: [{ role: "user", content: "Hello!" }],
    });
    ```
  </Tab>

  <Tab title="Vercel AI SDK">
    Wrap the entire AI SDK module:

    ```typescript theme={null}
    import fallom from "@fallom/trace";
    import * as ai from "ai";
    import { createOpenAI } from "@ai-sdk/openai";

    await fallom.init({ apiKey: process.env.FALLOM_API_KEY });

    const session = fallom.session({
      configKey: "my-app",
      sessionId: "session-123",
      customerId: "user-456",
    });

    // Option 1: Wrap the SDK
    const { generateText, streamText } = session.wrapAISDK(ai);

    // Option 2: Wrap the model directly (PostHog style)
    const openrouter = createOpenAI({
      baseURL: "https://openrouter.ai/api/v1",
      apiKey: process.env.OPENROUTER_API_KEY,
    });

    const { text } = await generateText({
      model: openrouter("openai/gpt-4o-mini"),
      prompt: "Hello!",
    });
    ```

    See [Vercel AI SDK Integration](/integrations/typescript/vercel-ai) for more details.
  </Tab>

  <Tab title="OpenRouter">
    OpenRouter uses the OpenAI-compatible API:

    ```typescript theme={null}
    import fallom from "@fallom/trace";
    import OpenAI from "openai";

    await fallom.init({ apiKey: process.env.FALLOM_API_KEY });

    const session = fallom.session({
      configKey: "my-app",
      sessionId: "session-123",
      customerId: "user-456",
    });

    const openrouter = session.wrapOpenAI(
      new OpenAI({
        baseURL: "https://openrouter.ai/api/v1",
        apiKey: process.env.OPENROUTER_API_KEY,
      })
    );

    const response = await openrouter.chat.completions.create({
      model: "openai/gpt-4o-mini",
      messages: [{ role: "user", content: "Hello!" }],
    });
    ```
  </Tab>
</Tabs>

## Python SDK

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

    fallom.init(api_key=os.environ["FALLOM_API_KEY"])

    # Create a session for this conversation/request
    session = fallom.session(
        config_key="my-app",
        session_id="session-123",
        customer_id="user-456",
    )

    openai = session.wrap_openai(OpenAI())

    response = openai.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": "Hello!"}]
    )
    ```
  </Tab>

  <Tab title="Anthropic">
    ```python theme={null}
    import os
    import fallom
    from anthropic import Anthropic

    fallom.init(api_key=os.environ["FALLOM_API_KEY"])

    session = fallom.session(
        config_key="my-app",
        session_id="session-123",
        customer_id="user-456",
    )

    anthropic = session.wrap_anthropic(Anthropic())

    response = anthropic.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello!"}]
    )
    ```
  </Tab>

  <Tab title="Google AI">
    ```python theme={null}
    import os
    import fallom
    import google.generativeai as genai

    fallom.init(api_key=os.environ["FALLOM_API_KEY"])

    session = fallom.session(
        config_key="my-app",
        session_id="session-123",
        customer_id="user-456",
    )

    genai.configure(api_key=os.environ["GOOGLE_API_KEY"])
    model = genai.GenerativeModel("gemini-1.5-flash")

    gemini = session.wrap_google_ai(model)

    response = gemini.generate_content("Hello!")
    ```
  </Tab>

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

    fallom.init(api_key=os.environ["FALLOM_API_KEY"])

    session = fallom.session(
        config_key="my-app",
        session_id="session-123",
        customer_id="user-456",
    )

    openrouter = session.wrap_openai(
        OpenAI(
            base_url="https://openrouter.ai/api/v1",
            api_key=os.environ["OPENROUTER_API_KEY"],
        )
    )

    response = openrouter.chat.completions.create(
        model="openai/gpt-4o-mini",
        messages=[{"role": "user", "content": "Hello!"}]
    )
    ```
  </Tab>
</Tabs>

## Session Context

Sessions group related LLM calls together (e.g., a conversation or agent run):

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import fallom from "@fallom/trace";

    // Create a session for this conversation/request
    const session = fallom.session({
      configKey: "my-agent",       // Groups traces in dashboard
      sessionId: "session-123",    // Conversation/request ID
      customerId: "user-456",      // Optional: end-user identifier
    });

    // All wrapped clients use this session context
    const openai = session.wrapOpenAI(new OpenAI());
    const anthropic = session.wrapAnthropic(new Anthropic());
    ```

    ### Concurrent Sessions

    Sessions are isolated - safe for concurrent requests:

    ```typescript theme={null}
    async function handleRequest(userId: string, conversationId: string) {
      const session = fallom.session({
        configKey: "my-agent",
        sessionId: conversationId,
        customerId: userId,
      });

      const openai = session.wrapOpenAI(new OpenAI());
      
      // This session's context is isolated
      return await openai.chat.completions.create({...});
    }

    // Safe to run concurrently!
    await Promise.all([
      handleRequest("user-1", "conv-1"),
      handleRequest("user-2", "conv-2"),
    ]);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import fallom

    # Create a session for this conversation/request
    session = fallom.session(
        config_key="my-agent",       # Groups traces in dashboard
        session_id="session-123",    # Conversation/request ID
        customer_id="user-456",      # Optional: end-user identifier
    )

    # All wrapped clients use this session context
    openai = session.wrap_openai(OpenAI())
    anthropic = session.wrap_anthropic(Anthropic())
    ```

    ### Concurrent Sessions

    Sessions are isolated - safe for concurrent requests:

    ```python theme={null}
    def handle_request(user_id: str, conversation_id: str):
        session = fallom.session(
            config_key="my-agent",
            session_id=conversation_id,
            customer_id=user_id,
        )

        openai = session.wrap_openai(OpenAI())

        # This session's context is isolated
        return openai.chat.completions.create(...)

    # Safe to run concurrently!
    import concurrent.futures
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = [
            executor.submit(handle_request, "user-1", "conv-1"),
            executor.submit(handle_request, "user-2", "conv-2"),
        ]
    ```

    ### Metadata and Tags

    Add custom metadata and tags for filtering:

    ```python theme={null}
    session = fallom.session(
        config_key="my-agent",
        session_id="session-123",
        customer_id="user-456",
        metadata={
            "deployment": "dedicated",
            "request_type": "transcript",
            "user_tier": "premium",
        },
        tags=["production", "high-priority", "premium"],
    )
    ```
  </Tab>
</Tabs>

| Parameter    | Description                                              |
| ------------ | -------------------------------------------------------- |
| `configKey`  | Your experiment/config identifier (e.g., `"summarizer"`) |
| `sessionId`  | Unique ID for this session (e.g., conversation ID)       |
| `customerId` | Optional user identifier for per-user analytics          |

## What Gets Captured

Every LLM call automatically includes:

| Field                   | Description                                      |
| ----------------------- | ------------------------------------------------ |
| **Model**               | The model used (e.g., `gpt-4o`, `claude-3-opus`) |
| **Duration**            | Total request time in milliseconds               |
| **Time to First Token** | TTFT for streaming requests                      |
| **Tokens**              | Input, output, and cached token counts           |
| **Cost**                | Calculated from token usage + model pricing      |
| **Prompts**             | Full input messages                              |
| **Completions**         | Model responses                                  |
| **Session**             | Config key, session ID, customer ID              |
| **Status**              | OK or ERROR                                      |

## Multimodal (Images)

Images in prompts are automatically handled:

* **URL images** - Stored as-is
* **Base64 images** - Uploaded to secure storage, replaced with URL

```typescript theme={null}
const response = await openai.chat.completions.create({
  model: "gpt-4o",
  messages: [
    {
      role: "user",
      content: [
        { type: "text", text: "What's in this image?" },
        { type: "image_url", image_url: { url: "https://..." } },
      ],
    },
  ],
});
// Trace captures the image URL for replay in dashboard
```

## Configuration

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    await fallom.init({
      apiKey: "your-fallom-api-key",
      
      // Optional settings
      baseUrl: "https://traces.fallom.com",  // Custom endpoint
      captureContent: true,                   // Capture prompt/completion text
      debug: false,                           // Enable debug logging
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import fallom

    fallom.init(
        api_key="your-fallom-api-key",

        # Optional settings
        traces_url="https://traces.fallom.com",   # Custom traces endpoint
        configs_url="https://configs.fallom.com", # Custom configs endpoint
        prompts_url="https://prompts.fallom.com", # Custom prompts endpoint
        capture_content=True,                      # Capture prompt/completion text
        debug=False,                               # Enable debug logging
    )
    ```
  </Tab>
</Tabs>

## Disable Content Capture

For privacy, you can disable capturing prompt/completion content:

```typescript theme={null}
await fallom.init({
  apiKey: "your-fallom-api-key",
  captureContent: false, // Only capture metadata (model, tokens, latency)
});
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Model A/B Testing" icon="flask" href="/model-testing">
    Test different models with traced calls.
  </Card>

  <Card title="Prompt Management" icon="pen-fancy" href="/prompt-testing">
    Manage and A/B test your prompts.
  </Card>

  <Card title="OpenRouter Broadcast" icon="broadcast-tower" href="/integrations/openrouter">
    Send traces without an SDK.
  </Card>

  <Card title="Vercel AI SDK" icon="bolt" href="/integrations/vercel-ai">
    Integration guide for Vercel AI.
  </Card>
</CardGroup>
