Quick Start
Authentication
All requests require a Factory API key in theAuthorization header:
Permissions
Only users with Manager or Owner roles can access the Analytics API. Members and guests will receive a403 error.
Base URL
Response Format
All responses follow a consistent envelope structure:| Field | Type | Description |
|---|---|---|
data | array | Array of result objects (one per day, or per group when using group_by) |
meta | object | Request metadata: org_id, start_date, end_date, and pagination info for /users |
Endpoints
The Analytics API provides five endpoints, each focused on a specific category of metrics:| Endpoint | Description |
|---|---|
/tokens | Token consumption by model and user |
/tools | Tool invocations and autonomy metrics |
/activity | Daily, weekly, and monthly active users |
/productivity | File operations and git activity |
/users | Per-user metrics with pagination |
Understanding group_by
Several endpoints support a group_by parameter. Here’s how it works:
-
Without
group_by: Returns one row per day with nested breakdowns (e.g.,by_model,by_tool,daily_active_users_by_client). Use this when you want all dimensions in a single response. -
With
group_by: Flattens one of those nested arrays into separate rows. Each row has agroup_keyfield identifying the dimension value. Use this when piping data into tools that expect flat rows (spreadsheets, BI tools, time-series databases).
/activity without group_by returns daily_active_users_by_client as an object. With group_by=client, you get separate rows for terminal-ui, web, and non-interactive-cli - useful for plotting each client type as its own line on a chart.
Token Usage
Returns daily token consumption across your organization.Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
startDate | string | Yes | Start date in YYYY-MM-DD format |
endDate | string | Yes | End date in YYYY-MM-DD format |
group_by | string | No | Set to model to group results by model |
Response
Response Fields
| Field | Type | Description |
|---|---|---|
date | string | Date in YYYY-MM-DD format |
billable_tokens | number | Total billable tokens (input + output, with cache discounts) |
input_tokens | number | Raw input tokens sent to model |
output_tokens | number | Tokens generated by model |
cache_read_tokens | number | Tokens read from prompt cache |
cache_write_tokens | number | Tokens written to prompt cache |
by_model | array | Breakdown per model |
by_user | array | Breakdown per user |
Grouped Response
Whengroup_by=model, returns one row per model per day inside data:
Example
Tool Usage
Returns daily tool invocations, MCP usage, skills, slash commands, and autonomy metrics.Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
startDate | string | Yes | Start date in YYYY-MM-DD format |
endDate | string | Yes | End date in YYYY-MM-DD format |
group_by | string | No | Set to tool_name to group results by tool |
Response
Response Fields
| Field | Type | Description |
|---|---|---|
date | string | Date in YYYY-MM-DD format |
tool_calls | number | Total tool invocations |
by_tool | array | Breakdown by tool name |
mcp_users_with_mcp | number | Users who used MCP servers |
mcp_by_server | array | Invocations per MCP server |
skills_invocations | number | Total skill activations |
skills_by_name | array | Breakdown by skill |
slash_commands_invocations | number | Total slash command uses |
slash_commands_by_name | array | Breakdown by command |
hooks_invocations | number | Total hook executions |
hooks_by_event | array | Breakdown by event type |
web_users | number | Users who used web/workspace interface |
autonomy_ratio_avg | number | Average tool calls per user turn |
autonomy_ratio_p50 | number | Median autonomy ratio |
autonomy_ratio_p90 | number | 90th percentile autonomy ratio |
tool_calls_per_session_avg | number | Average tool calls per session |
user_turns_per_session_avg | number | Average user messages per session |
tool_autonomy_level_ratio | object | Distribution of autonomy levels |
Grouped Response
Whengroup_by=tool_name, returns one row per tool per day inside data:
User Activity
Returns daily, weekly, and monthly active users along with session counts.Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
startDate | string | Yes | Start date in YYYY-MM-DD format |
endDate | string | Yes | End date in YYYY-MM-DD format |
group_by | string | No | Set to client to group by client type |
Response
Response Fields
| Field | Type | Description |
|---|---|---|
date | string | Date in YYYY-MM-DD format |
daily_active_users | number | Unique users on this day |
weekly_active_users | number | Unique users in trailing 7 days |
monthly_active_users | number | Unique users in trailing 30 days |
daily_active_users_by_client | object | DAU breakdown by client type |
sessions | number | Total sessions started |
messages | number | Total messages (user + assistant) |
user_messages | number | Messages from users only |
Client Types
| Client | Description |
|---|---|
terminal-ui | Interactive CLI sessions |
web | Factory web interface |
non-interactive-cli | Headless/automated CLI (droid exec) |
Grouped Response
Whengroup_by=client, returns one row per client type per day inside data:
Productivity
Returns daily file operations and git activity.Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
startDate | string | Yes | Start date in YYYY-MM-DD format |
endDate | string | Yes | End date in YYYY-MM-DD format |
Response
Response Fields
| Field | Type | Description |
|---|---|---|
date | string | Date in YYYY-MM-DD format |
files_created | number | New files created by agent |
files_edited | number | Existing files modified by agent |
by_extension | array | Operations per file extension |
by_language | array | Operations per programming language |
git_commits | number | Commits made via agent |
git_prs_created | number | Pull requests created via agent |
Per-User Metrics
Returns detailed metrics per user with cursor-based pagination.Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
startDate | string | Yes | Start date in YYYY-MM-DD format |
endDate | string | Yes | End date in YYYY-MM-DD format |
limit | number | No | Users per page, 1-100 (default: 20) |
cursor | string | No | User ID for pagination (from next_cursor) |
Response
Response Fields
| Field | Type | Description |
|---|---|---|
user_id | string | Unique user identifier |
user_email | string | null | User email |
date | string | Date in YYYY-MM-DD format |
tool_calls | number | Tool invocations by this user |
billable_tokens | number | Tokens consumed by this user |
primary_model | string | Most-used model |
primary_model_tier | string | Model tier (standard or thinking) |
files_created | number | Files created |
files_edited | number | Files edited |
git_commits | number | Commits made |
git_prs_created | number | Pull requests created |
mcp_calls | number | MCP tool invocations |
skill_calls | number | Skill activations |
slash_commands | number | Slash command uses |
hooks | number | Hook executions |
sessions | number | Sessions started |
messages | number | Total messages |
user_messages | number | User messages only |
assistant_messages | number | Assistant messages |
autonomy_ratio | number | Tool calls per user turn |
delegation_level | string | Primary autonomy mode |
languages | array | Programming languages worked in |
Delegation Levels
| Level | Description |
|---|---|
auto-high | Maximum autonomy, minimal confirmations |
auto-medium | Balanced autonomy with some confirmations |
auto-low | Limited autonomy, frequent confirmations |
spec | Specification mode, planning before execution |
manual | Full manual control, confirm each action |
Pagination
Use cursor-based pagination to iterate through users:Important Constraints
Date Requirements
- Format: All dates must be
YYYY-MM-DD - Timezone: UTC only (no timezone parameter)
- Data availability: Data is available through yesterday (UTC). Requesting today’s date returns a
400error. - Historical data: Available from January 14, 2026
Rate Limits
Rate limits vary by plan. Contact us for specifics or if you need higher limits for dashboard or automation use cases.Error Handling
The API returns standard HTTP status codes:| Status | Description |
|---|---|
400 | Invalid date format, today’s date requested, or limit out of range |
401 | Missing or invalid API key |
403 | Insufficient permissions (requires Manager or Owner role) |
500 | Internal error |
Error Response Format
Data Pipeline
Analytics data flows through the following pipeline:- Source: OpenTelemetry spans from the CLI and daemon
- Processing: Daily batch aggregation via dbt
- Availability: Data is available the day after it’s generated
Data Quality Notes
A few known data quality considerations:
- MCP server names: Some duplicates exist due to case sensitivity (e.g.,
axiomvsAxiom) - Tool names: Approximately 0.006% of entries contain parsing artifacts
- User counts: A user active on multiple clients counts once in DAU but appears in each client breakdown
