docs

Install for your stack

Pick your language or framework and copy the install and config steps that connect it to Unhandled.

Unhandled stores standard OpenTelemetry data, so every stack connects the same way: something in your process exports OTLP over HTTP with the three headers taken from your DSN. What differs is how much of that is done for you.

Setup

The snippets use a sample DSN and the production environment. In the app, Setup instructions on a service row shows the same steps with that service's endpoint and id filled in, and a new service shows them with its full DSN. There you also pick the environment. The last step follows it: development runs the dev server, and staging or production builds the app and starts the built server. /docs/install?stack=<id> opens a stack directly.

AdonisJS has two options. Unhandled agent installs @unhandled/agent-adonisjs. Already using @adonisjs/otel keeps the official package and only sets its exporter variables, as described in Keep @adonisjs/otel.

Unhandled SDKs

OpenTelemetry SDKs

Coding agents

Already on Sentry

Any Node.js process: HTTP servers, workers and scripts, with auto-instrumentation. Guide

  1. 1

    Install the package

    bash
    npm install @unhandled/node
  2. 2

    Add the environment variables

    .env
    UNHANDLED_DSN=https://[email protected]/0b6f3c1e-8d2a-4f7b-9c5e-2a1d4e6f8b3c
    APP_ENV=production

    APP_ENV decides which environment the data lands in: production, staging or development.

  3. 3

    Load it before your app

    bash
    node --import @unhandled/node/register server.js

Set up with an AI agent

Set up with an AI agent gives you a prompt for Claude Code, Cursor, Codex or any agent that edits files and runs commands. Paste it in the project's root. The prompt carries the DSN, the environment and the OTEL_* variables, and tells the agent to:

  1. Detect the stack from the project's manifest files.
  2. Install the matching Unhandled package, or the official OpenTelemetry SDK for other languages.
  3. Set UNHANDLED_DSN and APP_ENV in the env file the app loads.
  4. Hook up error reporting and set user.id from the signed-in user.
  5. Start the app for the chosen environment and send one request.
  6. Confirm the request arrived.

For the last step, connect the MCP server first. The agent then calls list_traces for the service and environment and finds its own request. Without it, the agent asks you to check Last seen on the service.

The DSN and the headers

A DSN such as https://uh_live_…@ingest.example.com/0b6f3c1e-… holds everything a sender needs. The Unhandled SDKs read it from UNHANDLED_DSN. OpenTelemetry SDKs need it split into parts:

From the DSNOpenTelemetry setting
The origin, https://ingest.example.comOTEL_EXPORTER_OTLP_ENDPOINT
The username, the API keyx-api-key in OTEL_EXPORTER_OTLP_HEADERS
The path, the service idx-unhandled-service-id in OTEL_EXPORTER_OTLP_HEADERS
Your deployment's environmentx-unhandled-env in OTEL_EXPORTER_OTLP_HEADERS

The exporters append /v1/traces, /v1/logs and /v1/metrics to the endpoint. Any OpenTelemetry SDK is the full wire contract.

What each stack fills in

Traces, logs, metrics, issues, requests, queries and external calls work from any SDK that follows the OpenTelemetry semantic conventions. A few pages depend on spans that only some instrumentations produce:

PageNeedsWho creates it
EmailsSpans with email.systemThe AdonisJS agent, for @adonisjs/mail. Other stacks add them by hand.
CommandsA root span marked unhandled.entry_point=cli, or an INTERNAL span with process.executable.nameThe AdonisJS agent, for Ace commands. Other stacks follow the OpenTelemetry CLI conventions.
Usersuser.id or enduser.id on request spansYour auth middleware, in any stack.
System metricsRuntime and host metricsNode.js SDKs report the event loop and V8 heap. Other runtimes report CPU and memory.

Check the data

Send a few requests, then open Settings, Services. The service shows events, a Last seen time and a badge with the language and SDK it reports.