---
title: "Helicone Integration"
sidebarTitle: Helicone
logo: /images/integrations/helicone_icon.png
description: "Learn how to integrate Langfuse with Helicone AI Gateway to access 100+ LLM providers with observability and tracing."
---

# Helicone Integration

  Helicone has moved into maintenance mode following its [acquisition by Mintlify](https://www.helicone.ai/blog/joining-mintlify). If you're looking to migrate, see our [Helicone to Langfuse migration guide](/resources/engineering/migrate-from-helicone).

In this guide, we'll show you how to integrate [Langfuse](/) with [Helicone](https://helicone.ai/).

> **What is Helicone?** [Helicone](https://helicone.ai/) is an open-source AI gateway enabling you access to 100+ AI models through an OpenAI-compatible interface. It offers features like intelligent routing, automatic failover, caching, cost tracking, and more.

> **What is Langfuse?** [Langfuse](/) is an open source AI engineering platform that helps teams trace LLM calls, monitor performance, and debug issues in their AI applications.

Since Helicone is OpenAI-compatible, we can utilize Langfuse's native integration with the OpenAI SDK, available in both [Python](/integrations/model-providers/openai-py) and [TypeScript](/integrations/model-providers/openai-js).

## Get started

<LangTabs items={["Python SDK", "JS/TS SDK"]}>

<Tab>

1. In your terminal, install the following packages if you haven't already:

```bash
pip install langfuse openai python-dotenv
```

2. Then, create a `.env` file in your project and add your environment variables:

```txt filename=".env"
HELICONE_API_KEY=sk-helicone-... # Get it from your Helicone dashboard

LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_BASE_URL=https://cloud.langfuse.com # 🇪🇺 EU region
# Other Langfuse data regions include 🇺🇸 US: https://us.cloud.langfuse.com, 🇯🇵 Japan: https://jp.cloud.langfuse.com and ⚕️ HIPAA: https://hipaa.cloud.langfuse.com
```

</Tab>

<Tab>

1. In your terminal, install the following packages if you haven't already:

```bash
npm install @langfuse/openai @langfuse/otel @opentelemetry/sdk-node openai
```

2. Create a `.env` file in your project and add your environment variables:

```txt filename=".env"
HELICONE_API_KEY=sk-helicone-... # Get it from your Helicone dashboard

LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_BASE_URL=https://cloud.langfuse.com # 🇪🇺 EU region
# Other Langfuse data regions include 🇺🇸 US: https://us.cloud.langfuse.com, 🇯🇵 Japan: https://jp.cloud.langfuse.com and ⚕️ HIPAA: https://hipaa.cloud.langfuse.com
```

3. Set up OpenTelemetry with the `LangfuseSpanProcessor`:

```typescript
import { NodeSDK } from "@opentelemetry/sdk-node";
import { LangfuseSpanProcessor } from "@langfuse/otel";

const sdk = new NodeSDK({
  spanProcessors: [new LangfuseSpanProcessor()],
});

sdk.start();
```

</Tab>
</LangTabs>

## Example 1: Simple LLM Call

We use Langfuse's OpenAI SDK wrapper to automatically log Helicone calls as generations in Langfuse.

- The `base_url` is set to Helicone's AI Gateway endpoint.
- You can replace `"gpt-4o"` with any model available in [Helicone's model registry](https://helicone.ai/models).
- The `api_key` uses your Helicone API key to handle authentication with model providers.

<LangTabs items={["Python SDK", "JS/TS SDK"]}>
<Tab>

```python
from langfuse.openai import openai
import os
from dotenv import load_dotenv

load_dotenv()

# Create an OpenAI client with Helicone's gateway endpoint
client = openai.OpenAI(
    api_key=os.getenv("HELICONE_API_KEY"),
    base_url="https://ai-gateway.helicone.ai/"
)

# Make a chat completion request
response = client.chat.completions.create(
    model="gpt-4o", # Or any other 100+ models
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Tell me a fun fact about space."}
    ],
    name="fun-fact-request"  # Optional: Name of the generation in Langfuse
)

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

</Tab>
<Tab>

```typescript
import { observeOpenAI } from "@langfuse/openai";
import OpenAI from "openai";

const openaiClient = new OpenAI({
    apiKey: process.env.HELICONE_API_KEY,
    baseURL: "https://ai-gateway.helicone.ai/"
});

// Create an observed client with Langfuse options
const client = observeOpenAI(openaiClient, {
    generationName: "fun-fact-request"  // Optional: Name of the generation in Langfuse
});

// Make a chat completion request
const response = await client.chat.completions.create({
    model: "gpt-4o", // Or any other 100+ models
    messages: [
        { role: "system", content: "You are a helpful assistant." },
        { role: "user", content: "Tell me a fun fact about space." }
    ]
});

console.log(response.choices[0].message.content);
```

</Tab>
</LangTabs>

## Example 2: Nested LLM Calls

By using the `@observe()` decorator, we capture execution details of any Python function, including nested LLM calls, inputs, outputs, and execution times. This provides in-depth observability with minimal code changes.

- The `@observe()` decorator captures inputs, outputs, and execution details of the functions.
- Nested functions `summarize_text` and `analyze_sentiment` are also decorated, creating a hierarchy of traces.
- Each LLM call within the functions is logged, providing a detailed trace of the execution flow.

<LangTabs items={["Python SDK", "JS/TS SDK"]}>

<Tab>

By using the `@observe()` decorator, we can capture execution details of any Python function.
The `@observe()` decorator captures inputs, outputs, and execution details of the functions.

```python
from langfuse import observe
from langfuse.openai import openai
import os
from dotenv import load_dotenv

load_dotenv()

# Create an OpenAI client with Helicone's base URL
client = openai.OpenAI(
    base_url="https://ai-gateway.helicone.ai/",
    api_key=os.getenv("HELICONE_API_KEY")
)

@observe()  # This decorator enables tracing of the function
def analyze_text(text: str):
    # First LLM call: Summarize the text
    summary_response = summarize_text(text)
    summary = summary_response.choices[0].message.content

    # Second LLM call: Analyze the sentiment of the summary
    sentiment_response = analyze_sentiment(summary)
    sentiment = sentiment_response.choices[0].message.content

    return {
        "summary": summary,
        "sentiment": sentiment
    }

@observe()  # Nested function to be traced
def summarize_text(text: str):
    return client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "You summarize texts in a concise manner."},
            {"role": "user", "content": f"Summarize the following text:\n{text}"}
        ],
        name="summarize-text"
    )

