Factory Analytics API

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

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

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

The organization-level endpoints require the Manager or Owner role. The personal cost endpoint is available to members with the User role and returns data only for the authenticated user.

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 six endpoints, each focused on a specific category of metrics:

EndpointDescription
/tokensOrganization-wide Factory Standard Credits by model and user
/cost/me/querySelf-scoped Factory Standard Credits and attribution metrics
/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"

Personal Factory Standard Credits usage

GET/cost/me/query

Returns Factory Standard Credits and attribution metrics for the authenticated user. The API derives the user ID from the bearer credential and does not accept a user selector, so callers cannot query another user.

This endpoint is available to Enterprise organizations with Analytics enabled.

Query Parameters

queryKeystringqueryrequired
Selects the metric returned in data.
startDatestringqueryrequired
Start date in YYYY-MM-DD format.
endDatestringqueryrequired
End date in YYYY-MM-DD format. Use yesterday or earlier.

Query Keys

ValueDescription
headline_dailyDaily Factory Standard Credits consumed
cost_summaryTotal sessions, messages, credits, and averages
top_sessionsSessions with the highest credit consumption
by_modelCredit consumption by model
fsc_by_model_dailyDaily credit consumption grouped by model
fsc_by_multiplier_dailyDaily credit consumption grouped by multiplier
by_ticketCredit consumption attributed to tickets
by_prCredit consumption attributed to pull requests
my_activity_summaryActivity totals for the authenticated user
my_time_spentEstimated time spent by the authenticated user
my_intent_breakdownCredit consumption grouped by intent
my_completed_tickets_dailyDaily completed-ticket counts
my_completed_ticketsCompleted-ticket details
my_merged_prs_dailyDaily merged-pull-request counts
my_merged_pr_detailMerged-pull-request details

Response

200

The fields inside data depend on queryKey. For headline_daily, each row contains:

JSON
{
  "data": [
    {
      "date": "2026-08-01",
      "fsc": 123456
    }
  ],
  "meta": {
    "org_id": "org_01HPMQ8ABCDE7Y7PR3TTZY4KLM",
    "start_date": "2026-08-01",
    "end_date": "2026-08-31"
  }
}

Response Fields

dataobject[]
Rows for the requested queryKey, scoped to the authenticated user.
meta.org_idstring
Organization associated with the bearer credential.
meta.start_datestring
Start of the requested UTC date range.
meta.end_datestring
End of the requested UTC date range.

Example

Bash
# Daily personal usage
curl -H "Authorization: Bearer $FACTORY_API_KEY" \
  "https://api.factory.ai/api/v1/analytics/cost/me/query?queryKey=headline_daily&startDate=2026-08-01&endDate=2026-08-31"

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.
Personal cost range
The /cost/me/query endpoint accepts a maximum range of 90 days.

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 role, organization tier, or Analytics access
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"