Factory Analytics API

REST API for organization-level usage, Factory Standard Credits consumption, tool usage, and productivity metrics.

The Factory Analytics API returns organization-level usage data for Factory. Query Factory Standard Credits consumption, tool invocations, user activity, and productivity metrics across your organization.

Authentication

All requests require a Factory API key in the Authorization header.

Authorization header
Authorization: Bearer fk-your-api-key

Generate API keys in the Factory API keys settings.

Permissions

Only members with the Manager or Owner role can access the Analytics API. Members with the User role receive a 403 error.

Base URL

Base URL
https://api.factory.ai/api/v1/analytics

Response format

All responses follow a consistent envelope structure:

JSON
{
  "data": [ ... ],
  "meta": { ... }
}
FieldTypeDescription
dataarrayArray of result objects (one per day, or per group when using group_by)
metaobjectRequest 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:

EndpointDescription
/tokensFactory Standard Credits consumption by model and user
/toolsTool invocations and autonomy metrics
/activityDaily, weekly, and monthly active users
/productivityFile operations and git activity
/usersPer-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_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 a group_key field identifying the dimension value. Use this when piping data into tools that expect flat rows (spreadsheets, BI tools, time-series databases).

For example, /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.

Factory Standard Credits usage

GET/tokens

Returns daily Factory Standard Credits consumption across your organization.

Query Parameters

startDatestringqueryrequired
Start date in YYYY-MM-DD format
endDatestringqueryrequired
End date in YYYY-MM-DD format
group_bystringqueryoptional
Set to model to group results by model

Response Fields

datestring
Date in YYYY-MM-DD format
billable_tokensnumber
Factory Standard Credits consumed, computed from raw input and raw output tokens with cache discounts
input_tokensnumber
Raw input tokens sent to model
output_tokensnumber
Tokens generated by model
cache_read_tokensnumber
Tokens read from prompt cache
cache_write_tokensnumber
Tokens written to prompt cache
by_modelarray
Breakdown per model
by_userarray
Breakdown per user

Example

Bash
# Factory Standard Credits usage for a date range
curl -H "Authorization: Bearer $FACTORY_API_KEY" \
  "https://api.factory.ai/api/v1/analytics/tokens?startDate=2026-01-14&endDate=2026-01-28"
 
# Grouped by model
curl -H "Authorization: Bearer $FACTORY_API_KEY" \
  "https://api.factory.ai/api/v1/analytics/tokens?startDate=2026-01-15&endDate=2026-01-15&group_by=model"

Tool usage

GET/tools

Returns daily tool invocations, MCP usage, skills, slash commands, and autonomy metrics.

Query Parameters

startDatestringqueryrequired
Start date in YYYY-MM-DD format
endDatestringqueryrequired
End date in YYYY-MM-DD format
group_bystringqueryoptional
Set to tool_name to group results by tool

Response

200
JSON
{
  "data": [
    {
      "date": "2026-01-15",
      "tool_calls": 45000,
      "by_tool": [
        { "tool": "Read", "invocations": 12500 },
        { "tool": "Edit", "invocations": 8200 },
        { "tool": "Execute", "invocations": 6100 }
      ],
      "mcp_users_with_mcp": 42,
      "mcp_by_server": [
        { "server": "github", "invocations": 1200 },
        { "server": "notion", "invocations": 850 }
      ],
      "skills_invocations": 320,
      "skills_by_name": [
        { "name": "browser", "count": 180 },
        { "name": "frontend-ui", "count": 95 }
      ],
      "slash_commands_invocations": 1500,
      "slash_commands_by_name": [
        { "name": "review", "count": 420 },
        { "name": "test", "count": 380 }
      ],
      "hooks_invocations": 2800,
      "hooks_by_event": [
        { "event": "PostToolUse", "matcher": "*.ts", "command": "eslint --fix", "count": 1200 }
      ],
      "web_users": 42,
      "autonomy_ratio_avg": 8.5,
      "autonomy_ratio_p50": 6.2,
      "autonomy_ratio_p90": 18.4,
      "tool_calls_per_session_avg": 45.2,
      "user_turns_per_session_avg": 5.3,
      "tool_autonomy_level_ratio": {
        "auto_high": 0.35,
        "auto_medium": 0.42,
        "auto_low": 0.18,
        "manual": 0.05
      }
    }
  ],
  "meta": {
    "org_id": "org_01HPMQ6ABCDE...",
    "start_date": "2026-01-15",
    "end_date": "2026-01-15"
  }
}

Response Fields

