> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://respan.ai/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://respan.ai/docs/_mcp/server.

# Langfuse

> Redirect Langfuse traces to Respan — auto-instrumented spans, gateway routing, and full observability.

[Langfuse](https://langfuse.com/) is an open-source LLM observability platform. The Respan instrumentor patches Langfuse's OTLP exporter to redirect traces to Respan, so your existing `@observe` decorators and `langfuse.trace()` calls continue to work unchanged. You also get gateway routing through the OpenAI-compatible Respan endpoint.

#### Set up Respan

Create an account at [platform.respan.ai](https://platform.respan.ai) and grab an [API key](https://platform.respan.ai/platform/gateway/api-keys). For gateway, also add [credits](https://platform.respan.ai/platform/gateway/credits) or a [provider key](https://platform.respan.ai/platform/gateway/api-keys?providers=1).

Run `npx @respan/cli setup` to set up with your coding agent.

#### Example projects

* [Python examples](https://github.com/respanai/respan-example-projects/tree/main/python/tracing/langfuse)

#### Tracing

## Setup

#### Install packages

```bash
pip install respan-ai respan-instrumentation-langfuse langfuse openai
```

#### Set environment variables

```bash
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
export LANGFUSE_PUBLIC_KEY="YOUR_LANGFUSE_PUBLIC_KEY"
export LANGFUSE_SECRET_KEY="YOUR_LANGFUSE_SECRET_KEY"
```

`OPENAI_API_KEY` is used for LLM requests. `RESPAN_API_KEY` is used to export traces to Respan. Langfuse keys are still required for the SDK to initialize.

#### Initialize and run

> **Warning**
>
> `LangfuseInstrumentor` must be activated **before** importing `langfuse`. The instrumentor patches the OTLP exporter at import time.

```python
from respan import Respan
from respan_instrumentation_langfuse import LangfuseInstrumentor

# Activate BEFORE importing langfuse
respan = Respan(instrumentations=[LangfuseInstrumentor()])

from langfuse.decorators import observe
from openai import OpenAI

client = OpenAI()

@observe()
def generate_joke():
    response = client.chat.completions.create(
        model="gpt-4.1-nano",
        messages=[{"role": "user", "content": "Tell me a joke about AI"}],
    )
    return response.choices[0].message.content

@observe()
def joke_pipeline():
    return generate_joke()

print(joke_pipeline())
```

#### View your trace

Open the [Traces page](https://platform.respan.ai/platform/traces) to see your Langfuse traces in Respan.

## Configuration

| Parameter             | Type           | Default | Description                                                          |
| --------------------- | -------------- | ------- | -------------------------------------------------------------------- |
| `api_key`             | `str \| None`  | `None`  | Falls back to `RESPAN_API_KEY` env var.                              |
| `base_url`            | `str \| None`  | `None`  | Falls back to `RESPAN_BASE_URL` env var.                             |
| `instrumentations`    | `list`         | `[]`    | Plugin instrumentations to activate (e.g. `LangfuseInstrumentor()`). |
| `customer_identifier` | `str \| None`  | `None`  | Default customer identifier for all spans.                           |
| `metadata`            | `dict \| None` | `None`  | Default metadata attached to all spans.                              |
| `environment`         | `str \| None`  | `None`  | Environment tag (e.g. `"production"`).                               |

## Attributes

### In Respan()

Set defaults at initialization — these apply to all spans.

```python
from respan import Respan
from respan_instrumentation_langfuse import LangfuseInstrumentor

respan = Respan(
    instrumentations=[LangfuseInstrumentor()],
    customer_identifier="user_123",
    metadata={"service": "chat-api", "version": "1.0.0"},
)
```

### With propagate_attributes

Override per-request using a context scope.

```python
from respan import Respan, propagate_attributes
from respan_instrumentation_langfuse import LangfuseInstrumentor

respan = Respan(instrumentations=[LangfuseInstrumentor()])

from langfuse.decorators import observe

@observe()
def handle_request(user_id: str, question: str):
    with propagate_attributes(
        customer_identifier=user_id,
        thread_identifier="conv_abc_123",
        metadata={"plan": "pro"},
    ):
        # your Langfuse-traced code here
        ...
```

| Attribute             | Type   | Description                                           |
| --------------------- | ------ | ----------------------------------------------------- |
| `customer_identifier` | `str`  | Identifies the end user in Respan analytics.          |
| `thread_identifier`   | `str`  | Groups related messages into a conversation.          |
| `metadata`            | `dict` | Custom key-value pairs. Merged with default metadata. |

#### Gateway

Route LLM calls through the Respan gateway to use 1000+ models from different providers. Only your `RESPAN_API_KEY` is needed — no separate provider keys required.

## Setup

#### Set environment variables

```bash
export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
```

No `OPENAI_API_KEY` needed — the Respan gateway handles provider authentication.

#### Point your LLM client to the Respan gateway

```python
import os
from respan import Respan
from respan_instrumentation_langfuse import LangfuseInstrumentor

respan = Respan(instrumentations=[LangfuseInstrumentor()])

from langfuse.decorators import observe
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["RESPAN_API_KEY"],
    base_url="https://api.respan.ai/api",
)

@observe()
def generate_joke():
    response = client.chat.completions.create(
        model="gpt-4.1-nano",
        messages=[{"role": "user", "content": "Tell me a joke about AI"}],
    )
    return response.choices[0].message.content

print(generate_joke())
```

## Switch models

Change the `model` parameter to use 1000+ models from different providers through the same gateway.

```python
response = client.chat.completions.create(model="claude-sonnet-4-5-20250929", messages=messages)
response = client.chat.completions.create(model="gemini-2.5-flash", messages=messages)
```

See the [full model list](https://platform.respan.ai/platform/models).