Verify your setup
Separate a delivered connection check from your application actually recording its model calls.
On this page
Two different things can be true, and confusing them is the most common reason a setup looks finished when it is not:
- Connection verified
The key, the address and the network work. A diagnostic was stored.
- Application recording
Your own code loaded the SDK and a real model call was captured.
A connection check never calls an AI provider, costs nothing and captures no prompt. It also proves nothing about your application.
Check the connection from the CLI
npx --yes @tracehatch/cli@0.3.0 doctordoctor resolves the SDK from the selected application's installed
dependencies, loads its environment, and sends a diagnostic. It then verifies
that exact trace id using the setup receipt scoped to the ingest key — an
accepted HTTP batch on its own does not count as success.
It reports the two states separately:
- Connection verified — that exact diagnostic was processed in this project and environment.
- Application recording — a model-call trace from the same key and environment was processed after the diagnostic.
--wait <seconds> waits up to 600 seconds for that application call and exits
with status 2 if the connection works but no application call appears. Errors
exit 1. Without --wait it exits 0 and says plainly that application recording
is still waiting. --fresh resets the baseline with a new diagnostic.
A local .tracehatch/setup.json keeps the diagnostic id and nonsecret project
metadata so the next run can recognise a call you made in between. It contains
no key.
Check the connection from a script
If you would rather not use the CLI, save this beside your package.json and run
it once. It sends a diagnostic trace with no model key, paid request or prompt
capture.
import "@tracehatch/sdk/auto"
import { trace, flushWithResult, shutdown } from "@tracehatch/sdk"
try {
const traceId = await trace("tracehatch-setup-check", (run) => run.id)
const result = await flushWithResult()
if (result.status !== "accepted")
throw new Error(`Delivery was not confirmed: ${JSON.stringify(result)}`)
console.log({ traceId, delivery: result.status })
} finally {
await shutdown()
}node tracehatch-check.mjsRun it beside the environment file holding your key: the SDK picks its own
settings up from there. On Node.js 22 or newer node --env-file=.env tracehatch-check.mjs also works. A real exported terminal variable still wins.
status: "accepted" means the API stored the batch with a matching span count. A
web page at the wrong address, a rejected key, a timeout and disabled tracing all
fail this check rather than passing quietly. What each status means:
Delivery and flushing.
Confirm your application is recording
This is the step that matters.
- Restart your server so the SDK loads first.
- Trigger one AI feature your application already has.
- Open Traces in the project, with the same environment selected as the key you configured.
- Open the newest run and confirm it is the action you just performed — not the diagnostic, and not another app sharing the key.
A model step shows its duration, reported tokens, finish reason, errors and cost where pricing is available. A failed run opens on the span that broke.
Nothing arrived
Work through these in order; they cover almost every case.
| Symptom | Most likely cause |
|---|---|
| Diagnostic fails too | The key is wrong or revoked, or the API address is wrong for a self-hosted installation. |
| Diagnostic works, no application calls | The SDK loaded after your provider client was constructed, or the server did not restart. |
| Traces in the wrong place | The key selects the project and the environment; check which key the server has. |
| Calls recorded, no bodies | TRACEHATCH_CAPTURE_BODIES=false — timings and usage are still recorded. |
| Calls recorded, no cost | The model has no price coverage; usage is still counted. |
The long version, including serverless and monorepo cases, is in Troubleshooting.