docs

Core concepts

How organizations, projects, services and environments fit together, what a DSN contains, and how keys, roles and the time scope decide what you see.

Unhandled files every span, log and metric under one service, in one project, in one organization, tagged with one of three environments. Read this page before you connect a second app. It decides where your data lands and who can see it.

How the pieces fit

An organization holds projects. A project holds services. Each service sends with its own DSN, and every record it sends carries an environment.

  • acme/organization with the plan, members, teams and integrations
    • shop/project with issues, alerts, dashboards, uptime and deployments
      • shop-apiservice, one DSN
      • shop-workerservice, one DSN
      • shop-webservice, one DSN
    • internal-tools/project
      • admin-apiservice, one DSN

The three environments, production, staging and development, exist in every project. They are a tag on the data, not a level of the tree.

Organizations

An organization is your workspace. It owns the plan and trial, the members and teams, and the integrations with GitHub and Linear. The pages under Organization in Settings, such as Members, Teams, Integrations and Plan & usage, apply to the whole organization.

Signing up creates an organization with you as its admin, a Default project, and a General team that holds you and that project. You can belong to several organizations and switch between them in the sidebar. App URLs carry the organization slug, as in /o/:org/settings/members.

Projects

A project groups the services of one product. Most of the sidebar works per project: traces, logs, metrics, exceptions and issues, the built-in dashboards, custom dashboards, alerts, uptime, the status page and deployments.

A trace that crosses services of the same project stays one trace. A page load in shop-web that calls shop-api shows as a single tree.

Admins create projects from Settings, Projects, with New project. A new project belongs to no team. Members who are not admins see it only after an admin adds it to one of their teams.

Environments

Every project has exactly three environments. There is nothing to create or rename.

EnvironmentSelector label
productionPRD
stagingSTG
developmentDEV

The sender picks the environment, not Unhandled. It travels in the x-unhandled-env header, and the ingest endpoint rejects any other value with a 400, so prod or local never get through.

The Node.js SDKs and the AdonisJS agent read the environment from the environment option first, then from UNHANDLED_ENV, then from APP_ENV, then from NODE_ENV when that is one of the three names. With none of them set, the environment is development. Any other value in the option or in UNHANDLED_ENV makes the SDK throw UnhandledConfigError at startup. An APP_ENV outside the three names is skipped. The AdonisJS agent's generated config fills the option from APP_ENV. Other OpenTelemetry SDKs set the header themselves.

In the dashboard, the Env selector in the top bar decides which environment every page shows. Pages open on Production when none is chosen.

Services

A service is one deployable unit, such as an API, a queue worker or a front end. Admins create services from Settings, Services under Project, with New service.

Namestringrequired

Free text up to 80 characters. Rename it at any time.

Telemetry namestringrequired

Becomes service.name on everything the service sends. Up to 120 characters, starting with a letter or digit, then letters, digits, ., _ or -. Unique among the live services of the project. It cannot change later.

IDuuid

Assigned by Unhandled. It is the path of the DSN.

The DSN decides the service, not the SDK. Unhandled files every record under the DSN's service and overwrites service.name with that service's telemetry name. Renaming a service changes only its display name. The telemetry name and the DSN stay the same.

Deleting a service removes it from every environment and revokes its key. Data it already sent stays until retention removes it.

DSN

A DSN is a URL that holds everything an SDK needs to send data to one service:

https://[email protected]/0b4f6c2e-8a1d-4c3e-9f7a-1234567890ab
Schemestringrequired

https or http.

API keystringrequired

The user part of the URL. uh_live_ or uh_test_ followed by 16 to 56 letters, digits, _ or -. Keys issued from the Services page start with uh_live_.

Ingest hoststringrequired

