Prefer to have an AI coding agent set this up for you? See AI agent skills —
npx skills add Autter-dev/autter-skills --all, then tell your agent “install Autter Runtime in this project.”Concepts
Two kinds of keys — never mix them up:
Two ways to send browser events:
- Relay (recommended, including static sites) — the browser posts to a same-origin route on your server, Worker, or edge function, which forwards with your server key. Allow the relay in
connect-src(usually'self') and check the actual browser request. See Stack integrations for the serverless relay. - Direct (lossy fallback for pure-static only) — the browser posts straight to the ingester with a publishable client key. Ad-blockers silently drop these cross-origin requests.
1
Run the ingester
For a local try-out, clone the repo and start ClickHouse plus the ingester with Docker Compose:There’s no key step. The local Compose setup accepts the built-in key
autter_rt_local_dev_only, but only from your own machine. A deployed ingester never accepts it. Point your app at it and check the connection:verify goes through key, network, ingester, storage, auth, ingest, stored, trace, release and logs, and stops at the first step that fails with what to do. Its test event never opens an issue. Run it first whenever events don’t show up. See Is my data arriving?.For real deployments, see Self-hosting or use Autter’s hosted ingester at otlp.autter.dev: set AUTTER_ENDPOINT=https://otlp.autter.dev and your repository’s server key, then run the same two commands.2
Instrument your backend
instrument.cjs — it must load before your app:GIT_SHA to the deployed commit SHA. See Endpoint regressions for metric requirements and retention limits.This records HTTP request metrics and captures crashes and unhandled
promise rejections. A rejection from a promise started during a request
keeps that request’s route and request id.On Express, add request ids and the error hook to your app:@autter/runtime-node 1.10.0 or later, the error behind every
Express 5xx is recorded with its type, message, stack, route and request
id even without autterErrorHandler(). That holds in every router,
including routers with their own error handler. The handler adds coded
errors that end in a 4xx, and it never reports an error twice, so one
app.use(autterErrorHandler()) at app level is enough. On older versions
it is required: without it a thrown error shows up only as
GET /route returned 500, with no stack. Fastify and Koa need their
hooks (autterFastifyErrors, autterKoa); see
Integrations.For handled errors:@autter/runtime-node/testing keeps every record in memory.npx @autter/runtime-node verify --service payments-api. If your app has no key, or the ingester refuses it, the SDK prints one line saying so at startup or on the first refusal.3
Add server operation diagnostics
Node/Next.js SDK and ingester 1.4.0+ are required (compatibility table).
npx @autter/runtime-node doctor shows whether operation logging is active
for your installed SDK and ingester, and verify checks that a log record
is stored.Once supported, add logging options to the existing initialization and
wrap meaningful checkout/job boundaries with withRuntimeOperation.
Record measured steps, bounded nested context, and explicit business
outcomes. Use runtimeLogger.info/warn/error for diagnostics, while
keeping exception or declared failed-outcome capture for issues.Follow the checkout example.
A callback that returns normally defaults to success, so declare a failed
payment result explicitly. Preserve existing loggers and await flushing at
the end of short-lived jobs. If support is pending, continue basic capture
and report that gap.4
Instrument your frontend
5
See your own events
verify proves the path; it is safe in production because its test event never opens an issue or counts as a request. To see your app’s own events locally, trigger an error, wait a few seconds (server errors arrive within 2 s, request counts within 60 s; see arrival times), then query ClickHouse. In production, inspect existing traffic instead:docker compose exec clickhouse clickhouse-client --password dev.When operation logging is enabled, verify it separately:Production checklist
- Server keys only in backend env vars; client keys only where a relay is genuinely impossible.
- Client keys have
allowedOriginsset to your exact app origins. releaseis wired to your git SHA in both frontend and backend — it powers regression detection (“broke in release X”).- Keep trace sampling at ~1% (
traceSampleRate) — errors are always captured regardless (what is sampled). npx @autter/runtime-node verifypasses from where the app runs (CI or the deployed host), with the production endpoint and key.- Confirm the logging SDK release and ingester/platform deployment separately; redeploy the application after upgrading.
- Declare business outcomes, preserve existing loggers, and check buffered/dropped records and flush failures. Logs are best-effort diagnostics.
- Check export volume after enabling
retainTracesAboveMs. The platform rollout does not enable this option in existing applications. - The relay route keeps its built-in per-IP rate limit, or your WAF covers it (
perIpRateLimit: false). - Direct browser ingest: your CSP includes
connect-src https://your-ingester…, and you accept that ad-blockers may drop some events (the relay avoids this). - The ingester’s
/healthzis wired to your load balancer health check.
Installation
Install the right package for your stack, including Next.js.
Stack integrations
Per-stack setup for React, Node, Next.js, Go, Rust, and any OpenTelemetry SDK.

