Use this file to discover all available pages before exploring further.
TracePilot AI instruments your OpenAI calls with a single wrapper function. Every call you wrap becomes a structured span in the dashboard — capturing the prompt, the completion, token usage, latency, and any errors — without changing how the rest of your code reads the response.
Import TracePilot alongside the OpenAI client and create instances of both.
import { TracePilot } from 'tracepilot-sdk';import OpenAI from 'openai';const tp = new TracePilot('tp_live_YOUR_KEY');const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
2
Start a trace
Call tp.startTrace once at the beginning of each agent run. Pass a name that identifies this agent or workflow — it appears as the trace label in the dashboard.
await tp.startTrace('customer-support-agent');
3
Wrap the OpenAI call
Replace a bare openai.chat.completions.create call with tp.wrapOpenAI. Pass the call as a function and include the messages array as the second argument.
const messages = [ { role: 'user', content: 'How do I reset my password?' }];const { result, spanId } = await tp.wrapOpenAI( () => openai.chat.completions.create({ model: 'gpt-4o-mini', messages }), messages);console.log(result.choices[0].message.content);
wrapOpenAI returns the original OpenAI response object unchanged. Any code that reads result.choices[0].message.content or any other field on the completion response continues to work without modification.
Pass the spanId returned by a previous wrapOpenAI or wrapToolCall call to link the current span as a child of that span. This builds a parent-child execution tree in the dashboard.
// Step 1 — no parent, this is the root spanconst { result: plan, spanId: planSpanId } = await tp.wrapOpenAI( () => openai.chat.completions.create({ model: 'gpt-4o', messages }), messages);// Step 2 — linked to the root spanconst followUpMessages = [...messages, plan.choices[0].message];const { result: answer, spanId: answerSpanId } = await tp.wrapOpenAI( () => openai.chat.completions.create({ model: 'gpt-4o', messages: followUpMessages }), followUpMessages, planSpanId // parentSpanId — makes this a child of step 1);
Pass a number to control the order in which spans are displayed within the same parent. Without stepOrder, the dashboard sorts spans by arrival time, which can be inconsistent under concurrency.
const { result, spanId } = await tp.wrapOpenAI( () => openai.chat.completions.create({ model: 'gpt-4o-mini', messages }), messages, parentSpanId, 1 // stepOrder — this span appears first in the tree);
Using a custom ingest endpoint
If you are self-hosting the TracePilot backend, pass your endpoint as the second argument to the constructor.
const tp = new TracePilot( 'tp_live_YOUR_KEY', 'https://your-server.com/api/ingest');
All other methods work identically.
Error handling
If the OpenAI call throws, wrapOpenAI captures the error as a failed span in the dashboard and re-throws the original error. Your existing try/catch blocks remain effective.
try { const { result, spanId } = await tp.wrapOpenAI( () => openai.chat.completions.create({ model: 'gpt-4o-mini', messages }), messages );} catch (err) { // The error is already recorded in the dashboard. // Handle it here as you normally would. console.error(err);}