Coding Agent Tracking

Track prompts, token usage, costs, and conversations from Claude Code, Cursor, Aider, Cline, and any other LLM-powered coding agent.

Managing the gateway from an agent?

Agents can also connect to Ingate over MCP, one URL, per-agent install snippets, and zero-credential onboarding. See MCP Server. The proxy setup below is the right approach if you just want usage tracking without giving your agent gateway-management tools.

How it works

Ingate sits between your coding agent and the LLM provider. Every request passes through, gets logged with full request/response capture, and is forwarded to the real API: logs, costs, usage, and sessions are all captured. The agent sees no difference: same API, same responses, same streaming.

Provider auth modes

Add provider configs to ingate.yaml. There are two modes depending on how your tools authenticate.

Mode A: API key (Ingate manages keys)

Ingate holds the real API keys. Tools authenticate to Ingate, and Ingate injects the real provider key when forwarding upstream.

yamlingate.yaml
providers:
  anthropic:
    base_url: https://api.anthropic.com
    api_key: sk-ant-your-real-key     # Ingate injects this
    enabled: true
  openai:
    base_url: https://api.openai.com
    api_key: sk-your-real-key
    enabled: true

Mode B: Auth passthrough (for subscriptions)

For tools that authenticate with their own credentials (e.g., Claude Code with a Pro/Max subscription, or Cursor with its own API key), use auth_passthrough: true. Ingate forwards the client's auth headers to the provider as-is, no key injection, just observation and logging.

yamlingate.yaml
providers:
  anthropic:
    base_url: https://api.anthropic.com
    auth_passthrough: true              # Don't inject auth, forward client's OAuth token
    enabled: true
    default: true
  openai:
    base_url: https://api.openai.com
    auth_passthrough: true
    enabled: true

When to use which

ScenarioMode
Team sharing a single Anthropic API keyAPI key, one key on the server, devs get Ingate keys
Individual developer with Claude Pro/MaxAuth passthrough, Claude Code's OAuth token passes through
Individual developer with their own API keyEither mode works
Cursor with built-in subscriptionAuth passthrough

Every request through the proxy authenticates with X-Ingate-Key (your Ingate API key). When a tool only exposes a base URL and API key setting, the Ingate key goes in the API key field, as in the per-tool setups below.

Claude Code

Claude Code uses the Anthropic SDK, which respects ANTHROPIC_BASE_URL.

With a subscription (Pro/Max)

If you're using Claude Code with a Claude subscription (not an API key), use auth passthrough mode. Claude Code authenticates via OAuth. Ingate just forwards the token and logs everything.

yamlingate.yaml
providers:
  anthropic:
    base_url: https://api.anthropic.com
    auth_passthrough: true    # Forward Claude Code's OAuth token
    enabled: true
    default: true
bash
export ANTHROPIC_BASE_URL=http://localhost:7100
# No ANTHROPIC_API_KEY needed, Claude Code uses its own OAuth token

Claude Code authenticates normally (browser OAuth), sends POST /v1/messages to Ingate, Ingate auto-detects "anthropic", forwards the request with the OAuth token intact, logs everything, and returns the response.

With an API key

If you have an Anthropic API key (not a subscription), Ingate holds the key and injects it:

yamlingate.yaml
providers:
  anthropic:
    base_url: https://api.anthropic.com
    api_key: sk-ant-your-real-key
    enabled: true
    default: true
bash
export ANTHROPIC_BASE_URL=http://localhost:7100
export ANTHROPIC_API_KEY=igt_your_ingate_key   # Ingate key, not Anthropic key

Cursor

Cursor supports custom API endpoints in its settings:

  • Open Cursor Settings → Models
  • Set API Base URL to http://localhost:7100
  • Set the API key to your Ingate key

Or via environment:

bash
export OPENAI_BASE_URL=http://localhost:7100   # For OpenAI models
export ANTHROPIC_BASE_URL=http://localhost:7100 # For Claude models

Aider

Aider supports custom base URLs via environment variables:

bash
# For Anthropic models
export ANTHROPIC_BASE_URL=http://localhost:7100
export ANTHROPIC_API_KEY=igt_your_ingate_key

