Skip to main content

Documentation Index

Fetch the complete documentation index at: https://tracepilot.mintlify.app/llms.txt

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.

Prerequisites

Install the SDK and make sure you have an OpenAI API key ready.
npm install tracepilot-sdk openai
Get your TracePilot API key by signing in at tracepilotai.com with GitHub or Google. Your key looks like tp_live_xxxxxxxxxxxxxxxx.

Wrap your first call

1

Import and initialize

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.

Full working example

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 });

async function runAgent() {
  await tp.startTrace('customer-support-agent');

  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);
  // Open tracepilotai.com/dashboard — your trace is already there.
}

runAgent();
After the function runs, open tracepilotai.com/dashboard. The trace appears immediately with no additional configuration.

Optional parameters

wrapOpenAI accepts two additional parameters that become useful once your agent has multiple steps.

parentSpanId

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 span
const { result: plan, spanId: planSpanId } = await tp.wrapOpenAI(
  () => openai.chat.completions.create({ model: 'gpt-4o', messages }),
  messages
);

// Step 2 — linked to the root span
const 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
);

stepOrder

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
);
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.
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);
}