REST API Reference

HTTP endpoints for ingesting events and querying sessions.

The AgentLens backend exposes a RESTful API on http://localhost:3000 (configurable via PORT env var). All request/response bodies use JSON.

Authentication

Pass your API key in the X-API-Key header:

curl -H "X-API-Key: your-key" http://localhost:3000/sessions
â„šī¸ Dev Mode

If the AGENTLENS_API_KEY environment variable is not set, the backend runs in dev mode — no authentication is required. When the variable is set, the key is validated on every request to /events, /sessions, and /analytics.

Rate Limiting

The backend enforces per-IP rate limits to prevent abuse:

RouteWindowMax Requests
/events60 seconds60
/sessions60 seconds120
/analytics60 seconds120

Rate limit headers (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) are included in all responses.

Endpoints

GET /health

Health check endpoint.

curl http://localhost:3000/health

Response:

{
  "status": "ok",
  "timestamp": "2026-02-14T10:30:00.000Z"
}

POST /events

Ingest a batch of events. This is the primary endpoint used by the SDK.

curl -X POST http://localhost:3000/events \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "event_type": "session_start",
        "session_id": "abc123",
        "agent_name": "my-agent",
        "metadata": {"version": "1.0"},
        "timestamp": "2026-02-14T10:30:00Z"
      },
      {
        "event_type": "llm_call",
        "session_id": "abc123",
        "event_id": "evt001",
        "model": "gpt-4",
        "input_data": {"prompt": "Hello"},
        "output_data": {"response": "Hi"},
        "tokens_in": 5,
        "tokens_out": 3,
        "duration_ms": 150.0,
        "decision_trace": {
          "reasoning": "Simple greeting"
        }
      }
    ]
  }'

Response:

{"status": "ok", "processed": 2}

Special Event Types

Event TypeBehavior
session_startCreates a new session record. Requires session_id and agent_name.
session_endMarks a session as completed. Sets ended_at, status, and final token counts.
anything elseStored as a regular event. Auto-creates the session if it doesn't exist.

Event Fields

FieldTypeRequiredDescription
event_typestringNoDefaults to "generic"
session_idstringNoDefaults to "unknown"
event_idstringNoAuto-generated UUID if not provided
timestampstringNoISO 8601. Defaults to current time
modelstringNoLLM model name
input_dataobjectNoInput to the operation
output_dataobjectNoOutput from the operation
tokens_inintegerNoInput token count
tokens_outintegerNoOutput token count
tool_callobjectNoTool call details (name, input, output)
decision_traceobjectNoReasoning trace
duration_msnumberNoExecution time in ms

GET /sessions

List all sessions with pagination and optional status filter.

curl "http://localhost:3000/sessions?limit=10&offset=0&status=active"
Query ParamTypeDefaultDescription
limitint50Max results (capped at 200)
offsetint0Pagination offset
statusstring—Filter: active, completed, error

Response:

{
  "sessions": [
    {
      "session_id": "abc123",
      "agent_name": "research-agent",
      "started_at": "2026-02-14T10:30:00Z",
      "ended_at": "2026-02-14T10:31:00Z",
      "metadata": {"version": "2.0"},
      "total_tokens_in": 1200,
      "total_tokens_out": 350,
      "status": "completed"
    }
  ],
  "total": 42
}

GET /sessions/:id

Get a single session with its full event trace.

curl http://localhost:3000/sessions/abc123

Response: Same as session list item, plus an events array with all parsed events (JSON fields like input_data, tool_call, decision_trace are returned as objects, not strings).

GET /sessions/:id/explain

Get a human-readable explanation of the session's agent behavior.

curl http://localhost:3000/sessions/abc123/explain

Response:

{
  "session_id": "abc123",
  "explanation": "## Agent Session: research-agent\n**Duration:** 45.2s\n..."
}

The explanation is a Markdown-formatted string with a timeline of events, token counts, and reasoning. See the Explainability page for details on how explanations are generated.

GET /sessions/:id/export

Export a session's full data as JSON or CSV. Useful for offline analysis, archival, or feeding into other tools.

# JSON export (default)
curl "http://localhost:3000/sessions/abc123/export?format=json" \
  -H "X-API-Key: your-key"

# CSV export
curl "http://localhost:3000/sessions/abc123/export?format=csv" \
  -H "X-API-Key: your-key" -o session.csv
Query ParamTypeDefaultDescription
formatstring"json""json" or "csv"

JSON Response:

{
  "exported_at": "2026-02-18T10:30:00.000Z",
  "session": {
    "session_id": "abc123",
    "agent_name": "research-agent",
    "status": "completed",
    "started_at": "2026-02-14T10:30:00Z",
    "ended_at": "2026-02-14T10:31:00Z",
    "total_tokens_in": 1200,
    "total_tokens_out": 350,
    "metadata": {"version": "2.0"}
  },
  "events": [
    {
      "event_id": "evt001",
      "event_type": "llm_call",
      "timestamp": "2026-02-14T10:30:05Z",
      "model": "gpt-4",
      "tokens_in": 50,
      "tokens_out": 30,
      "duration_ms": 150,
      "input_data": {"prompt": "..."},
      "output_data": {"response": "..."},
      "tool_call": null,
      "decision_trace": null
    }
  ],
  "summary": {
    "total_events": 8,
    "total_tokens": 1550,
    "models_used": ["gpt-4"],
    "event_types": ["llm_call", "tool_call", "decision"],
    "total_duration_ms": 4250.5
  }
}

