TypeScript SDK
Pure TypeScript SDK for LLM traces, logs, and GenAI metrics. Works on Node and edge runtimes, built on OpenTelemetry with zero lock-in.
Built by
telemetry.dev
Language
TypeScript
Packages
@telemetry-dev/sdk · @telemetry-dev/otel
Category
SDKs
Docs
About the TypeScript SDK
@telemetry-dev/sdk adds LLM traces, logs, and GenAI metrics to any TypeScript or JavaScript app. Spans use the gen_ai.* semantic conventions and ship as OTLP protobuf. It runs on Node >= 20.19 and edge runtimes — Vercel Edge and Cloudflare Workers with nodejs_compat — and is the foundation the OpenAI, OpenRouter, Anthropic, Gemini, and Bedrock wrappers build on.
Key features
- Ergonomic span API:
observe(fn)wraps any function (args become input, return becomes output);startSpanandstartActiveSpangive manual control with typed generation fields. - User and session correlation:
propagateAttributes({ userId, sessionId, metadata }, fn)stamps every span and log record in scope. - Logs and metrics included:
log()emits trace-correlated log records; GenAI duration and token-usage histograms are recorded automatically. - Serverless-ready:
exportMode: "immediate"plusflush()or the platform'swaitUntilkeep data flowing from frozen isolates. - Bring your own OTel: Already running NodeSDK or
@vercel/otel? AttachTelemetrySpanProcessorfrom@telemetry-dev/otelto your existing provider instead. - Fail-open: Without an API key every call is a silent no-op — the SDK never throws into your code.
Get started
This Node.js example sends one real OpenAI request and records its token usage. OpenAI charges apply.
Use Node.js 22 or later. Install the SDK, its OpenTelemetry peer dependency, the OpenAI client, and the TypeScript runner:
npm install @telemetry-dev/sdk @opentelemetry/api openai
npm install --save-dev tsx
Get a project API key from telemetry.dev. Set the two keys in your shell:
export TELEMETRY_DEV_API_KEY="your-project-api-key"
export OPENAI_API_KEY="your-openai-api-key"
Keep these keys out of browser code and version control. Save this code as first-trace.mts:
import OpenAI from "openai";
import { init, startSpan, flush, shutdown } from "@telemetry-dev/sdk";
const apiKey = process.env.TELEMETRY_DEV_API_KEY;
if (!apiKey) throw new Error("Set TELEMETRY_DEV_API_KEY.");
const openai = new OpenAI();
init({
apiKey,
serviceName: "typescript-sdk-first-trace",
environment: "development",
onError: (error) => console.error("[telemetry.dev]", error),
});
const model = "gpt-4o-mini";
const messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [
{ role: "user", content: "What is OTLP?" },
];
const generation = startSpan("chat-completion", {
type: "generation",
model,
provider: "openai",
input: messages,
});
try {
const res = await openai.chat.completions.create({
model,
messages,
max_completion_tokens: 100,
});
generation.end({
responseModel: res.model,
output: res.choices[0]?.message,
usage: {
inputTokens: res.usage?.prompt_tokens,
outputTokens: res.usage?.completion_tokens,
},
});
console.log(res.choices[0]?.message.content);
console.log("Trace ID:", generation.traceId);
} catch (error) {
generation.end({ error });
throw error;
} finally {
await flush();
await shutdown();
}
Run the file:
npx tsx first-trace.mts
Open your telemetry.dev project and select the development environment. Find the printed trace ID and open its chat-completion span. A successful request records the model, input and output token counts, and latency. The span includes the prompt and response if your project capture settings permit them.
flush() sends pending telemetry before exit. shutdown() releases the SDK resources. The finally block runs after success or an OpenAI error.
Cost is computed server-side from usage and current model pricing — set costUsd only when you want to override it.