# For OpenAI models
export OPENAI_API_BASE=http://localhost:7100
export OPENAI_API_KEY=igt_your_ingate_key

Cline (VS Code)

In Cline's settings, configure:

  • API Provider: Anthropic (or OpenAI)
  • Base URL: http://localhost:7100
  • API Key: your Ingate key

How routing works

Ingate automatically detects the provider from the request path, no X-Ingate-Provider header needed:

Path patternAuto-detected provider
/v1/messagesanthropic
/v1/chat/completionsopenai
/v1/completionsopenai
/v1/embeddingsopenai
/v1/modelsopenai
/v1/responsesopenai
/api/generateollama
/api/chatollama

For any path not in this table, you can configure a fallback by marking a provider default: true.

Priority chain

Explicit X-Ingate-Provider header → path auto-detection → the provider marked default: true in config.

What gets tracked

Once routed through Ingate, every request is captured:

DataWhere to see
Full request/response bodiesDashboard → Logs (/ui/#/logs)
Token counts (input/output)Dashboard → Usage (/ui/#/usage)
Latency per requestLog detail view
Cost estimatesDashboard → Usage breakdown
Model usedLogs filter by model
ProviderLogs filter by provider
Session timelinesDashboard → Sessions (/ui/#/sessions)
User breakdownDashboard → User Analytics (/ui/#/user-analytics)

Session tracking

To group requests into conversations, add the optional tracking headers X-Ingate-User-Id (who is making the request) and X-Ingate-Session-Id (which conversation/session this belongs to). Then view conversation timelines at /ui/#/sessions.

Usage analytics

Query usage by user or session:

bash
# Who's using the most tokens?
curl http://localhost:7100/api/v1/usage/breakdown?group_by=user \
  -H "Authorization: Bearer $TOKEN"

# What sessions are active?
curl http://localhost:7100/api/v1/sessions \
  -H "Authorization: Bearer $TOKEN"

# Timeline of a specific session
curl http://localhost:7100/api/v1/sessions/SESSION_ID/timeline \
  -H "Authorization: Bearer $TOKEN"

Team setup

For a team of developers, each developer gets their own Ingate API key:

bash
# Admin creates keys for each developer
# Each developer sets their personal key in their shell profile

# Developer 1
export ANTHROPIC_BASE_URL=http://ingate.internal:7100
export ANTHROPIC_API_KEY=igt_dev1_key

# Developer 2
export ANTHROPIC_BASE_URL=http://ingate.internal:7100
export ANTHROPIC_API_KEY=igt_dev2_key

Benefits:

  • Centralized API key management (real keys never leave the server)
  • Per-developer usage tracking and cost attribution
  • Budget enforcement per org/user
  • Audit trail of all LLM interactions
  • No need to distribute provider API keys to individual machines

Alternative: post-hoc ingestion

If you can't proxy (e.g., the tool doesn't support custom base URLs), use the Ingestion API to send logs after the fact:

bash
curl -X POST http://localhost:7100/api/v1/ingest \
  -H "X-Ingate-Key: igt_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "anthropic",
    "model": "claude-sonnet-4-20250514",
    "request": {
      "body": "{\"model\":\"claude-sonnet-4-20250514\",\"messages\":[{\"role\":\"user\",\"content\":\"explain this code\"}]}"
    },
    "response": {
      "status_code": 200,
      "body": "{\"content\":[{\"text\":\"This code...\"}],\"usage\":{\"input_tokens\":50,\"output_tokens\":200}}"
    },
    "latency_ms": 1500,
    "tags": {
      "user_id": "dev@company.com",
      "session_id": "coding-session-42",
      "tool": "claude-code"
    }
  }'

Alternative: OpenTelemetry

If your tool emits OpenTelemetry traces (or you instrument it), send traces to Ingate's OTLP receiver: Ingate accepts OTLP/HTTP at POST /v1/traces:

bash
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:7100

Ingate extracts gen_ai.* span attributes (model, tokens, provider) and maps them to log entries automatically. See OpenTelemetry for details.