The origin the SDK posts OTLP data to, served by the ingest receiver rather than the web app. Unhandled builds it from INGEST_URL, or from APP_URL when INGEST_URL is not set, which works when a proxy sends /v1/* and the Sentry endpoints on that host to the receiver.

Service IDuuidrequired

The service's UUID, as the only path segment.

A DSN with a password, a query string or a fragment is invalid. The Unhandled SDKs then disable export and log a warning that starts with Invalid UNHANDLED_DSN: and names the problem.

The DSN carries no environment. Use the same DSN on every host of a service and set the environment per deployment.

A Sentry SDK can't use this DSN, because it reads the last path segment as a numeric project id. Give it the Sentry DSN instead, https://<api key>@<ingest host>/<project id>: the same key and host, ending in the project's id. The key still picks the service. The Sentry SDK guide in the setup instructions shows it filled in.

An SDK turns the DSN into three request headers and posts to /v1/traces, /v1/logs and /v1/metrics on the ingest host:

HeaderValue
x-api-keyThe API key
x-unhandled-service-idThe service ID
x-unhandled-envproduction, staging or development

Any OpenTelemetry SDK can send the same headers, whatever its language. The quickstart shows this split for each language, and Any OpenTelemetry SDK has the full wire contract.

API keys

Each service has one active key at a time. Unhandled stores only a hash of it and its last four characters, so the full DSN appears once, right after you create the service or rotate its key. The Services table then shows the key as uh_live_ plus those four characters, or Revoked.

From a service's row menu, an admin can:

  • Rotate key. Shows a new DSN. You choose how long the current key keeps working: Stop it now, 1 hour, 24 hours or 7 days. Deploy the new DSN to every environment of the service before then.
  • Revoke key. Rejects telemetry sent with the key, and with a previous key still inside its grace period, until you rotate to a new one.
RequestResponse
Key is revoked, or its service is deleted401
Key is valid but belongs to a different service than x-unhandled-service-id403
x-unhandled-env is missing or not one of the three names400
The organization is suspended403
The service or organization is over its rate limit or ingest quota429 with Retry-After

The ingest receiver caches key checks, and Postgres tells it to drop that cache whenever a key, service, organization or plan changes. A revoked key, a deleted service or a suspended organization is refused on the next request. If the receiver loses its Postgres connection, cached keys keep working for up to 15 minutes until it reconnects.

DSN keys are not the only credentials. Declaring deployments uses project deploy keys that start with dk_, see the Deployments API. AI assistants connect to the MCP server with OAuth instead of keys.

Members, roles and teams

An organization member is either an admin or a member.

  • Admins see every project and manage the organization, including projects, services and keys, members and teams.
  • Members see the projects attached to their teams, and nothing else.

Admins invite people from Members with an email address and a role. Invitations expire after 7 days. An organization always keeps at least one admin, so the last admin cannot be demoted or removed.

Teams connect members to projects. Add people and projects to a team on the Teams page. Access and permissions covers the full rules.

Time scope

The top bar of every telemetry page holds the same controls, and they apply to the whole page.

Envenvironmentdefault production

One of the three environments.

Serviceslistdefault all

All services, or any subset of up to 50.

Time rangepresetdefault 24h

15m, 1h, 6h, 24h, 7d or 30d, or a custom range. You can also type a range, such as 2h, yesterday 14:00-15:00 or last monday. A custom range ends no later than now and spans at most 90 days. The arrows shift the window back or forward, and Zoom out doubles it.

Intervalbucketdefault auto

The chart bucket size, 1m, 5m, 15m, 1h, 6h or 1d. Only intervals that give between 2 and 1500 buckets are offered. By default Unhandled picks the smallest one that keeps a chart at 200 buckets or fewer.

Compareoptiondefault off

Previous period, 1 day ago or 1 week ago. Stat cards gain a change against that window, and charts draw it as a dotted line.

Refreshaction

Reloads the data for the same window. Auto-refresh reloads it every 10 seconds, 30 seconds or minute while the tab is visible, and pauses on a custom range.

The scope lives in the URL query (env, services, range, from, to, interval, compare), so a copied link opens the same view for a teammate.

Find your way around

The sidebar lists the pages of the current project. Settings at the bottom of the sidebar opens its own navigation in three groups: Project (General, Services, Deploy keys, Source maps, Issue triage), Organization (General, Projects, Members, Teams, Integrations, Ingest domain, Plan & usage, Feedback) and Account (Profile, Notifications). Members do not see the project pages that only admins can use.

Press Cmd+K, or Ctrl+K outside macOS, to open the command palette. It searches pages, settings, projects, organizations, alerts, monitors, status pages, dashboards and issues, lists the records you opened recently, and runs actions such as switching the theme. Paste a trace ID to open that trace. Pages add their own actions, such as resolving the issue you are looking at.

Press ? to list every keyboard shortcut that works on the current page. Two-key sequences go to a page: g o Overview, g i Issues, g a Alerts, g u Uptime, g t Traces and g l Logs. / focuses the page's search. Letter keys do nothing while a text field has focus.

Telemetry signals

Unhandled stores the three OpenTelemetry signals.

Exceptions arrive inside those signals, either as exception events on spans or as log records with exception.* attributes, such as the ones the Unhandled SDKs and standard logging bridges send. Unhandled groups them into issues by exception type and the top in-app stack frames. An issue is open, resolved or archived, has a priority from low to critical, and can link to a GitHub or Linear issue.