AI Agent Telemetry (OpenTelemetry Setup)
Connect Claude Code, Cursor, Gemini CLI, Codex, and other AI coding agents to CodeDD via OpenTelemetry push
AI Agent Telemetry (OpenTelemetry Setup)
CodeDD can receive platform-assisted AI usage telemetry from coding agents that run on developer machines. This is separate from git-derived AI authorship (git-ai notes, co-author trailers, commit markers), which proves what was committed with evidence.
| Signal | What it measures | How it arrives |
|---|---|---|
| Git authorship | Lines and commits disclosed as AI-assisted in git history | Audit pipeline scans the repository |
| Platform-assisted telemetry | Sessions, tokens, lines written in the editor, cost, tool usage | Agents push OpenTelemetry (OTEL) to CodeDD, or CodeDD pulls vendor admin APIs |
Platform-assisted numbers are a floor, not a ceiling: they reflect only developers and machines that were configured. Treat them as adoption and activity signals, not proof of what landed in production.
How CodeDD implements OTEL ingest
Push model (this guide)
Most coding agents never expose a team-wide admin API. Their telemetry stays on the developer machine until you configure an exporter. CodeDD therefore issues an ingest endpoint per portfolio organization:
- An organization manager creates the endpoint in Organization Settings → AI agent telemetry (OpenTelemetry).
- CodeDD returns:
- OTLP base URL — e.g.
https://api.codedd.ai/api/otel - Ingest token — a bearer secret scoped to that organization
- OTLP base URL — e.g.
- You paste those values into each agent (or into a collector that forwards on the agent's behalf).
- Agents push OTLP/HTTP on a schedule (typically every 60 seconds).
- CodeDD decodes, normalizes vendor-specific metrics, and stores daily rollups in PostgreSQL (
AgentUsageDailywithingestion_source = otel_push).
Endpoints
| Path | Purpose |
|---|---|
POST /api/otel/v1/metrics | Primary signal — sessions, tokens, lines, cost |
POST /api/otel/v1/logs | Codex and other agents that report usage as log events |
POST /api/otel/v1/traces | Acknowledged and discarded (prevents exporter retry loops) |
Token-in-path variant (for agents that cannot set headers):
| Path | Purpose |
|---|---|
POST /api/otel/k/{token}/v1/metrics | Same as above; token embedded in URL |
POST /api/otel/k/{token}/v1/logs | Logs with path-embedded token |
Supported encodings
- OTLP/HTTP protobuf (
application/x-protobuf) — recommended; used by Claude Code and Cursor Enterprise - OTLP/HTTP JSON (
application/json) — required for Gemini CLI - Gzip request bodies — supported
What CodeDD stores
Daily aggregates per organization and provider:
- Sessions, engaged users (hashed identities — no emails stored)
- Input / output / cache tokens
- Lines added and removed (where the agent reports them)
- Cost (micro-USD, where reported)
- Tool and model breakdowns (bounded cardinality)
What CodeDD never stores
The normalizer reads allow-listed numeric attributes only. The following are structurally ignored even if an agent sends them:
- Prompt text and chat content
- File paths and repository contents
- Tool arguments and shell commands
- Raw user identifiers (hashed before persistence)
Important: Gemini CLI enables prompt logging by default upstream. Always set logPrompts: false in Gemini settings. Claude Code snippets disable log export explicitly.
Authentication
Three ways to send the ingest token:
- Authorization header (preferred):
Authorization: Bearer codedd_otel_… - Custom header:
X-CodeDD-Ingest-Token: codedd_otel_… - URL path (Gemini CLI):
/api/otel/k/{token}/v1/metrics
Only organization managers can create, reveal, rotate, or pause the ingest token.
Step 1 — Create the ingest endpoint in CodeDD
- Open your Portfolio Organization dashboard.
- Open Settings (gear icon).
- Scroll to AI agent telemetry (OpenTelemetry).
- Click Create telemetry endpoint.
- Copy the OTLP endpoint and ingest token (click Show to reveal the token).
- Choose a provider tab for a pre-filled setup snippet, or follow the sections below.
Status meanings:
| Badge | Meaning |
|---|---|
| Not set up | No endpoint created yet |
| Waiting for data | Endpoint exists but no push received yet — restart agents after configuring |
| Receiving | At least one batch accepted |
| Paused | Token kept but pushes rejected until resumed |
Full setup reference: use the in-app snippet generator and this page together.
Step 2 — Configure your agent or collector
Choose the path that matches your stack. An existing OpenTelemetry Collector is the highest-conversion route — one engineer adds an exporter; no developer machines need changing.
Existing OpenTelemetry Collector (recommended)
Who configures: One platform or observability engineer
Per-developer install: No
Best for: Teams that already run a collector and want to forward agent telemetry to CodeDD
Add an OTLP HTTP exporter to your collector configuration:
exporters:
otlphttp/codedd:
endpoint: https://api.codedd.ai/api/otel
headers:
Authorization: "Bearer YOUR_CODEDD_INGEST_TOKEN"
service:
pipelines:
metrics:
receivers: [otlp]
exporters: [otlphttp/codedd]
logs:
receivers: [otlp]
exporters: [otlphttp/codedd]
Replace the endpoint and token with the values from Organization Settings. If agents already export to your collector on localhost:4318, this is the only change required.
Local development: use http://localhost:8000/api/otel (Django direct) or http://localhost:3000/api/otel (via nginx in Docker Compose).
Claude Code
Who configures: IT / platform admin via MDM, or each developer once
Per-developer install: Yes, unless you distribute managed settings centrally
Protocol: OTLP/HTTP protobuf
Signals: Metrics only (logs disabled in CodeDD snippets)
Create managed settings on each developer machine (or push via MDM):
| OS | Path |
|---|---|
| macOS | /Library/Application Support/ClaudeCode/managed-settings.json |
| Linux | /etc/claude-code/managed-settings.json |
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "none",
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://api.codedd.ai/api/otel",
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer YOUR_CODEDD_INGEST_TOKEN",
"OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE": "delta",
"OTEL_METRIC_EXPORT_INTERVAL": "60000"
}
}
After saving: restart Claude Code. First data usually arrives within one export interval (~60 seconds).
Alternative — Anthropic admin API (pull): CodeDD can also poll Claude Code usage with an organization admin key (no per-developer OTEL). That path uses a separate credential connection and is distinct from OTEL push.
Cursor
Who configures: Cursor team admin (Enterprise) or each developer (community hooks)
Per-developer install: Depends on path (see below)
Cursor has two OTEL-compatible paths in CodeDD:
Path A — Cursor Enterprise native export (team-wide)
Available on Cursor Enterprise (OpenTelemetry Export beta). Cursor pushes from Cursor's servers, not from each IDE instance.
Requirements:
- Cursor Enterprise plan
- Public HTTPS endpoint reachable from the internet (Cursor egresses from fixed IPs;
localhostwill not work without a tunnel such as ngrok) - Organization manager has created the CodeDD ingest endpoint
Setup:
-
In Cursor Team Settings → OpenTelemetry Export, create a destination.
-
Set the base URL to your CodeDD OTLP base (no
/v1/...suffix — Cursor appends/v1/metricsand/v1/logsautomatically):https://api.codedd.ai/api/otel -
Add authorization header:
Authorization: Bearer YOUR_CODEDD_INGEST_TOKEN -
Run Test connection, then Enable.
Notes:
- Cursor sends OTLP/HTTP protobuf only (not JSON).
- Metrics are at-most-once; logs are at-least-once (dedupe on
cursor.event.idif you mirror elsewhere). - CodeDD stores sessions, tokens, and tool activity where Cursor's wire format maps to daily rollups.
Path B — Forward from your collector
If developers already send Cursor hook or agent telemetry to an internal collector, add the CodeDD exporter (see Existing collector above). No Cursor Team Settings change required.
Path C — Per-developer community hooks (local development)
For local CodeDD (localhost) or teams without Enterprise export, community tools (e.g. cursor-otel-hook, cursorscope) can capture IDE hook events and POST OTLP to CodeDD. Each developer installs and points exporters at:
http://localhost:8000/api/otel
with the ingest token in OTEL_EXPORTER_OTLP_HEADERS. This path is per machine and requires manual setup unless scripted.
Alternative — Cursor Team Admin API (pull): CodeDD can poll Cursor team daily usage with a team admin API key (one admin paste, whole team covered, no OTEL). That is a separate integration from OTEL push.
Gemini CLI
Who configures: Each developer, or once via a committed .gemini/settings.json in a shared repo
Per-developer install: Yes, unless the settings file is shared
Protocol: OTLP/HTTP JSON
Limitation: Cannot set authorization headers — token must travel in the URL path
Edit ~/.gemini/settings.json (or .gemini/settings.json in a repository):
{
"telemetry": {
"enabled": true,
"otlpEndpoint": "https://api.codedd.ai/api/otel/k/YOUR_CODEDD_INGEST_TOKEN",
"otlpProtocol": "http",
"logPrompts": false
}
}
Security: Treat the full URL as a secret because it embeds the token. Rotate the CodeDD token if the URL leaks into logs.
OpenAI Codex
Who configures: Each developer, or one system-wide file via MDM
Per-developer install: Yes, unless /etc/codex/config.toml is distributed
Protocol: OTLP/HTTP protobuf on logs endpoint
Coverage: Tokens, sessions, tool decisions — no line counts (Codex reports usage as log events, not metrics)
Edit ~/.codex/config.toml or /etc/codex/config.toml:
[otel]
environment = "production"
log_user_prompt = false
[otel.exporter.otlp-http]
endpoint = "https://api.codedd.ai/api/otel/v1/logs"
protocol = "binary"
headers = { "Authorization" = "Bearer YOUR_CODEDD_INGEST_TOKEN" }
Restart Codex after saving.
Other agents (OpenTelemetry GenAI conventions)
Agents that emit gen_ai.* metrics without a vendor-specific prefix are stored under Other (OpenTelemetry). Configure any OTLP/HTTP exporter to the CodeDD metrics endpoint with bearer authentication. If your agent supports only a collector, use the collector forwarding path.
Local development (Docker Compose)
When running CodeDD locally:
| Service | OTLP base URL |
|---|---|
| Django direct | http://localhost:8000/api/otel |
| Via nginx (frontend container) | http://localhost:3000/api/otel |
Create the ingest endpoint from Organization Settings the same way as production. Use the localhost URL in agent configuration.
Cursor Enterprise native export cannot target localhost — use a tunnel, a collector in the cloud, or per-developer hooks for local testing.
Operations
Rotate token
In Organization Settings → Rotate token. This immediately invalidates the old token. Every configured agent and collector must be updated. Rotation is explicit (not automatic on page reload) to avoid silently breaking production integrations.
Pause collection
Pause collection stops accepting pushes while keeping the token and historical data. Resume collection re-enables the same token without reconfiguring agents.
Rate limits
CodeDD applies a per-organization rate limit (default 6,000 requests/minute). Exceeding it returns HTTP 429; OTLP exporters should back off. The OTLP path is exempt from IP-based DDoS throttling because entire teams share office egress IPs.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Status stays Waiting for data | Agent not restarted after config | Restart the agent; wait one export interval |
| HTTP 401 Unauthorized | Wrong, rotated, or paused token | Reveal token in settings; check pause state |
| HTTP 400 Bad Request | Malformed OTLP body or wrong content type | Use protobuf for Claude/Cursor; JSON for Gemini |
| HTTP 413 Payload too large | Batch exceeds 2 MB | Reduce batch size in exporter |
| Gemini works but Claude does not | Wrong protocol | Claude requires http/protobuf, not JSON |
| Cursor Enterprise test fails | localhost or missing HTTPS | Use public URL or ngrok tunnel |
| Data appears but line counts are zero | Expected for Codex | Codex reports tokens/sessions via logs only |
| Double counts after collector change | Same agent sent twice | One path per agent (direct OR collector, not both) |
Privacy and security summary
- Ingest tokens grant write access to organization usage data — manager-only management.
- Tokens are encrypted at rest; lookup uses a SHA-256 hash of the plaintext.
- Developer identities are salted and hashed; emails are not persisted.
- Prompt and source content are never read by the ingest pipeline.
- OTEL push data is labeled
OpenTelemetry pushin the UI, separate fromVendor admin APIpull data for the same provider.

