docs
First event in five minutes
Install the agent, set two environment variables, mount the middleware. Everything below that — alert rules, the API, the design system this site is built on — is here on one page rather than scattered across forty.
quickstart
Get a service reporting
Four steps. The only one that touches application code is the third, and it is one line.
- 01
Install the agent
One package, no build step. The agent buffers events in memory and flushes on a two-second interval, so an ingest outage costs you telemetry, never requests.
bashnpm install @tracepoint/node # or: pip install tracepoint · go get go.tracepoint.dev/agent - 02
Set the key and the service name
Write keys are per-environment and scoped to ingest only — a leaked write key cannot read your data or change a routing rule. Rotate from Settings → Keys without a redeploy; both keys stay valid for an hour.
bashTRACEPOINT_KEY=wk_live_3f9a2c... TRACEPOINT_SERVICE=checkout-api TRACEPOINT_ENV=production - 03
Add the middleware
Mount it before your routes so the timer starts at the edge of your app. The route pattern is read from the router, which is what keeps /v2/checkout/:cartId one series instead of one per cart.
tsimport express from "express"; import { tracepoint } from "@tracepoint/node"; const app = express(); app.use(tracepoint({ service: process.env.TRACEPOINT_SERVICE, env: process.env.TRACEPOINT_ENV, // Health checks are excluded by default and never bill. ignore: ["/healthz", "/readyz", "/metrics"], })); app.post("/v2/checkout/:cartId", handleCheckout); - 04
Confirm ingest
Events appear in the console within about five seconds. If nothing arrives, the verify command tells you which of the three usual causes it is — wrong key, blocked egress, or a service name that does not match the one in the workspace.
bashnpx @tracepoint/cli verify ✓ key valid (workspace: northwind, env: production) ✓ egress to ingest.tracepoint.dev:443 ok ✓ 214 events received in the last 60s
instrumenting
SDKs and what they send
First-party middleware for five runtimes, and a documented wire format for everything else.
| runtime | package | frameworks |
|---|---|---|
| Node.js | @tracepoint/node | Express, Fastify, Hono, Koa, Next.js route handlers |
| Python | tracepoint | FastAPI, Django, Flask, Starlette |
| Go | go.tracepoint.dev/agent | chi, gin, echo, net/http ServeMux |
| Ruby | tracepoint-rb | Rails, Sinatra, Hanami |
| Elixir | tracepoint_ex | Phoenix, Plug |
| Anything else | HTTP | POST batches to /v1/events — the wire format is stable and documented |
Route patterns, not paths
The middleware reads the matched pattern from your router. If you are posting events directly, send `route` as the pattern and `path` as the raw URL — Tracepoint groups on the former and only stores the latter on sampled events.
Sampling
Below 500 rpm nothing is sampled. Above it, Tracepoint keeps every error and every request slower than the current p95, and samples the remainder at a rate it publishes on the service page. Percentiles are computed pre-sampling at the agent, so accuracy does not depend on the sample rate.
Log forwarding
Point your existing log shipper at the ingest endpoint, or let the agent capture your application logger directly. Either way lines are fingerprinted at ingest; nothing is stored unstructured.
alerting
Alert rules and routing
Rules live in your repository as YAML and apply on push, so changing who gets paged goes through review like any other change.
# tracepoint.yml — checked into the repo, applied on push
rules:
- name: checkout p99
service: checkout-api
signal: latency.p99
route: "POST /v2/checkout/:cartId"
condition: "> 800ms for 3m"
severity: sev2
notify: codeowners # resolves via CODEOWNERS
escalate_after: 10m
- name: checkout 5xx
service: checkout-api
signal: errors.rate_5xx
condition: "> 1% for 2m"
severity: sev2
notify: codeowners
- name: novel log patterns
service: "*"
signal: logs.novel_pattern
condition: "> 25/hr"
severity: sev3
notify: "@northwind/platform"- Rules live in your repository and apply on push, so an alerting change goes through review like any other change.
- `notify: codeowners` resolves the owning team from the CODEOWNERS entry covering the route's handler, then pages that team's current on-call.
- Escalation is time-based per severity: unacknowledged sev1 escalates in 5 minutes, sev2 in 10, sev3 never pages outside working hours.
- Every destination — Slack, PagerDuty, Opsgenie, webhook — receives the same payload shape, documented under `POST /v1/incidents` below.
api reference
The /v1 surface
Seven endpoints. Everything the console does, your scripts can do — including reading the computed series back out in Prometheus format.
POST/v1/events
Ingest a batch of request, log, or check events.
Up to 1,000 events per batch, gzip encouraged. Returns 202 with an accepted count; malformed events are reported individually rather than failing the batch.
GET/v1/services
List services in the workspace with current health, rpm, p99, and error rate.
GET/v1/services/:service/routes
Per-route percentiles and error rates over a time window.
Window defaults to 1h. `resolution=1m` is available for the last 24 hours, `5m` for the rest of retention.
GET/v1/incidents
List incidents, filterable by service, severity, and state.
PATCH/v1/incidents/:id
Acknowledge, reassign, or resolve an incident.
The same call the Slack action buttons make. Acknowledgement is idempotent.
POST/v1/deploys
Record a deploy so it appears as a marker on every chart.
Send `service`, `sha`, and optionally `diff_url`. The GitHub Actions integration calls this for you.
GET/v1/metrics
Read back computed series in Prometheus exposition format.
Available on every plan including Starter. Scoped to the API key's workspace.
Authentication
Bearer token in the Authorization header. Write keys (`wk_`) can only reach /v1/events and /v1/deploys; read keys (`rk_`) can reach everything else. There is no key that can do both, deliberately.
Rate limits
Ingest is limited by events per second, not requests: 20,000/s on Team, negotiated on Enterprise. Read endpoints are 120 requests per minute per key. Both return `Retry-After` and never 429 an ingest batch without accepting what it can.
Versioning
The `/v1` surface is stable. Additive changes ship without notice; anything breaking gets a new prefix and 12 months of overlap. Deprecations appear in the changelog and in a `Sunset` header on the response.
Base URL is https://api.tracepoint.dev. Ingest terminates separately at ingest.tracepoint.dev in all four regions; the SDK picks the nearest and fails over on its own.
design system
Brand and component reference
The tokens this site and the console are both built from. It is short on purpose — a design system nobody can hold in their head gets ignored by the third contributor.
Colour tokens
- --backgroundPage ground
- --cardPanel and card surface
- --mutedRecessed rows, table headers
- --borderHairlines and panel edges
- --primarySignal cyan — actions, healthy series
- --accentAlert violet — eventing and routing surfaces
- --successHealthy state only
- --destructiveIncidents. Never decoration.
Every pair clears WCAG AA in both themes. Values are declared once in forge-theme.css and consumed everywhere as variables — there are no hex codes in any component.
Type scale
- DisplayKnow what brokeChivo 600 · 3.5rem / 1.03 · -0.03em
- HeadingAlert rules and routingChivo 600 · 2rem / 1.12 · -0.028em
- BodyPercentiles are computed per route, over rolling one-minute windows.Manrope 400 · 1.0625rem / 1.65
- Marker/ SIGNALSJetBrains Mono 500 · 0.7rem · 0.16em, uppercase
- Codep99 1,412ms · 3.10% · 4.2k rpmJetBrains Mono 400 · 0.85rem / 1.6 · tabular
Components
- Radii are 6px. Nothing on this site is a pill — a console has corners, and the marketing site should not promise a shape the product does not have.
- Numbers are always tabular and always monospace, including in body copy. A latency figure that reflows as it updates reads as decoration rather than as data.
- Red is reserved for incidents. A destructive-coloured button on a page about alerting would be the single most confusing thing we could do.
- Every panel is a 1px border and a flat surface. Elevation is used once, on the hero composition, and nowhere else.
Nothing here needs a sales call to try
The free plan runs the same ingest pipeline, the same alerting, and the same API as Enterprise. The quickstart above works on it verbatim.