@observe()  # Nested function to be traced
def analyze_sentiment(summary: str):
    return client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "You analyze the sentiment of texts."},
            {"role": "user", "content": f"Analyze the sentiment of the following summary:\n{summary}"}
        ],
        name="analyze-sentiment"
    )

# Example usage
text_to_analyze = "OpenAI's GPT-4 model has significantly advanced the field of AI, setting new standards for language generation."
analyze_text(text_to_analyze)
```

</Tab>
<Tab>

By wrapping the calls in `startActiveObservation`, nested LLM calls made with the wrapped OpenAI client are automatically grouped under one trace.

```typescript
import { startActiveObservation } from "@langfuse/tracing";
import { observeOpenAI } from "@langfuse/openai";
import OpenAI from "openai";

const openaiClient = new OpenAI({
    baseURL: "https://ai-gateway.helicone.ai/",
    apiKey: process.env.HELICONE_API_KEY
});

async function analyzeText(text: string) {
    // Create a root observation for the entire analysis
    return await startActiveObservation("analyze-text", async (span) => {
        span.update({ input: { text } });

        // First LLM call: Summarize the text
        const summaryResponse = await summarizeText(text);
        const summary = summaryResponse.choices[0].message.content;

        // Second LLM call: Analyze the sentiment of the summary
        const sentimentResponse = await analyzeSentiment(summary!);
        const sentiment = sentimentResponse.choices[0].message.content;

        const result = {
            summary,
            sentiment
        };

        span.update({ output: result });

        return result;
    });
}

async function summarizeText(text: string) {
    const client = observeOpenAI(openaiClient, {
        generationName: "summarize-text"
    });

    return await client.chat.completions.create({
        model: "gpt-4o",
        messages: [
            { role: "system", content: "You summarize texts in a concise manner." },
            { role: "user", content: `Summarize the following text:\n${text}` }
        ]
    });
}

async function analyzeSentiment(summary: string) {
    const client = observeOpenAI(openaiClient, {
        generationName: "analyze-sentiment"
    });

    return await client.chat.completions.create({
        model: "gpt-4o",
        messages: [
            { role: "system", content: "You analyze the sentiment of texts." },
            { role: "user", content: `Analyze the sentiment of the following summary:\n${summary}` }
        ]
    });
}