CSV Response: The CSV export includes columns for event_id, event_type, timestamp, model, tokens_in, tokens_out, duration_ms, input_data, output_data, tool_name, tool_input, tool_output, and reasoning. The response includes a Content-Disposition header for automatic file download.

POST /sessions/compare

Compare two sessions side-by-side, calculating deltas for token usage, event counts, timing, and tool usage. Useful for A/B testing prompts, models, or agent configurations.

curl -X POST http://localhost:3000/sessions/compare \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-key" \
  -d '{"session_a": "abc123", "session_b": "def456"}'

Request Body

FieldTypeRequiredDescription
session_astringYesFirst session ID (baseline)
session_bstringYesSecond session ID (compared against baseline)

Response:

{
  "compared_at": "2026-02-18T10:30:00.000Z",
  "session_a": {
    "session_id": "abc123",
    "agent_name": "research-agent",
    "status": "completed",
    "tokens_in": 1200,
    "tokens_out": 350,
    "total_tokens": 1550,
    "event_count": 8,
    "error_count": 0,
    "total_processing_ms": 4250.5,
    "avg_event_duration_ms": 531.31,
    "session_duration_ms": 60000,
    "models": {
      "gpt-4": {"calls": 5, "tokens_in": 1000, "tokens_out": 300}
    },
    "event_types": {"llm_call": 5, "tool_call": 3},
    "tools": {
      "web_search": {"calls": 2, "total_duration": 800},
      "calculator": {"calls": 1, "total_duration": 50}
    },
    "metadata": {}
  },
  "session_b": { ... },
  "deltas": {
    "total_tokens": {"absolute": -200, "percent": -12.9},
    "tokens_in": {"absolute": -150, "percent": -12.5},
    "tokens_out": {"absolute": -50, "percent": -14.29},
    "event_count": {"absolute": -2, "percent": -25},
    "error_count": {"absolute": 0, "percent": 0},
    "total_processing_ms": {"absolute": -1000.5, "percent": -23.54},
    "avg_event_duration_ms": {"absolute": 10.2, "percent": 1.92}
  },
  "shared": {
    "event_types": ["llm_call", "tool_call", "decision"],
    "tools": ["web_search", "calculator"],
    "models": ["gpt-4"]
  }
}
📊 Delta Interpretation

Deltas are computed as B relative to A. Negative values mean session B used fewer resources. The percent field shows the percentage change: ((B - A) / A) × 100.

GET /analytics

Get aggregate statistics across all sessions — overview metrics, model usage, top agents, event type breakdowns, time-series data, and hourly activity patterns.

curl http://localhost:3000/analytics \
  -H "X-API-Key: your-key"

Response:

{
  "overview": {
    "total_sessions": 42,
    "active_sessions": 2,
    "completed_sessions": 38,
    "error_sessions": 2,
    "error_rate": 4.76,
    "total_events": 1250,
    "total_tokens": 95000,
    "total_tokens_in": 72000,
    "total_tokens_out": 23000,
    "avg_tokens_per_session": 2262,
    "earliest_session": "2026-01-15T08:00:00Z",
    "latest_session": "2026-02-18T10:30:00Z"
  },
  "duration": {
    "avg_ms": 45200,
    "min_ms": 1200,
    "max_ms": 320000
  },
  "top_agents": [
    {
      "agent_name": "research-agent",
      "session_count": 20,
      "total_tokens": 50000,
      "avg_tokens": 2500
    }
  ],
  "model_usage": [
    {
      "model": "gpt-4",
      "call_count": 800,
      "total_tokens": 60000,
      "total_tokens_in": 45000,
      "total_tokens_out": 15000,
      "avg_duration_ms": 250.5
    }
  ],
  "event_types": [
    {"event_type": "llm_call", "count": 600},
    {"event_type": "tool_call", "count": 400},
    {"event_type": "decision", "count": 250}
  ],
  "sessions_over_time": [
    {"day": "2026-02-17", "session_count": 5, "total_tokens": 12000},
    {"day": "2026-02-18", "session_count": 3, "total_tokens": 8000}
  ],
  "hourly_activity": [
    {"hour": 9, "event_count": 150},
    {"hour": 10, "event_count": 200},
    {"hour": 14, "event_count": 180}
  ]
}

Response Fields

SectionDescription
overviewAggregate counts: sessions, events, tokens, error rate, date range
durationSession wall-clock duration stats (avg/min/max in milliseconds)
top_agentsTop 10 agents by total token usage
model_usagePer-model breakdown: call count, tokens, average latency
event_typesCount of events by type (excludes session_start/session_end)
sessions_over_timeDaily session counts and token usage (last 90 days)
hourly_activityEvent counts by hour of day (0–23) across all time

Environment Variables

VariableDefaultDescription
PORT3000HTTP server port
AGENTLENS_API_KEYnoneAPI key for authentication. When unset, auth is disabled (dev mode)
CORS_ORIGINS*Comma-separated allowed origins (e.g. http://localhost:3000,https://app.example.com)

Error Responses

All error responses follow a consistent format:

{"error": "Description of what went wrong"}
StatusMeaning
400Bad request — invalid input, missing fields, or validation failure
401Unauthorized — missing or invalid API key
404Not found — session ID doesn't exist
429Rate limited — too many requests
500Internal server error