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
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:
| Route | Window | Max Requests |
|---|---|---|
/events | 60 seconds | 60 |
/sessions | 60 seconds | 120 |
/analytics | 60 seconds | 120 |
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 Type | Behavior |
|---|---|
session_start | Creates a new session record. Requires session_id and agent_name. |
session_end | Marks a session as completed. Sets ended_at, status, and final token counts. |
| anything else | Stored as a regular event. Auto-creates the session if it doesn't exist. |
Event Fields
| Field | Type | Required | Description |
|---|---|---|---|
event_type | string | No | Defaults to "generic" |
session_id | string | No | Defaults to "unknown" |
event_id | string | No | Auto-generated UUID if not provided |
timestamp | string | No | ISO 8601. Defaults to current time |
model | string | No | LLM model name |
input_data | object | No | Input to the operation |
output_data | object | No | Output from the operation |
tokens_in | integer | No | Input token count |
tokens_out | integer | No | Output token count |
tool_call | object | No | Tool call details (name, input, output) |
decision_trace | object | No | Reasoning trace |
duration_ms | number | No | Execution 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 Param | Type | Default | Description |
|---|---|---|---|
limit | int | 50 | Max results (capped at 200) |
offset | int | 0 | Pagination offset |
status | string | â | 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 Param | Type | Default | Description |
|---|---|---|---|
format | string | "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
| Field | Type | Required | Description |
|---|---|---|---|
session_a | string | Yes | First session ID (baseline) |
session_b | string | Yes | Second 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"]
}
}
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
| Section | Description |
|---|---|
overview | Aggregate counts: sessions, events, tokens, error rate, date range |
duration | Session wall-clock duration stats (avg/min/max in milliseconds) |
top_agents | Top 10 agents by total token usage |
model_usage | Per-model breakdown: call count, tokens, average latency |
event_types | Count of events by type (excludes session_start/session_end) |
sessions_over_time | Daily session counts and token usage (last 90 days) |
hourly_activity | Event counts by hour of day (0â23) across all time |
Environment Variables
| Variable | Default | Description |
|---|---|---|
PORT | 3000 | HTTP server port |
AGENTLENS_API_KEY | none | API 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"}
| Status | Meaning |
|---|---|
400 | Bad request â invalid input, missing fields, or validation failure |
401 | Unauthorized â missing or invalid API key |
404 | Not found â session ID doesn't exist |
429 | Rate limited â too many requests |
500 | Internal server error |