> 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.

# Helicone (tracing)

> Trace Helicone Manual Logger calls from Python and TypeScript with canonical Respan spans.

[Helicone's Manual Logger](https://docs.helicone.ai/getting-started/integration-method/custom) records calls to custom, self-hosted, and provider-backed models. The Respan Helicone instrumentation observes that same manual-logger lifecycle and emits canonical Respan spans without replacing or bypassing Helicone's own logging.

The integration supports `helicone-helpers >=1.2.1,<1.3.0` for Python and `@helicone/helpers >=1.8.3 <1.9.0` for TypeScript.

#### Set up Respan

Create an account at [platform.respan.ai](https://platform.respan.ai) and grab an [API key](https://platform.respan.ai/platform/api/api-keys).

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

#### Use Respan Gateway

See [Helicone gateway setup](/docs/gateway/helicone) to replace Helicone Gateway routing with the OpenAI-compatible Respan Gateway.

#### Example projects

* [Python examples](https://github.com/respanai/respan-example-projects/tree/main/python/tracing/helicone)
* [TypeScript examples](https://github.com/respanai/respan-example-projects/tree/main/typescript/tracing/helicone)
* [Python instrumentation package](https://github.com/respanai/respan/tree/main/python-sdks/instrumentations/respan-instrumentation-helicone)
* [TypeScript instrumentation package](https://github.com/respanai/respan/tree/main/javascript-sdks/instrumentations/respan-instrumentation-helicone)

## Setup

#### Install packages

**`Python`**

```bash Python
pip install respan-ai respan-instrumentation-helicone "helicone-helpers~=1.2.1" openai
```

**`TypeScript`**

```bash TypeScript
npm install @respan/respan @respan/instrumentation-helicone @helicone/helpers@~1.8.3 openai
```

#### Set environment variables

```bash
export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
export HELICONE_API_KEY="YOUR_HELICONE_API_KEY"
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
```

`RESPAN_API_KEY` exports traces to Respan. `HELICONE_API_KEY` keeps the Manual Logger connected to Helicone. This example calls OpenAI directly, so it also needs `OPENAI_API_KEY`; use the credential required by the provider in your callback. `RESPAN_BASE_URL` is optional for a self-hosted or non-default Respan endpoint.

#### Initialize and run

Initialize Respan before the first Helicone Manual Logger call.

**`Python`**

```python Python
import os

from helicone_helpers import HeliconeManualLogger
from openai import OpenAI
from respan import Respan
from respan_instrumentation_helicone import HeliconeInstrumentor

respan = Respan(
    api_key=os.environ["RESPAN_API_KEY"],
    app_name="helicone-manual-logger",
    instrumentations=[HeliconeInstrumentor()],
)

helicone = HeliconeManualLogger(api_key=os.environ["HELICONE_API_KEY"])
openai = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

request = {
    "model": "gpt-4o-mini",
    "messages": [{"role": "user", "content": "Say hello in three languages."}],
}


def call_model(recorder):
    response = openai.chat.completions.create(**request)
    recorder.append_results(response.model_dump())
    return response


try:
    response = helicone.log_request(
        request=request,
        operation=call_model,
        provider="openai",
        additional_headers={
            "Helicone-User-Id": "user_123",
            "Helicone-Session-Id": "conversation_456",
            "Helicone-Property-Environment": "production",
        },
    )
    print(response.choices[0].message.content)
finally:
    respan.flush()
    respan.shutdown()
```

**`TypeScript`**

```typescript TypeScript
import { HeliconeManualLogger } from "@helicone/helpers";
import { HeliconeInstrumentor } from "@respan/instrumentation-helicone";
import { Respan } from "@respan/respan";
import OpenAI from "openai";

const respan = new Respan({
  apiKey: process.env.RESPAN_API_KEY,
  baseURL: process.env.RESPAN_BASE_URL,
  appName: "helicone-manual-logger",
  instrumentations: [new HeliconeInstrumentor()],
});
await respan.initialize();

const helicone = new HeliconeManualLogger({
  apiKey: process.env.HELICONE_API_KEY!,
});
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const request = {
  model: "gpt-4o-mini",
  messages: [
    { role: "user" as const, content: "Say hello in three languages." },
  ],
};

try {
  const response = await helicone.logRequest(
    request,
    async (recorder) => {
      const result = await openai.chat.completions.create(request);
      recorder.appendResults(result);
      return result;
    },
    {
      "Helicone-User-Id": "user_123",
      "Helicone-Session-Id": "conversation_456",
      "Helicone-Property-Environment": "production",
    },
    "openai",
  );

  console.log(response.choices[0]?.message.content);
} finally {
  await respan.shutdown();
}
```

#### View your trace

Open the [Traces page](https://platform.respan.ai/platform/traces) to inspect the Helicone span's model, provider, input, output, usage, status, timing, and correlation attributes.

## What is traced

The instrumentors patch Helicone's published Manual Logger methods rather than the underlying provider SDK.

| Language   | Manual Logger surface                                                                                                  |
| ---------- | ---------------------------------------------------------------------------------------------------------------------- |
| Python     | `log_request()`, direct `send_log()`, `log_builder()`, and the builder's async `send_log()` lifecycle                  |
| TypeScript | `logRequest()`, `logStream()`, `logSingleStream()`, `logSingleRequest()`, direct `sendLog()`, and `HeliconeLogBuilder` |

The emitted span type is inferred from the payload:

| Helicone payload                                                        | Respan log type |
| ----------------------------------------------------------------------- | --------------- |
| Chat messages, including OpenAI-, Anthropic-, and Google-shaped content | `chat`          |
| Prompt and text completion                                              | `text`          |
| Embedding input and vectors                                             | `embedding`     |
| `_type=tool` custom event                                               | `tool`          |
| `_type=vector_db` custom event                                          | `task`          |
| `_type=data` custom event                                               | `task`          |

When Helicone supplies them, Respan retains model and provider identity, request and response content, token usage, tool definitions and calls, streaming timing, HTTP status, and errors. An operation that fails before Helicone reaches its shared logging sink still produces one error span rather than a duplicate success/error pair.

## Configuration

| Parameter              | Type                                  | Default           | Description                                                                           |
| ---------------------- | ------------------------------------- | ----------------- | ------------------------------------------------------------------------------------- |
| `api_key` / `apiKey`   | `str \| None` / `string \| undefined` | `RESPAN_API_KEY`  | Respan API key used to export traces.                                                 |
| `base_url` / `baseURL` | `str \| None` / `string \| undefined` | `RESPAN_BASE_URL` | Optional Respan trace export endpoint.                                                |
| `instrumentations`     | `list` / `RespanInstrumentation[]`    | `[]`              | Include `HeliconeInstrumentor()` or `new HeliconeInstrumentor()` to activate tracing. |
| `capture_content`      | `bool`                                | `True`            | Python option that controls request and response content capture.                     |
| `traceContent`         | `boolean`                             | `true`            | TypeScript option that controls request and response content capture.                 |

### Disable content capture

Disable content capture when prompts or responses may contain sensitive data:

**`Python`**

```python Python
from respan_instrumentation_helicone import HeliconeInstrumentor

instrumentor = HeliconeInstrumentor(capture_content=False)
```

**`TypeScript`**

```typescript TypeScript
import { HeliconeInstrumentor } from "@respan/instrumentation-helicone";

const instrumentor = new HeliconeInstrumentor({ traceContent: false });
```

Model, provider, usage, timing, status, errors, and safe correlation fields remain available. Helicone API keys, authorization headers, unknown headers, and structured secret fields are never copied into spans.

## Correlation attributes

The instrumentors recognize Helicone's safe correlation headers:

| Header                | Respan behavior                                                |
| --------------------- | -------------------------------------------------------------- |
| `Helicone-User-Id`    | Sets the customer identifier.                                  |
| `Helicone-Session-Id` | Sets the session or conversation identifier.                   |
| `Helicone-Property-*` | Preserved as safe association properties or Helicone metadata. |

Respan propagated attributes also stay attached to the manual-log span, including parent workflow context captured when a delayed builder is created.

## Avoid duplicate telemetry

Helicone instrumentation is explicit-only. Activate it only in processes that use `HeliconeManualLogger`.

Do not also activate a provider-specific instrumentor for the same provider call unless two spans for one logical operation are intentional. Likewise, a request routed through Respan Gateway already creates a gateway log; wrapping it in an instrumented Helicone manual log adds a separate manual-log span. See the [gateway guide](/docs/gateway/helicone) for the simpler gateway-only migration path.