Worker Endpoints
The Cloudflare Worker acts as a secure proxy between the dashboard and Supabase. All requests require authentication.
Base URL
https://claude-telemetry.<your-subdomain>.workers.devOr your custom domain if configured.
Authentication
All endpoints (except POST /api/auth) require a valid session token in the Authorization header:
Authorization: Bearer <session-token>The session token is obtained via the auth endpoint.
Endpoints
POST /api/auth
Initiate magic link authentication.
Request:
{
"email": "user@example.com"
}Response (200):
{
"message": "Magic link sent to user@example.com"
}Response (403):
{
"error": "Email not in whitelist"
}GET /api/usage/daily
Get daily usage aggregates.
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
from | ISO date | No | Start date (default: 30 days ago) |
to | ISO date | No | End date (default: today) |
machine_id | UUID | No | Filter by machine |
model | string | No | Filter by model |
Response (200):
{
"data": [
{
"date": "2025-04-04",
"input_tokens": 45000,
"output_tokens": 120000,
"cache_read_tokens": 8000,
"cache_write_tokens": 3000,
"cost_usd": 2.34,
"session_count": 15,
"machines": ["work-laptop", "home-desktop"]
}
]
}GET /api/usage/sessions
Get individual session data.
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
from | ISO datetime | No | Start timestamp |
to | ISO datetime | No | End timestamp |
machine_id | UUID | No | Filter by machine |
model | string | No | Filter by model |
project | string | No | Filter by project path |
limit | integer | No | Max results (default: 100) |
offset | integer | No | Pagination offset |
Response (200):
{
"data": [
{
"id": "a1b2c3d4-...",
"machine_id": "e5f6g7h8-...",
"machine_name": "work-laptop",
"session_id": "session-abc123",
"timestamp": "2025-04-04T14:30:00Z",
"model": "opus-4",
"input_tokens": 3200,
"output_tokens": 8500,
"cost_usd": 0.42,
"project_path": "/home/user/my-project",
"duration_seconds": 180
}
],
"total": 342,
"limit": 100,
"offset": 0
}GET /api/machines
List all registered machines.
Response (200):
{
"data": [
{
"machine_id": "a1b2c3d4-...",
"machine_name": "work-laptop",
"last_sync": "2025-04-04T12:00:00Z",
"total_sessions": 450,
"total_cost_usd": 34.56
},
{
"machine_id": "e5f6g7h8-...",
"machine_name": "home-desktop",
"last_sync": "2025-04-04T11:45:00Z",
"total_sessions": 280,
"total_cost_usd": 22.10
}
]
}POST /api/agent/sync
Agent sync endpoint. Used by the Python agent to push new session data.
Authentication: Uses the agent's Supabase API key, not a user session token.
Request:
{
"machine_id": "a1b2c3d4-...",
"machine_name": "work-laptop",
"sessions": [
{
"session_id": "session-abc123",
"timestamp": "2025-04-04T14:30:00Z",
"model": "opus-4",
"input_tokens": 3200,
"output_tokens": 8500,
"cache_read_tokens": 500,
"cache_write_tokens": 200,
"cost_usd": 0.42,
"project_path": "/home/user/my-project",
"duration_seconds": 180
}
]
}Response (200):
{
"synced": 1,
"duplicates_skipped": 0
}Response (401):
{
"error": "Invalid API key"
}Error Format
All error responses follow the same format:
{
"error": "Human-readable error message",
"code": "ERROR_CODE"
}| Code | HTTP Status | Description |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid auth token |
FORBIDDEN | 403 | Email not in whitelist |
NOT_FOUND | 404 | Resource not found |
RATE_LIMITED | 429 | Too many requests |
INTERNAL_ERROR | 500 | Server error |