Skip to main content
The @autter/* npm packages are convenience wrappers, not requirements. Autter Runtime’s ingest API is built on open standards — OTLP/HTTP for servers and a small, documented JSON payload for browsers — so any codebase in any language can send telemetry with nothing but its own ecosystem’s OpenTelemetry SDK, or a plain HTTP request. There are two integration surfaces. Pick per service: The default endpoint is https://otlp.autter.dev; self-hosters substitute their own domain. Auth on every request: Authorization: Bearer <key> (or x-autter-key: <key>), using a server key (autter_rt_…) for OTLP and either key kind for /v1/browser.

Servers: any language with an OpenTelemetry SDK

OTLP/HTTP is OpenTelemetry’s standard export protocol. Every official OTel SDK — Python, Ruby, Go, Rust, Java, .NET, PHP, Erlang/Elixir, Swift, C++ — can export to Autter with configuration only, usually just environment variables:
Install that language’s OTel SDK and OTLP exporter from its own package manager (pip, gem, go get, cargo, Maven/Gradle, NuGet, Composer, …) and enable its auto-instrumentation. Per-language snippets for Go, Rust, Python, and friends live in Stack integrations. How the signals map:
  • Errors — a span with an exception event (record_exception / RecordError in every SDK) or ERROR status becomes an error occurrence, fingerprinted and grouped server-side. The ingester parses your language’s native stack format (Go, Rust, Java, .NET, Python, JavaScript), so occurrences group by the actual function and file — two different defects never merge just because their messages match.
  • Intentional warning/info issues — add autter.severity ("fatal" | "error" | "warning" | "info") to an exception event when that message needs issue grouping. Ordinary diagnostic messages use the logs pipeline below.
  • Usage — HTTP-server spans and the standard http.server.request.duration histogram fold into per-minute request/error/latency rollups automatically.
  • Diagnostic logs — a configured logs provider/bridge sends ordinary messages to /v1/logs, separate from error occurrences. Logs include active trace/span IDs where available and never become issues solely because their severity is error.

Add structured logging

Check deployed /v1/logs support first; self-hosted ingestion needs migration 0011-runtime-logs. Then configure your language’s installed logs provider, OTLP/HTTP log exporter and logger bridge, or a Collector logs pipeline. A trace exporter alone does not send logs. Reuse your existing logger and shared service/environment/release resource, scrub context before export, and set bounded buffering/retries and shutdown flushing in that exporter. The Node helpers are unavailable in other languages, but OTLP records can carry the same operation attributes and captured IDs. Follow the operation logging contract. Keep exception and failed autter.outcome trace events for issue detection. Check stored logs and linked failure evidence separately; platform readers and analysis/fix consumers also need the matching deployment. These variables and the installed SDK do not upgrade your hosted service.

No OTel SDK at all?

If a language or environment has no OTel SDK, or you can’t add dependencies, you have two options:
1

Run an OpenTelemetry Collector

Run the Collector (a single static binary) next to your app, speaking whatever you can emit — syslog, Prometheus, Jaeger, Zipkin, file logs — and point its OTLP/HTTP exporter at Autter with the bearer-token header. No app changes beyond what you already emit.
2

POST OTLP/JSON directly

OTLP has a JSON encoding, so a hand-rolled HTTP request works from anything that can speak HTTPS — curl included:
That’s a complete error report from a shell script. Swap curl for your language’s HTTP client and you have an integration in ~30 lines with zero dependencies.

Browsers: without @autter/runtime-browser

The tiny tracker is just a convenience around POST /v1/browser. The payload contract (version: 1) is stable and small enough to hand-roll — from vanilla JS, a browser extension, a WebView, or any non-npm frontend toolchain:
Rules the hand-rolled path must respect (the ingester enforces them):
  • ≤ 50 events per request, ≤ 1 MB body, message ≤ 4000 chars, stack ≤ 32000 chars.
  • route is a path only — never include query strings (they’re stripped defensively, but don’t send them).
  • Client keys (autter_rtc_…) are origin-restricted; the Origin your page sends must be on the key’s allow-list.
  • Never put a server key (autter_rt_…) in browser code. If your site has a backend, prefer relaying through it — the relay is just an authenticated proxy that forwards this same JSON with the server key.
The full schema is browserPayloadSchema in packages/otlp-ingester/src/normalize-browser.ts — the code is the contract.

AI-assisted setup works for non-npm codebases too

The agent skills are not npm-specific — npx is only the installer for the skill files (any machine with Node can run it once; the target codebase doesn’t need Node at all). The skills include Python, Go, Rust, and a generic any-OTel-language guide:
Then tell your coding agent: “install Autter Runtime in this project” — it inventories the services, picks the right per-language approach from above, and wires it up. See AI agent skills for the full setup walkthrough.