OpenAI SDK
Capture traces from the OpenAI Python or TypeScript SDK with OpenInference
Language support
| Setup option | Python | TypeScript |
|---|---|---|
| Voxmith skill | ✓ | ✓ |
| Voxmith SDK | ✓ | ✓ |
| OpenTelemetry auto-instrumentation | ✓ | ✓ |
Choose a setup method
| Method | Use it when |
|---|---|
| Voxmith skill | You want your coding agent to inspect the app, make the change, and verify it. |
| Voxmith SDK | You want explicit control over the interaction boundaries and fields. |
| OpenTelemetry | The framework already emits useful spans or you operate an OTel pipeline. |
Start with one method for a call path. Combining SDK tracking with framework OpenTelemetry on the same call can create duplicate interactions.
Recommended: Voxmith skill
Recommended. Choose this path when you want your coding agent to inspect the project, select a supported transport, make the smallest instrumentation change, send a test event, and verify that it reached Voxmith.
Install the skill once in your coding-agent environment:
npx skills add Voxmith/skills --skill voxmithRun the framework-specific prompt below from the application root. Review the resulting diff before deploying it.
Use the voxmith skill to add Voxmith analytics to this OpenAI SDK application.
Org ID: your-org-id
Instrument the real Responses API call and verify one fresh interaction.Manual setup: Voxmith SDK
pip install voxmithnpm install voxmithaiimport voxmith
from openai import OpenAI
voxmith.init("your-org-id")
client = OpenAI()
interaction = voxmith.begin(user_id="u-42", agent_name="openai-support", input=prompt)
try:
response = client.responses.create(model="gpt-4.1-mini", input=prompt)
interaction.end(output=response.output_text)
except Exception as exc:
interaction.end(output=str(exc), success=False)
raise
finally:
voxmith.shutdown()import OpenAI from 'openai';
import * as voxmith from 'voxmithai';
voxmith.init('your-org-id');
const client = new OpenAI();
const interaction = voxmith.begin({ userId: 'u-42', agentName: 'openai-support', input: prompt });
try {
const response = await client.responses.create({ model: 'gpt-4.1-mini', input: prompt });
interaction.end(response.output_text);
} catch (error) {
interaction.end(String(error), false);
throw error;
} finally {
await voxmith.shutdown();
}Manual setup: OpenTelemetry
The openai SDK ships no first-party OTel: use OpenInference's auto-instrumentation. Pick your language in the code blocks below; the choice persists across the page.
1. Install
Already have OpenInference + an OTLP exporter wired up? Skip.
No setup yet?
pip install openai openinference-instrumentation-openai \
opentelemetry-sdk opentelemetry-exporter-otlp-proto-httpnpm install openai @arizeai/openinference-instrumentation-openai \
@arizeai/openinference-core @opentelemetry/sdk-node \
@opentelemetry/exporter-trace-otlp-proto @opentelemetry/api2. Wire OpenInference + OTLP exporter pointing at Voxmith
Already have OpenInference (or any OTel TracerProvider) running? Append Voxmith as an additional span processor on the existing provider:
from opentelemetry import trace
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(
OTLPSpanExporter(
endpoint="https://otel.voxmith.com/v1/traces",
headers={"X-Voxmith-Org-ID": os.environ["VOXMITH_ORG_ID"]},
)
)
)import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
provider.addSpanProcessor(
new BatchSpanProcessor(
new OTLPTraceExporter({
url: 'https://otel.voxmith.com/v1/traces',
headers: { 'X-Voxmith-Org-ID': process.env.VOXMITH_ORG_ID! },
}),
),
);No OTel yet? Full setup:
import os
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from openinference.instrumentation.openai import OpenAIInstrumentor
provider = TracerProvider(resource=Resource.create({"service.name": "openai-py"}))
provider.add_span_processor(
BatchSpanProcessor(
OTLPSpanExporter(
endpoint="https://otel.voxmith.com/v1/traces",
headers={"X-Voxmith-Org-ID": os.environ["VOXMITH_ORG_ID"]},
)
)
)
trace.set_tracer_provider(provider)
OpenAIInstrumentor().instrument(tracer_provider=provider)import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { OpenAIInstrumentation } from '@arizeai/openinference-instrumentation-openai';
const openAIInstrumentation = new OpenAIInstrumentation();
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: 'https://otel.voxmith.com/v1/traces',
headers: { 'X-Voxmith-Org-ID': process.env.VOXMITH_ORG_ID! },
}),
instrumentations: [openAIInstrumentation],
});
sdk.start();
// Import openai AFTER sdk.start() and apply the ESM patch.
import OpenAI from 'openai';
openAIInstrumentation.manuallyInstrument(OpenAI as never);3. Pass userId / sessionId per call
from openinference.instrumentation import using_attributes
with using_attributes(user_id="user-42", session_id="conv-abc123"):
client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
)import { context } from '@opentelemetry/api';
import { setUser, setSession } from '@arizeai/openinference-core';
let ctx = context.active();
ctx = setUser(ctx, { userId: 'user-42' });
ctx = setSession(ctx, { sessionId: 'conv-abc123' });
await context.with(ctx, () =>
client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }],
}),
);using_attributes (Python) and setUser / setSession (TS) propagate via OTel context, landing as user.id / session.id on every span the OpenAI SDK emits inside the block.
What appears in Voxmith
- Conversations grouped by
session.id. - User-level analytics grouped by
user.id. - Events containing OpenInference spans.
- Tool calls when OpenAI tool-use spans are emitted.
Verify
Run one OpenAI call inside the context block, then open Events in Voxmith. Confirm user.id, session.id, model, and message attributes are present.
Troubleshooting
- Import and initialize instrumentation before creating the OpenAI client.
- Confirm the OTLP exporter points at
https://otel.voxmith.com/v1/traces. - For TypeScript, confirm the
openaiand@arizeai/openinference-instrumentation-openaiversions match the table below.
TypeScript version compatibility
Pin matching majors: version mismatches throw does not provide an export named 'APIPromise' at import time:
openai |
@arizeai/openinference-instrumentation-openai |
|---|---|
^6.7.0 |
^4.0.0 |
^4.95.0 – ^5.x |
~2.3.1 |
References
Next steps
- Conversations: review the complete OpenAI interaction.
- Events: inspect SDK or OpenTelemetry activity.
- Intents: organize production conversations by what users wanted.