DocumentationPortfolio AnalyticsAI Agent Telemetry (OpenTelemetry Setup)

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.

SignalWhat it measuresHow it arrives
Git authorshipLines and commits disclosed as AI-assisted in git historyAudit pipeline scans the repository
Platform-assisted telemetrySessions, tokens, lines written in the editor, cost, tool usageAgents 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:

  1. An organization manager creates the endpoint in Organization Settings → AI agent telemetry (OpenTelemetry).
  2. CodeDD returns:
    • OTLP base URL — e.g. https://api.codedd.ai/api/otel
    • Ingest token — a bearer secret scoped to that organization
  3. You paste those values into each agent (or into a collector that forwards on the agent's behalf).
  4. Agents push OTLP/HTTP on a schedule (typically every 60 seconds).
  5. CodeDD decodes, normalizes vendor-specific metrics, and stores daily rollups in PostgreSQL (AgentUsageDaily with ingestion_source = otel_push).

Endpoints

PathPurpose
POST /api/otel/v1/metricsPrimary signal — sessions, tokens, lines, cost
POST /api/otel/v1/logsCodex and other agents that report usage as log events
POST /api/otel/v1/tracesAcknowledged and discarded (prevents exporter retry loops)

Token-in-path variant (for agents that cannot set headers):

PathPurpose
POST /api/otel/k/{token}/v1/metricsSame as above; token embedded in URL
POST /api/otel/k/{token}/v1/logsLogs 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:

  1. Authorization header (preferred): Authorization: Bearer codedd_otel_…
  2. Custom header: X-CodeDD-Ingest-Token: codedd_otel_…
  3. 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

  1. Open your Portfolio Organization dashboard.
  2. Open Settings (gear icon).
  3. Scroll to AI agent telemetry (OpenTelemetry).
  4. Click Create telemetry endpoint.
  5. Copy the OTLP endpoint and ingest token (click Show to reveal the token).
  6. Choose a provider tab for a pre-filled setup snippet, or follow the sections below.

Status meanings:

BadgeMeaning
Not set upNo endpoint created yet
Waiting for dataEndpoint exists but no push received yet — restart agents after configuring
ReceivingAt least one batch accepted
PausedToken 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):

OSPath
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; localhost will not work without a tunnel such as ngrok)
  • Organization manager has created the CodeDD ingest endpoint

Setup:

  1. In Cursor Team Settings → OpenTelemetry Export, create a destination.

  2. Set the base URL to your CodeDD OTLP base (no /v1/... suffix — Cursor appends /v1/metrics and /v1/logs automatically):

    https://api.codedd.ai/api/otel
    
  3. Add authorization header:

    Authorization: Bearer YOUR_CODEDD_INGEST_TOKEN
    
  4. 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.id if 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:

ServiceOTLP base URL
Django directhttp://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

SymptomLikely causeFix
Status stays Waiting for dataAgent not restarted after configRestart the agent; wait one export interval
HTTP 401 UnauthorizedWrong, rotated, or paused tokenReveal token in settings; check pause state
HTTP 400 Bad RequestMalformed OTLP body or wrong content typeUse protobuf for Claude/Cursor; JSON for Gemini
HTTP 413 Payload too largeBatch exceeds 2 MBReduce batch size in exporter
Gemini works but Claude does notWrong protocolClaude requires http/protobuf, not JSON
Cursor Enterprise test failslocalhost or missing HTTPSUse public URL or ngrok tunnel
Data appears but line counts are zeroExpected for CodexCodex reports tokens/sessions via logs only
Double counts after collector changeSame agent sent twiceOne 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 push in the UI, separate from Vendor admin API pull data for the same provider.

Related documentation