datestring
Date in YYYY-MM-DD format
tool_callsnumber
Total tool invocations
by_toolarray
Breakdown by tool name
mcp_users_with_mcpnumber
Users who used MCP servers
mcp_by_serverarray
Invocations per MCP server
skills_invocationsnumber
Total skill activations
skills_by_namearray
Breakdown by skill
slash_commands_invocationsnumber
Total slash command uses
slash_commands_by_namearray
Breakdown by command
hooks_invocationsnumber
Total hook executions
hooks_by_eventarray
Breakdown by event type
web_usersnumber
Users who used web/workspace interface
autonomy_ratio_avgnumber
Average tool calls per user turn
autonomy_ratio_p50number
Median autonomy ratio
autonomy_ratio_p90number
90th percentile autonomy ratio
tool_calls_per_session_avgnumber
Average tool calls per session
user_turns_per_session_avgnumber
Average user messages per session
tool_autonomy_level_ratioobject
Distribution of autonomy levels

Grouped Response

When group_by=tool_name, returns one row per tool per day inside data:

JSON
{
  "data": [
    {
      "date": "2026-01-15",
      "group_key": "Read",
      "tool_calls": 12500
    },
    {
      "date": "2026-01-15",
      "group_key": "Edit",
      "tool_calls": 8200
    }
  ],
  "meta": {
    "org_id": "org_01HPMQ6ABCDE...",
    "start_date": "2026-01-15",
    "end_date": "2026-01-15"
  }
}

User activity

GET/activity

Returns daily, weekly, and monthly active users along with session counts.

Query Parameters

startDatestringqueryrequired
Start date in YYYY-MM-DD format
endDatestringqueryrequired
End date in YYYY-MM-DD format
group_bystringqueryoptional
Set to client to group by client type

Response

200
JSON
{
  "data": [
    {
      "date": "2026-01-15",
      "daily_active_users": 128,
      "weekly_active_users": 312,
      "monthly_active_users": 485,
      "daily_active_users_by_client": {
        "terminal-ui": 95,
        "web": 42,
        "non-interactive-cli": 18
      },
      "sessions": 890,
      "messages": 12500,
      "user_messages": 4200
    }
  ],
  "meta": {
    "org_id": "org_01HPMQ6ABCDE...",
    "start_date": "2026-01-15",
    "end_date": "2026-01-15"
  }
}

Response Fields

datestring
Date in YYYY-MM-DD format
daily_active_usersnumber
Unique users on this day
weekly_active_usersnumber
Unique users in trailing 7 days
monthly_active_usersnumber
Unique users in trailing 30 days
daily_active_users_by_clientobject
DAU breakdown by client type
sessionsnumber
Total sessions started
messagesnumber
Total messages (user + assistant)
user_messagesnumber
Messages from users only

Client Types

ClientDescription
terminal-uiInteractive CLI sessions
webFactory App
non-interactive-cliHeadless/automated CLI (droid exec)

Grouped Response

When group_by=client, returns one row per client type per day inside data:

JSON
{
  "data": [
    {
      "date": "2026-01-15",
      "group_key": "terminal-ui",
      "daily_active_users": 95
    },
    {
      "date": "2026-01-15",
      "group_key": "web",
      "daily_active_users": 42
    }
  ],
  "meta": {
    "org_id": "org_01HPMQ6ABCDE...",
    "start_date": "2026-01-15",
    "end_date": "2026-01-15"
  }
}

Productivity

GET/productivity

Returns daily file operations and git activity.

Query Parameters

startDatestringqueryrequired
Start date in YYYY-MM-DD format
endDatestringqueryrequired
End date in YYYY-MM-DD format

Response

200
JSON
{
  "data": [
    {
      "date": "2026-01-15",
      "files_created": 245,
      "files_edited": 1820,
      "by_extension": [
        { "extension": ".ts", "count": 890 },
        { "extension": ".tsx", "count": 420 },
        { "extension": ".py", "count": 310 }
      ],
      "by_language": [
        { "language": "TypeScript", "count": 1310 },
        { "language": "Python", "count": 310 }
      ],
      "git_commits": 156,
      "git_prs_created": 42
    }
  ],
  "meta": {
    "org_id": "org_01HPMQ6ABCDE...",
    "start_date": "2026-01-15",
    "end_date": "2026-01-15"
  }
}

Response Fields

datestring
Date in YYYY-MM-DD format
files_creatednumber
New files created by agent
files_editednumber
Existing files modified by agent
by_extensionarray
Operations per file extension
by_languagearray
Operations per programming language
git_commitsnumber
Commits made via agent
git_prs_creatednumber
Pull requests created via agent

Per-user metrics

GET/users

Returns detailed metrics per user with cursor-based pagination.

Query Parameters

startDatestringqueryrequired
Start date in YYYY-MM-DD format
endDatestringqueryrequired
End date in YYYY-MM-DD format
limitnumberqueryoptional
Users per page, 1-100 (default: 20)
cursorstringqueryoptional
User ID for pagination (from next_cursor)

Response

