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

# OpenAI SDK

> Automatically trace supported direct OpenAI SDK calls with PromptLayer.

PromptLayer can auto-instrument the official OpenAI SDK and export supported calls as OpenTelemetry spans. Each supported direct SDK call appears in PromptLayer as both a trace span and an associated request log without changing how you create or use the OpenAI client.

<Note>
  This guide covers the OpenAI model SDK. If you use the OpenAI Agents SDK, follow the [OpenAI Agents SDK integration](/features/observability/traces/integrations#openai-agents-sdk) instead.
</Note>

## Supported APIs

| API surface                                  | Python                     | JavaScript    |
| -------------------------------------------- | -------------------------- | ------------- |
| Chat Completions (`chat.completions.create`) | Supported (sync and async) | Supported     |
| Chat Completions streaming                   | Supported (sync and async) | Supported     |
| Structured-output parsing                    | Supported (sync and async) | Not supported |
| Responses (`responses.create`)               | Supported (sync and async) | Supported     |
| Responses streaming                          | Supported (sync and async) | Supported     |
| Embeddings (`embeddings.create`)             | Supported (sync and async) | Supported     |
| Azure OpenAI                                 | Supported                  | Supported     |

Only the API surfaces in this table are auto-instrumented. Other OpenAI SDK calls continue to work normally, but this integration does not automatically create PromptLayer traces or request logs for them.

## Prerequisites

* A [PromptLayer API key](/quickstart#prerequisites) for the workspace that should receive the traces
* An OpenAI API key
* Python 3.10 or later for the Python integration, or Node.js 20 or later for the JavaScript integration

Export the variables for your language before the application starts. The API keys are required for the setup in this guide. PromptLayer captures supported prompt, response, and tool content by default.

<CodeGroup>
  ```bash Python theme={null}
  export PROMPTLAYER_API_KEY="pl_..."
  export OPENAI_API_KEY="sk_..."
  ```

  ```bash JavaScript theme={null}
  export PROMPTLAYER_API_KEY="pl_..."
  export OPENAI_API_KEY="sk_..."
  ```
</CodeGroup>

If your data policies require metadata-only telemetry, use the language-specific opt-out in [Capture Prompts and Responses](#capture-prompts-and-responses) before starting the application. Disabling capture limits content-aware PromptLayer features.

## Python

### 1. Install the SDKs

Install PromptLayer with the OpenAI tracing extra:

```bash theme={null}
pip install "promptlayer[otel-genai-instrumentation]" openai
```

### 2. Initialize instrumentation

Call `instrument_openai()` before the first OpenAI request. It configures the OpenAI instrumentor and an authenticated OTLP exporter for PromptLayer.

```python theme={null}
from openai import OpenAI
from promptlayer import instrument_openai

tracer_provider = instrument_openai()
client = OpenAI()

try:
    completion = client.chat.completions.create(
        model="gpt-4.1-mini",
        messages=[
            {"role": "user", "content": "Explain distributed tracing in one sentence."}
        ],
    )
    print(completion.choices[0].message.content)

    embedding = client.embeddings.create(
        model="text-embedding-3-small",
        input="Distributed tracing connects work across services.",
    )
    print(len(embedding.data[0].embedding))
finally:
    # Flush pending spans before a short-lived process exits.
    tracer_provider.force_flush()
```

`instrument_openai()` is idempotent when called again with the same tracer provider. If your application already owns an OpenTelemetry SDK tracer provider, pass it with `tracer_provider=`.

<Accordion title="Use an existing PromptLayer client">
  If your application already creates a PromptLayer client, select OpenAI when enabling tracing:

  ```python theme={null}
  from openai import OpenAI
  from promptlayer import PromptLayer

  promptlayer_client = PromptLayer(
      enable_tracing=True,
      tracing_providers=("openai",),
  )
  client = OpenAI()

  completion = client.chat.completions.create(
      model="gpt-4.1-mini",
      messages=[{"role": "user", "content": "Say hello."}],
  )

  promptlayer_client.tracer_provider.force_flush()
  ```

  Omit `tracing_providers` to instrument every supported provider SDK that is installed. Use either this setup or `instrument_openai()` for the same tracer provider; you do not need both.
</Accordion>

## JavaScript

### 1. Install the SDKs

```bash theme={null}
npm install promptlayer openai
```

### 2. Preload PromptLayer instrumentation

Start Node.js with the `promptlayer/register` preload. The preload must run before your application imports `openai`.

```bash theme={null}
node --import promptlayer/register app.mjs
```

For a deployment command that you cannot edit directly, add the preload through `NODE_OPTIONS`:

```bash theme={null}
NODE_OPTIONS="--import promptlayer/register" node app.mjs
```

### 3. Use the OpenAI SDK normally

```javascript theme={null}
import OpenAI from "openai";
import { shutdownTracing } from "promptlayer";

const client = new OpenAI();

try {
  const completion = await client.chat.completions.create({
    model: "gpt-4.1-mini",
    messages: [
      {
        role: "user",
        content: "Explain distributed tracing in one sentence.",
      },
    ],
  });
  console.log(completion.choices[0]?.message.content);

  const response = await client.responses.create({
    model: "gpt-4.1-mini",
    input: "Explain distributed tracing in one sentence.",
  });
  console.log(response.output_text);

  const embedding = await client.embeddings.create({
    model: "text-embedding-3-small",
    input: "Distributed tracing connects work across services.",
  });
  console.log(embedding.data[0]?.embedding.length);
} finally {
  // Flush pending spans and stop the PromptLayer-owned tracing provider.
  await shutdownTracing();
}
```

Call `shutdownTracing()` when a short-lived process finishes, not after every request in a long-running server.

The preload instruments every supported provider. To instrument only OpenAI, call `configureTracing({ providers: ["openai"] })` in a bootstrap module and dynamically import the application afterward. See [Select Providers](/features/observability/traces/auto-instrumentation/overview#select-providers).

## Capture Prompts and Responses

PromptLayer captures supported prompt and response content by default so search, analytics, request inspection, and debugging can use the complete LLM interaction. Model names, timing, token usage when available, and other non-content telemetry are still recorded when capture is disabled.

To disable content capture, set the language-specific value before `instrument_openai()` or the `promptlayer/register` preload runs:

<CodeGroup>
  ```bash Python theme={null}
  export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT="NO_CONTENT"
  ```

  ```bash JavaScript theme={null}
  export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT="false"
  ```
</CodeGroup>

JavaScript can instead pass `captureContent: false` to `configureTracing()`. Restart an already-running process after changing the setting.

<Warning>
  Content capture can send user prompts, model responses, and tool arguments to PromptLayer. Because it is enabled by default, review your privacy, retention, and compliance requirements and opt out before the first OpenAI request when necessary.
</Warning>

## Configuration Reference

| Setting                                              | Required | Description                                                                                                                                              |
| ---------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PROMPTLAYER_API_KEY`                                | Yes      | Authenticates trace export and selects the PromptLayer workspace. Python can instead pass `api_key=` to `instrument_openai()` or `configure_tracing()`.  |
| `OPENAI_API_KEY`                                     | Yes      | Authenticates OpenAI SDK requests. It is read by OpenAI and is not sent to PromptLayer.                                                                  |
| `PROMPTLAYER_BASE_URL`                               | No       | Overrides the PromptLayer API root. The tracing endpoint defaults to `<base-url>/v1/traces`.                                                             |
| `PROMPTLAYER_OTLP_TRACES_ENDPOINT`                   | No       | Overrides the complete OTLP/HTTP trace endpoint and takes precedence over `PROMPTLAYER_BASE_URL`.                                                        |
| `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` | No       | Controls prompt, response, and tool content capture. Capture is enabled by default. Use `NO_CONTENT` for Python or `false` for JavaScript to disable it. |

Python also accepts `api_key`, `base_url`, `endpoint`, and `tracer_provider` keyword arguments:

```python theme={null}
tracer_provider = instrument_openai(
    api_key="pl_...",
    endpoint="https://api.promptlayer.com/v1/traces",
    tracer_provider=application_tracer_provider,
)
```

Configure a tracer provider only once and reuse it. If the OpenAI SDK is already instrumented with a different provider, PromptLayer rejects the mismatch instead of silently exporting incomplete traces.

For multi-provider Python applications, use `configure_tracing(providers=("openai", ...))` or the `tracing_providers` PromptLayer client option described in the [auto-instrumentation overview](/features/observability/traces/auto-instrumentation/overview#select-providers).

## Verify the Integration

Run one supported OpenAI request, flush tracing, and open [Traces](/features/observability/traces) in PromptLayer. The OpenAI span should have an associated request log. If the call runs inside `PromptLayer.run()`, PromptLayer links the provider span to the existing run request log instead of creating a duplicate.

If no span appears:

* Confirm the initialization or JavaScript preload runs before the first OpenAI call.
* Confirm the call uses an API surface listed in [Supported APIs](#supported-apis).
* Confirm `PROMPTLAYER_API_KEY` belongs to the workspace you are checking.
* Flush or shut down tracing before a short-lived process exits.
* If only prompt or response content is missing, confirm content capture was not disabled and restart the process after changing the setting.