// Example usage
const textToAnalyze = "OpenAI's GPT-4 model has significantly advanced the field of AI, setting new standards for language generation.";
analyzeText(textToAnalyze);
```

</Tab>
</LangTabs>

## Example 3: Streaming Responses

<LangTabs items={["Python SDK", "JS/TS SDK"]}>
<Tab>

```python
stream = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "user", "content": "Write a haiku about a robot."}
    ],
    stream=True,
    name="streaming-story"
)

print("🤖 Assistant (streaming):")
for chunk in stream:
    if chunk.choices[0].delta.content is not None:
        print(chunk.choices[0].delta.content, end="", flush=True)
print("\n")
```

</Tab>
<Tab>

```typescript
const stream = await client.chat.completions.create({
    model: "gpt-4o",
    messages: [
        { role: "user", content: "Write a haiku about a robot." }
    ],
    stream: true
});

console.log("🤖 Assistant (streaming):");
for await (const chunk of stream) {
    if (chunk.choices[0]?.delta?.content) {
        process.stdout.write(chunk.choices[0].delta.content);
    }
}
console.log("\n");
```

</Tab>
</LangTabs>

## Example 4: Multi-Provider Access

Helicone provides access to 100+ LLM providers through a single interface. Simply change the model name to use different providers:

<LangTabs items={["Python SDK", "JS/TS SDK"]}>
<Tab>

```python
# Use Anthropic Claude
response = client.chat.completions.create(
    model="claude-3.5-sonnet-v2/anthropic",
    messages=[{"role": "user", "content": "Hello!"}]
)

# Use Gemini Pro if Anthropic's Claude Sonnet 3.5 is not available
response = client.chat.completions.create(
    model="claude-3.5-sonnet-v2/anthropic,gemini-2.5-flash-lite/google-ai-studio",
    messages=[{"role": "user", "content": "Hello!"}]
)
```

</Tab>
<Tab>

```typescript
// Use Anthropic Claude
const response = await client.chat.completions.create({
    model: "claude-3.5-sonnet-v2/anthropic",
    messages: [{ role: "user", content: "Hello!" }]
});

// Use Gemini Pro if Anthropic's Claude Sonnet 3.5 is not available
const response2 = await client.chat.completions.create({
    model: "claude-3.5-sonnet-v2/anthropic,gemini-2.5-flash-lite/google-ai-studio",
    messages: [{ role: "user", content: "Hello!" }]
});
```

</Tab>
</LangTabs>

## Learn More

- **[Helicone Model Registry](https://helicone.ai/models)**: Browse all available models in Helicone's model registry.
- **[Helicone Documentation](https://docs.helicone.ai/)**: Documentation for Helicone.
- **[Helicone GitHub](https://github.com/helicone/helicone)**: GitHub repository for Helicone.
- **[Helicone Twitter](https://x.com/helicone_ai)**: Stay up to date with Helicone's latest news and updates.

<!-- agent-instructions -->

---

## Agent Instructions

This page is part of the [Langfuse](https://langfuse.com) documentation, published as plain Markdown for AI agents. Every page is available as Markdown by appending `.md` to its URL, or by sending an `Accept: text/markdown` header. This page: `https://langfuse.com/integrations/gateways/helicone.md`.

### Querying these docs

If the answer is not on this page, query the documentation instead of guessing:

- **Semantic search** across all Langfuse docs, returning an answer with the relevant pages and excerpts. Ask a specific, self-contained question:

  ```bash
  curl -sG "https://langfuse.com/api/search-docs" --data-urlencode "query=How do I trace a LangGraph agent?"
  ```

- **Index of every page**: <https://langfuse.com/llms.txt>, with per-section indexes [llms-docs.txt](https://langfuse.com/llms-docs.txt), [llms-integrations.txt](https://langfuse.com/llms-integrations.txt), and [llms-self-hosting.txt](https://langfuse.com/llms-self-hosting.txt).

### Before writing Langfuse code

- **Install the [Langfuse Agent Skill](https://langfuse.com/docs/api-and-data-platform/features/agent-skill).** It encodes Langfuse's own best practices for instrumentation, prompt management, and evaluation, and materially improves results.
- **Read [What does a good trace look like?](https://langfuse.com/docs/observability/best-practices.md)** before instrumenting an application.
- **Verify endpoints, parameters, and response fields** against the [API reference](https://api.reference.langfuse.com) instead of inferring them from code examples.
- **Use the [Langfuse CLI](https://langfuse.com/docs/api-and-data-platform/features/cli)** (`npx langfuse-cli api <resource> <action>`) to read or write traces, prompts, datasets, and scores from the terminal.

Found an error in these docs? Please open an issue at <https://github.com/langfuse/langfuse-docs/issues>.
