How it works
- You create a server key for a Terma project. This key authenticates telemetry sent to Terma.
- In OpenRouter, you add Terma as an OpenTelemetry Collector destination under Broadcast, using Terma’s OTLP endpoint and the server key as a bearer token.
- After every request, OpenRouter asynchronously posts an OTLP trace to Terma. Terma recognises the OpenRouter format, records a model call with tokens and cost, and groups calls into sessions.
Before you start
- A Terma project. Every server key is scoped to one project, and OpenRouter traffic lands in that project.
- Access to the OpenRouter account or organization whose traffic you want to track. Editing an organization’s Broadcast settings requires an OpenRouter organization admin.
Setup
1
Get connection details from Terma
Open your project in the Terma dashboard and go to Connectors. Under Server keys, create a key for OpenRouter and give it a recognisable name, for example
OpenRouter.If you are setting up a new project, the project setup guide offers the same thing: choose Router or other tool and click Generate connection details.Note two values:- The OTLP endpoint shown on the page (for example
https://otel.terma.ai) - The key itself
2
Enable Broadcast in OpenRouter
In OpenRouter, open Settings → Observability and turn on Enable Broadcast.Find OpenTelemetry Collector in the destination list and click its edit icon.
3
Add Terma as the destination
Fill in the destination with the values from step 1. OpenRouter needs the full traces URL, so append Headers (optional) — a JSON object carrying your Terma server key:Click Test Connection. OpenRouter sends a small synthetic span to Terma and only saves the destination if Terma accepts it.
/v1/traces to the endpoint Terma showed you.Endpoint4
Make a request and verify
Send any request through OpenRouter with a key covered by the Broadcast settings you just edited. Within a minute, the call should appear in Terma:An
- Overview lists
openrouterunder Spend by source - Sessions shows the request as a session, with the model and provider that served it
openrouter row confirms traces are arriving.What Terma captures
Cost comes straight from OpenRouter’s own accounting, so it matches the drawdown on your OpenRouter balance rather than a Terma-side estimate.
Attributing calls to people and sessions
OpenRouter identifies each call by the API key that made it, and Terma uses that key as the principal for the call. The key’s name in OpenRouter is what you will see in Terma’s Team and People views. To get useful attribution:- Use one OpenRouter key per person or per service, named after them. A single shared key makes every call look like the same actor.
- Map keys to people in the Terma dashboard under Project Settings → Principal mapping. An organization admin can alias an OpenRouter key to the person who owns it, so their OpenRouter usage sits alongside their Claude Code or Codex activity.
session_id in the request body (or an x-session-id header). Every call sharing that value lands in the same session:
session_id, each request is its own session.
In
terma usage, OpenRouter traffic that is not mapped to a person shows as (no user id). Run terma usage --group-by api-key to see which key it came from, then map that key in Principal mapping.Privacy Mode
OpenRouter’s Broadcast settings include a Privacy Mode that strips prompts and completions from exported traces. With it enabled, Terma still receives model, provider, tokens, cost, and timing for every call, so spend tracking is unaffected. Session replay will show the call structure and usage but not the conversation text.Multiple OpenRouter accounts or organizations
Broadcast settings live on the OpenRouter account or organization, and each Terma server key belongs to one project. To send traffic from several OpenRouter organizations to Terma, configure Broadcast in each one. Point them at the same server key to land everything in one project, or create a key per project to keep them separate.Troubleshooting
- Test Connection fails. Check that the endpoint ends in
/v1/tracesand that the header value starts withBearerfollowed by the full key. A revoked key is rejected the same way; create a new one in Connectors. - The test passes but no sessions appear. Confirm the requests are being made with a key covered by the Broadcast settings you edited, and that the destination’s sampling rate is
1.0. Traces arrive asynchronously, so allow a minute after the request. - Everything shows as one person. The calls share an OpenRouter API key. Create per-person keys, or map the shared key in Principal mapping.
- Spend looks like an estimate. It is not. Costs for OpenRouter calls are the amounts OpenRouter reported for each request. Estimates marked
est.only appear for sources that do not report cost themselves.