200
JSON
{
  "data": [
    {
      "user_id": "user_01HPMQ7NXKHM7Y7PR3TTZY3JZS",
      "user_email": "developer@company.com",
      "date": "2026-01-15",
      "tool_calls": 1250,
      "billable_tokens": 450000,
      "primary_model": "claude-sonnet-4-5-20250929",
      "primary_model_tier": "standard",
      "files_created": 12,
      "files_edited": 85,
      "git_commits": 8,
      "git_prs_created": 2,
      "mcp_calls": 45,
      "skill_calls": 8,
      "slash_commands": 22,
      "hooks": 120,
      "sessions": 15,
      "messages": 180,
      "user_messages": 62,
      "assistant_messages": 118,
      "autonomy_ratio": 9.2,
      "delegation_level": "auto-high",
      "languages": ["TypeScript", "Python", "Go"]
    }
  ],
  "meta": {
    "org_id": "org_01HPMQ6ABCDE...",
    "start_date": "2026-01-15",
    "end_date": "2026-01-15",
    "has_more": true,
    "next_cursor": "user_01HPMQ8ABCDE7Y7PR3TTZY4KLM"
  }
}

Response Fields

user_idstring
Unique user identifier
user_emailstring | null
User email
datestring
Date in YYYY-MM-DD format
tool_callsnumber
Tool invocations by this user
billable_tokensnumber
Factory Standard Credits consumed by this user
primary_modelstring
Most-used model
primary_model_tierstring
Model tier (standard or thinking)
files_creatednumber
Files created
files_editednumber
Files edited
git_commitsnumber
Commits made
git_prs_creatednumber
Pull requests created
mcp_callsnumber
MCP tool invocations
skill_callsnumber
Skill activations
slash_commandsnumber
Slash command uses
hooksnumber
Hook executions
sessionsnumber
Sessions started
messagesnumber
Total messages
user_messagesnumber
User messages only
assistant_messagesnumber
Assistant messages
autonomy_rationumber
Tool calls per user turn
delegation_levelstring
Primary autonomy mode
languagesarray
Programming languages worked in

Delegation Levels

LevelDescription
auto-highMaximum autonomy, minimal confirmations
auto-mediumBalanced autonomy with some confirmations
auto-lowLimited autonomy, frequent confirmations
specSpecification mode, planning before execution
manualFull manual control, confirm each action

Pagination

Use cursor-based pagination to iterate through users:

Bash
# First page
curl -H "Authorization: Bearer $FACTORY_API_KEY" \
  "https://api.factory.ai/api/v1/analytics/users?startDate=2026-01-15&endDate=2026-01-15&limit=50"
 
# Next page
curl -H "Authorization: Bearer $FACTORY_API_KEY" \
  "https://api.factory.ai/api/v1/analytics/users?startDate=2026-01-15&endDate=2026-01-15&limit=50&cursor=user_01HPMQ8ABCDE7Y7PR3TTZY4KLM"

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 400 error.

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.

Errors

The API returns standard HTTP status codes:

StatusDescription
400Invalid date format, today's date requested, or limit out of range
401Missing or invalid API key
403Insufficient permissions (requires Manager or Owner role)
500Internal error

Error response format

JSON
{
  "title": "Bad Request",
  "detail": "Cannot query today's date - analytics data has a 24-hour lag",
  "status": 400,
  "requestId": "req_01HPMQ9WXYZ..."
}

Data pipeline

Analytics data flows through the following pipeline:

CLI/Daemon → OTEL Events → BigQuery (raw) → dbt models → API
  • 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

Note

A few known data quality considerations:

  • MCP server names: Some duplicates exist due to case sensitivity (e.g., axiom vs Axiom)
  • 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

Use cases

Cost monitoring dashboard

Track usage trends and identify cost drivers:

Bash
# Daily usage for the month
curl -H "Authorization: Bearer $FACTORY_API_KEY" \
  "https://api.factory.ai/api/v1/analytics/tokens?startDate=2026-01-14&endDate=2026-01-28"

Adoption tracking

Monitor DAU/WAU/MAU and identify adoption patterns:

Bash
# Activity metrics with client breakdown
curl -H "Authorization: Bearer $FACTORY_API_KEY" \
  "https://api.factory.ai/api/v1/analytics/activity?startDate=2026-01-14&endDate=2026-01-28&group_by=client"

Team productivity reports

Measure output and efficiency:

Bash
# Productivity metrics
curl -H "Authorization: Bearer $FACTORY_API_KEY" \
  "https://api.factory.ai/api/v1/analytics/productivity?startDate=2026-01-14&endDate=2026-01-28"

Individual performance

Export per-user metrics for team leads:

Bash
# Paginate through all users
curl -H "Authorization: Bearer $FACTORY_API_KEY" \
  "https://api.factory.ai/api/v1/analytics/users?startDate=2026-01-15&endDate=2026-01-15&limit=100"