Skip to content

Manual installation

Install the SDK, set the ingest key and load it before your provider clients, without the installer.

On this page

The integration is one import. The SDK reads its own settings from the environment and captures provider calls at the fetch boundary, so there is no file to generate, no client to wrap and no option you must pass.

Package

@tracehatch/sdk@

0.5.0
Runtime
Node.js 18+, ESM and CommonJS
Runtime dependencies
None
Where
The server package that makes model calls

Create a project and a key

Create a project, then create or choose an ingest key in project setup — Project settings → API keys manages them too. A key selects both the project and the environment, so use a development key while you experiment. A new secret is shown once; save it then.

Keys for the production environment start with th_live_; every other environment gets th_test_.

Install the SDK

Install it in the server package that makes your model calls, beside the package.json your server actually runs.

Terminal
npm install --save-exact @tracehatch/sdk@0.5.0

Commit the updated lockfile. Bun runtime compatibility is unverified.

Save the key in the private server environment

.env for Node.js · .env.local for Next.jsEnvironment
TRACEHATCH_API_KEY=your-project-api-key

Keep the file ignored by Git and never expose the key to browser code — there is no public variant of this variable. Restart your server after changing it.

Load the SDK before your provider clients

Provider clients capture fetch when they are constructed, so the SDK has to be loaded first. Pick whichever matches how your server starts.

Keep your existing entry file and argumentsTerminal
node --import @tracehatch/sdk/auto server.js

The preload flag runs before your entry file's imports, so clients created at import time are captured too. Keep the entry file and arguments you already run.

Restart and trigger an AI action

Keep your existing provider credentials, model and requests. Restart the server, use one AI feature you already have, then open Traces and confirm the run is the action you just performed.

Next.js

Next.js owns startup, so it loads the SDK from instrumentation.ts rather than a preload flag.

instrumentation.ts · beside app/ or pages/, inside src/ when you use itTypeScript
export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    await import("@tracehatch/sdk/auto")
  }
}

Save it beside your app or pages directory — inside src when your app uses src/app. Merge it into an existing register() function if you have one, keep the key in .env.local, and use the Node.js runtime for AI routes. The Edge runtime and browser code are not supported.

In short-lived route handlers, hand the final flush to after() so export finishes after the response:

app/api/chat/route.tsTypeScript
import { after } from "next/server"
import { flush } from "@tracehatch/sdk"

export async function POST(request: Request) {
  const response = await answer(request)
  after(() => flush())
  return response
}

More runtimes: Frameworks and runtimes.

Which providers are captured

OpenAI
Captured automatically: chat.completions, responses and embeddings, including streams and background responses. Keep your existing client and model.
Anthropic
Captured automatically: messages.create and messages.stream. Keep your existing client and Claude model.
OpenAI-compatible endpoint
Captured automatically for OpenAI-compatible hosts such as Azure OpenAI, Groq, Mistral, Together, OpenRouter, DeepSeek, xAI and Ollama. Provider-specific pricing is not guaranteed.
Gemini / other providers or frameworks
Frameworks that call a supported API shape through fetch are captured automatically. Other providers use a manual generation span around the real call, or the log endpoint from any language.

Support follows API methods and response shapes, not a fixed model list. A new or custom model is captured; whether its price is known is a separate question, and unpriced calls are counted but show no cost.

What you get without writing anything else

  • Runs, generations, tool steps, sessions, end users and prompt versions — see Automatic capture.
  • The run's agent comes from the nearest package.json name, and its release from the deployment's commit (VERCEL_GIT_COMMIT_SHA, GITHUB_SHA and similar, then git HEAD).

Add trace(), span() and tool() only where you want a run named your way, or a step the provider never sees.

What is not captured

  • Provider clients constructed before the SDK loaded — they kept the original fetch.
  • A client given its own fetch option.
  • Non-JSON request bodies, such as audio uploads.
  • Endpoints outside the supported set.

If nothing arrives, Troubleshooting goes through the causes in order.