Scout API v1 Reference
Base URL: https://scout-api.larridin.com/api/v1
Authentication: API key via x-company-api-key header (ANALYTICS scope required)
Standard Response Envelope:
{ "success": true, "data": { ... }, "query": { ... } }Error Response:
{ "success": false, "error": "Error message" }Validation Error Response (400):
{ "error": "Validation failed", "details": [{ "field": "startDate", "message": "..." }] }Table of Contents
1. Adoption
GET /adoption/overview
Returns organization-level or department-level AI adoption overview metrics.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | Yes | - | YYYY-MM-DD |
endDate | string | Yes | - | YYYY-MM-DD |
groupBy | string | No | none | none or departments |
granularity | string | No | daily | daily, weekly, biweekly, four-weekly, monthly, twelve-weekly |
department[] | string[] | No | - | Filter by department IDs |
aiTypes[] | string[] | No | - | Filter by AI tool types |
sortBy | string | No | aiActiveSessions | departmentName, aiActiveSessions, aiActiveUsers, avgDau, avgAiAdoptionRate |
sortOrder | string | No | desc | asc or desc |
Response (groupBy=none):
{
"success": true,
"data": {
"activeUsersCount": 150,
"activeUsersCountChange": 5.2,
"aiActiveUsersCount": 120,
"aiActiveUsersCountChange": 8.1,
"aiActiveSessionsCount": 5000,
"aiActiveSessionsCountChange": 12.3,
"aiActiveBrowserSessionsCount": 3000,
"aiActiveBrowserSessionsCountChange": 10.0,
"aiActiveDesktopSessionsCount": 2000,
"aiActiveDesktopSessionsCountChange": 15.5,
"aiAdoptionRate": 80.0,
"aiAdoptionRateChange": 3.2,
"avgDau": 45.3,
"avgDauChange": 2.1,
"dauPct": 30.2,
"dauPctChangePct": 1.5,
"aiSessionsPerAiUser": 41.7,
"aiSessionsPerAiUserChangePct": 5.0,
"rolling30daysActiveAiUsers": 95,
"rolling30daysActiveAiUsersChangePct": 4.2,
"avgWau": 85.0,
"avgWauChangePct": 3.0,
"avgWauPct": 56.7,
"avgWauPctChangePct": 2.0,
"avgAiEngagementScore": 7.5,
"avgAiEngagementScoreChangePct": 1.2,
"avgMau": 110,
"avgMauChangePct": 4.5
}
}Response (groupBy=departments):
{
"success": true,
"data": {
"departments": [
{
"departmentId": "dept-123",
"departmentName": "Engineering",
"aiActiveSessions": 2500,
"aiActiveBrowserSessions": 1500,
"aiActiveDesktopSessions": 1000,
"activeUsersCount": 80,
"aiActiveUsers": 65,
"avgDau": 22.0,
"avgAiAdoptionRate": 81.3,
"avgAiAdoptionRateChangePct": 4.5,
"dauPct": 27.5,
"dauPctChangePct": 1.2,
"aiSessionsPerAiUser": 38.5,
"aiSessionsPerAiUserChangePct": 3.0,
"rolling30daysActiveAiUsers": 55,
"rolling30daysActiveAiUsersChangePct": 6.0,
"avgWau": 50.0,
"avgWauChangePct": 2.5,
"avgWauPct": 62.5,
"avgWauPctChangePct": 1.8,
"avgAiEngagementScore": 8.0,
"avgAiEngagementScoreChangePct": 0.5,
"avgMau": 70,
"avgMauChangePct": 3.0,
"toolsUsed": 5,
"activeDaysPerAiUser": 3.2
}
]
}
}GET /adoption/trends
Returns time-series adoption metrics with optional grouping.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | Yes | - | YYYY-MM-DD |
endDate | string | Yes | - | YYYY-MM-DD |
groupBy | string | Yes | - | none, tools, or departments |
granularity | string | No | daily | Granularity option |
metrics | string | No | - | Comma-separated list of metrics to include |
department[] | string[] | No | - | Filter by department IDs |
tool[] | string[] | No | - | Filter by tool IDs |
platform[] | string[] | No | - | BROWSER, DESKTOP |
aiTypes[] | string[] | No | - | Filter by AI tool types |
Response:
{
"success": true,
"data": {
"data": [
{
"date": "2024-01-01",
"activeUsersCount": 150,
"aiActiveUsersCount": 120,
"aiActiveSessionsCount": 5000,
"aiActiveBrowserSessionsCount": 3000,
"aiActiveDesktopSessionsCount": 2000,
"aiAdoptionRate": 80.0,
"avgDau": 45.3,
"dauPct": 30.2,
"dauPctChangePct": 1.5,
"toolsUsed": 5,
"aiSessionsPerAiUser": 41.7,
"aiSessionsPerAiUserChangePct": 5.0,
"rolling30daysActiveAiUsers": 95,
"rolling30daysActiveAiUsersChangePct": 4.2,
"avgWau": 85.0,
"avgWauChangePct": 3.0,
"avgWauPct": 56.7,
"avgWauPctChangePct": 2.0,
"avgAiEngagementScore": 7.5,
"avgAiEngagementScoreChangePct": 1.2,
"p25AiEngagementScore": 5.0,
"p50AiEngagementScore": 7.5,
"p75AiEngagementScore": 9.0,
"avgMau": 110,
"avgMauChangePct": 4.5,
"toolTypes": ["AI_ASSISTANT"],
"toolName": "ChatGPT",
"toolId": "tool-123",
"platform": "BROWSER",
"departmentName": "Engineering",
"departmentId": "dept-123"
}
],
"groupBy": "none",
"tools": [{ "toolId": "tool-123", "toolName": "ChatGPT", "platform": "BROWSER" }],
"departments": [{ "departmentId": "dept-123", "departmentName": "Engineering" }],
"aiTypes": ["AI_ASSISTANT"]
}
}GET /adoption/breakdown
Returns detailed breakdown of AI adoption by tools or departments, with pagination.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | Yes | - | YYYY-MM-DD |
endDate | string | Yes | - | YYYY-MM-DD |
groupBy | string | Yes | - | tools or departments |
granularity | string | No | daily | Granularity option |
department[] | string[] | No | - | Filter by department IDs |
tool[] | string[] | No | - | Filter by tool IDs |
platform[] | string[] | No | - | BROWSER, DESKTOP |
aiTypes[] | string[] | No | - | Filter by AI tool types |
sortBy | string | No | aiActiveSessions | departmentName, toolName, aiActiveSessions, aiActiveUsers, avgDau, avgAiAdoptionRate |
sortOrder | string | No | desc | asc or desc |
page | number | No | 1 | Page number (min: 1) |
limit | number | No | 10 | Results per page (max: 100) |
Response (groupBy=tools):
{
"success": true,
"data": {
"data": [
[
{
"toolId": "tool-123",
"name": "ChatGPT",
"category": "AI_ASSISTANT",
"status": "APPROVED",
"platform": "BROWSER",
"licenseType": null,
"aiActiveSessions": 2500,
"aiActiveUsers": 65,
"avgDau": 22.0,
"avgAiAdoptionRate": 81.3,
"isAiTool": true,
"metricType": "non-license",
"rank": 1,
"dauPct": 27.5,
"dauPctChangePct": 1.2,
"aiSessionsPerAiUser": 38.5,
"aiSessionsPerAiUserChangePct": 3.0,
"avgWau": 50.0,
"avgWauChangePct": 2.5,
"avgWauPct": 62.5,
"avgWauPctChangePct": 1.8,
"avgMau": 70,
"avgMauChangePct": 3.0
}
]
],
"total": 25,
"page": 1,
"limit": 10
}
}Response (groupBy=departments):
{
"success": true,
"data": {
"data": [
{
"departmentId": "dept-123",
"departmentName": "Engineering",
"aiActiveSessions": 2500,
"aiActiveBrowserSessions": 1500,
"aiActiveDesktopSessions": 1000,
"aiActiveUsers": 65,
"avgDau": 22.0,
"avgAiAdoptionRate": 81.3,
"rank": 1,
"dauPct": 27.5,
"dauPctChangePct": 1.2,
"avgWau": 50.0,
"avgWauChangePct": 2.5,
"avgWauPct": 62.5,
"avgWauPctChangePct": 1.8,
"avgAiEngagementScore": 8.0,
"avgAiEngagementScoreChangePct": 0.5,
"toolsUsed": 5,
"activeDaysPerAiUser": 3.2,
"tools": [[ { "toolId": "...", "name": "...", "aiActiveSessions": 500 } ]]
}
],
"total": 8,
"page": 1,
"limit": 10
}
}2. Proficiency
All proficiency endpoints use period-based selection instead of date ranges.
GET /proficiency/score
Returns AI proficiency score snapshot with prior-period comparison.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodType | string | Yes | - | monthly or quarterly |
period | number | Yes | - | 1-12 (monthly) or 1-4 (quarterly) |
year | number | Yes | - | e.g. 2024 |
groupBy | string | No | none | none or departments |
granularity | string | No | weekly | weekly or biweekly |
department[] | string[] | No | - | Filter by department IDs |
tool[] | string[] | No | - | Filter by tool IDs |
Response (groupBy=none):
{
"success": true,
"data": {
"data": {
"averageAiProficiencyScore": 72.5,
"p85AiProficiencyScore": 90.0,
"p75AiProficiencyScore": 85.0,
"p50AiProficiencyScore": 72.0,
"p25AiProficiencyScore": 55.0,
"promptQualityComponent": 68.0,
"featureAdoptionComponent": 75.0,
"useCaseDiversityComponent": 74.5,
"aiProficiencyScore": 72.5,
"scoresCount": 120,
"userCount": 85,
"prevPeriodValue": 68.0,
"prevPeriodDelta": 6.6,
"promptQualityComponentPrevPeriodDelta": 3.2,
"useCaseDiversityComponentPrevPeriodDelta": 5.1
},
"filters": {
"periodType": "monthly",
"period": 3,
"year": 2024,
"departmentIds": [],
"orgToolIds": []
},
"groupedByDepartment": false,
"summary": { "dateRange": { "start": "2024-03-01", "end": "2024-03-31" } },
"pendingPeriod": null
}
}Response (groupBy=departments):
{
"success": true,
"data": {
"data": [
{
"departmentId": "dept-123",
"departmentName": "Engineering",
"averageAiProficiencyScore": 78.0,
"p50AiProficiencyScore": 76.0,
"promptQualityComponent": 72.0,
"featureAdoptionComponent": 80.0,
"useCaseDiversityComponent": 82.0,
"aiProficiencyScore": 78.0,
"scoresCount": 45,
"userCount": 30,
"prevPeriodValue": 74.0,
"prevPeriodDelta": 5.4
}
],
"filters": { ... },
"groupedByDepartment": true,
"summary": { "dateRange": { "start": "2024-03-01", "end": "2024-03-31" } }
}
}GET /proficiency/trends
Returns time-series AI proficiency score data.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodType | string | Yes | - | monthly or quarterly |
period | number | Yes | - | Period number |
year | number | Yes | - | Year |
groupBy | string | No | none | none or departments |
granularity | string | No | weekly | weekly or biweekly |
department[] | string[] | No | - | Filter by department IDs |
tool[] | string[] | No | - | Filter by tool IDs |
percentiles[] | string[] | No | - | p25, p50, p75 |
Response:
{
"success": true,
"data": {
"data": [
{
"date": "2024-03-04",
"dateRange": { "start": "2024-03-04", "end": "2024-03-10" },
"averageAiProficiencyScore": 71.0,
"p85AiProficiencyScore": 89.0,
"p75AiProficiencyScore": 84.0,
"p50AiProficiencyScore": 71.0,
"p25AiProficiencyScore": 54.0,
"promptQualityComponent": 66.0,
"featureAdoptionComponent": 74.0,
"useCaseDiversityComponent": 73.0,
"aiProficiencyScore": 71.0,
"scoresCount": 30,
"userCount": 22
}
],
"filters": { ... },
"groupedByDepartment": false,
"summary": { "totalDataPoints": 4, "dateRange": { "start": "2024-03-04", "end": "2024-03-31" } }
}
}GET /proficiency/prompt-categories
Returns AI topic/prompt classification breakdown.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodType | string | Yes | - | monthly or quarterly |
period | number | Yes | - | Period number |
year | number | Yes | - | Year |
groupBy | string | No | none | none or departments |
granularity | string | No | weekly | weekly or biweekly |
department[] | string[] | No | - | Filter by department IDs |
tool[] | string[] | No | - | Filter by tool IDs |
topics[] | string[] | No | - | Filter by topic names |
Response (groupBy=none):
{
"success": true,
"data": {
"data": {
"topics": { "Code Generation": 450, "Debugging": 320, "Documentation": 180 },
"totalUsers": 85,
"totalEvents": 950
},
"filters": { ... },
"groupedByDepartment": false,
"summary": { "dateRange": { "start": "2024-03-01", "end": "2024-03-31" } }
}
}Response (groupBy=departments):
{
"success": true,
"data": {
"data": [
{
"departmentId": "dept-123",
"departmentName": "Engineering",
"topics": { "Code Generation": 250, "Debugging": 180 },
"totalUsers": 30,
"totalEvents": 430
}
],
"filters": { ... },
"groupedByDepartment": true,
"summary": { "dateRange": { ... } }
}
}GET /proficiency/conversation-metrics
Returns time-series conversation-level interaction metrics.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodType | string | Yes | - | monthly or quarterly |
period | number | Yes | - | Period number |
year | number | Yes | - | Year |
groupBy | string | No | none | none or departments |
granularity | string | No | weekly | weekly or biweekly |
department[] | string[] | No | - | Filter by department IDs |
tool[] | string[] | No | - | Filter by org_tool IDs |
Response:
{
"success": true,
"data": {
"data": [
{
"date": "2024-03-04",
"dateRange": { "start": "2024-03-04", "end": "2024-03-10" },
"avgTurnDepth": 4.2,
"singleTurnDominancePct": 35.0,
"messagesPerSession": 8.5,
"conversationCount": 320,
"userCount": 85
}
],
"filters": { ... },
"groupedByDepartment": false,
"summary": { "totalDataPoints": 4, "dateRange": { ... } }
}
}3. Tools
Browser Adoption
GET /tools/browser/overview
Returns browser platform AI adoption overview metrics.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | Yes | - | YYYY-MM-DD |
endDate | string | Yes | - | YYYY-MM-DD |
granularity | string | No | daily | Granularity option |
Response:
{
"success": true,
"data": {
"adoptionRate": 80.0,
"adoptionChange": 5.2,
"aiEngagementScore": 0.75,
"aiEngagementScoreChange": 3.0,
"aiActiveUsers": 120,
"aiActiveUsersChange": 8.1,
"activeUsers": 150,
"activeUsersChange": 5.0,
"dau": 45.3,
"mau": 110,
"activeEventsPerEmployee": 42.0,
"uniqueAppsPerEmployee": 3.5,
"dauChange": 2.1,
"mauChange": 4.5,
"activeEventsChange": 12.0,
"uniqueAppsChange": 8.0,
"installBase": 130,
"installBaseChange": 6.0,
"totalSessions": 5000,
"totalSessionsChange": 15.0,
"avgSessionDuration": 12.5,
"avgSessionDurationChange": 3.0,
"totalActiveMinutes": 45.0,
"totalActiveMinutesChange": 5.0
}
}GET /tools/browser/trends
Returns time-series browser adoption data.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | Yes | - | YYYY-MM-DD |
endDate | string | Yes | - | YYYY-MM-DD |
groupBy | string | No | none | none, departments, tools |
granularity | string | No | daily | Granularity option |
department[] | string[] | No | - | Filter by department IDs |
tool[] | string[] | No | - | Filter by tool IDs |
Response:
{
"success": true,
"data": {
"data": [
{
"period": "2024-01-01",
"adoptionRate": 80.0,
"activeAiUsers": 120,
"activeUsers": 150,
"dau": 45.3,
"activeEventsPerUser": 42.0,
"dauPct": 30.2,
"dauPctChangePct": 1.5,
"avgWau": 85.0,
"avgWauChangePct": 3.0,
"avgWauPct": 56.7,
"avgWauPctChangePct": 2.0,
"toolName": "ChatGPT",
"toolId": "tool-123",
"departmentName": "Engineering",
"departmentId": "dept-123"
}
],
"groupBy": "none",
"departments": [{ "departmentId": "dept-123", "departmentName": "Engineering" }],
"tools": [{ "toolId": "tool-123", "toolName": "ChatGPT" }]
}
}GET /tools/browser/breakdown
Returns detailed breakdown of browser AI usage by tools or departments.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | Yes | - | YYYY-MM-DD |
endDate | string | Yes | - | YYYY-MM-DD |
groupBy | string | Yes | - | departments or tools |
granularity | string | No | daily | Granularity option |
sortBy | string | No | dau | dau, aiActiveSessions, aiActiveUsers, avgAiAdoptionRate, toolName, departmentName |
sortOrder | string | No | desc | asc or desc |
page | number | No | 1 | Page number |
limit | number | No | 10 | Max: 100 |
department[] | string[] | No | - | Filter by department IDs |
tool[] | string[] | No | - | Filter by tool IDs |
Response: Same paginated format as adoption/breakdown.
Desktop Adoption
GET /tools/desktop/overview
Same parameters as browser overview. Returns DesktopOrganizationOverview:
{
"success": true,
"data": {
"adoptionRate": 65.0,
"adoptionRateChange": 8.0,
"activeAiUsers": 50,
"activeAiUsersChange": 12.0,
"activeUsers": 80,
"activeUsersChange": 5.0,
"dau": 15.0,
"dauChange": 3.0,
"activeEventsPerUser": 25.0,
"activeEventsPerUserChange": 6.0
}
}GET /tools/desktop/trends
Same parameters as browser trends. Same response shape.
GET /tools/desktop/breakdown
Desktop breakdown is tools-only (no department grouping).
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | Yes | - | YYYY-MM-DD |
endDate | string | Yes | - | YYYY-MM-DD |
granularity | string | No | daily | Granularity option |
sortBy | string | No | dau | Sort field |
sortOrder | string | No | desc | asc or desc |
page | number | No | 1 | Page number |
limit | number | No | 10 | Max: 100 |
tool[] | string[] | No | - | Filter by tool IDs |
Response:
{
"success": true,
"data": {
"data": [
{
"tool_id": "tool-456",
"tool_name": "Cursor",
"status": "APPROVED",
"category": "AI_IDE",
"active_events": 1200,
"ai_adoption_rate": 75.0,
"active_ai_users": 40,
"dau": 12.0,
"growth_rate": 15.0,
"rank": 1,
"dauPct": 15.0,
"avgWau": 35.0,
"avgWauPct": 43.8
}
],
"total": 5,
"page": 1,
"limit": 10
}
}Tool Metrics
GET /tools/:toolId
Returns metrics for a specific tool over time.
Path Parameters: toolId (string, required)
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | Yes | - | YYYY-MM-DD |
endDate | string | Yes | - | YYYY-MM-DD |
granularity | string | No | daily | Granularity option |
Response:
{
"success": true,
"data": {
"toolId": "tool-123",
"granularity": "daily",
"data": [
{
"date": "2024-01-01",
"toolId": "tool-123",
"toolName": "ChatGPT",
"metricType": "non-license",
"platform": "BROWSER",
"licenseType": null,
"toolTypes": ["AI_ASSISTANT"],
"toolCategory": "AI_ASSISTANT",
"toolStatus": "APPROVED",
"activeUsersCount": 150,
"aiActiveUsersCount": 120,
"aiActiveSessionsCount": 5000,
"aiAdoptionRate": 80.0,
"avgDau": 45.3,
"dauPct": 30.2,
"aiSessionsPerAiUser": 41.7
}
]
}
}User Tool Usage
GET /tools/user-tool-usage
Returns user-level AI tool usage data.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | Yes | - | YYYY-MM-DD |
endDate | string | Yes | - | YYYY-MM-DD |
departmentName[] | string[] | No | - | Filter by department names |
userEmail[] | string[] | No | - | Filter by user emails |
toolName[] | string[] | No | - | Filter by tool names |
toolDomain[] | string[] | No | - | Filter by tool domains (case-insensitive) |
page | number | No | 1 | Page number |
limit | number | No | 10 | Max: 100 |
Response:
{
"success": true,
"data": {
"data": [
{
"date": "2024-01-15",
"userEmail": "user@company.com",
"departmentId": "dept-123",
"departmentName": "Engineering",
"toolId": "tool-123",
"toolName": "ChatGPT",
"toolDomains": ["chatgpt.com"],
"platform": "BROWSER",
"toolMetrics": [
{ "activeEvents": 45, "metricsType": "non-license", "licenseType": null }
]
}
],
"total": 250,
"page": 1,
"limit": 10
}
}Policy Enforcement
GET /tools/policy/enforcement-overview
Query Parameters: startDate, endDate, granularity (all standard).
Response:
{
"success": true,
"data": {
"data": {
"block_events_count": 150,
"warn_events_count": 320,
"ai_tools_count": 8
}
}
}GET /tools/policy/enforcement-breakdown
Query Parameters: startDate, endDate, granularity, page, limit, sortBy (default: triggerCount), sortOrder.
Response:
{
"success": true,
"data": {
"data": [
{
"tool_id": "tool-789",
"tool_name": "Unauthorized AI Tool",
"licenseType": null,
"events_count": 45,
"events_count_change_pct": 12.0
}
],
"total": 8,
"page": 1,
"limit": 10
}
}GET /tools/policy/breakdown
Query Parameters: startDate, endDate, granularity, page, limit, sortBy (default: enforcementCount), sortOrder, search.
Response:
{
"success": true,
"data": {
"data": [
{
"tool_id": "tool-789",
"tool_name": "AI Tool",
"licenseType": null,
"policy": "Block unapproved AI",
"events_count": 30,
"events_count_change_pct": 8.0,
"updated_at": "2024-03-15T10:30:00Z",
"updated_by": "Admin User"
}
],
"total": 12,
"page": 1,
"limit": 10
}
}Unapproved Tools
GET /tools/unapproved/overview
Query Parameters: startDate, endDate, groupBy (none|departments), granularity.
Response (groupBy=none):
{
"success": true,
"data": {
"data": {
"unauthorized_ai_tool_count": 5,
"unauthorized_ai_tool_rate": 12.5,
"unauthorized_ai_dau_pct": 8.0,
"unauthorized_ai_usage_rate": 15.0,
"unauthorized_ai_tool_count_change_pct": 20.0,
"unauthorized_ai_dau_pct_change_pct": -3.0,
"unauthorized_ai_usage_rate_change_pct": 5.0
}
}
}Response (groupBy=departments):
{
"success": true,
"data": {
"data": [
{
"departmentId": "dept-123",
"departmentName": "Engineering",
"unauthorized_ai_dau_pct": 5.0,
"unauthorized_ai_usage_rate": 10.0,
"unauthorized_ai_dau_pct_change_pct": -2.0,
"unauthorized_ai_usage_rate_change_pct": 3.0
}
]
}
}GET /tools/unapproved/breakdown
Query Parameters: startDate, endDate, groupBy (none|departments), granularity, page, limit.
Response:
{
"success": true,
"data": {
"groupBy": "none",
"data": [
{
"tool_id": "tool-unknown",
"tool_name": "Unknown AI Tool",
"category": "UNCATEGORIZED",
"unauthorized_ai_dau": 3,
"unauthorized_ai_dau_change_pct": 50.0,
"unauthorized_ai_dau_pct": 2.0,
"unauthorized_ai_active_users_count": 5,
"unauthorized_ai_active_sessions_count": 30,
"unauthorized_ai_dau_pct_change_pct": 1.0,
"unauthorized_ai_active_users_count_change_pct": 25.0,
"unauthorized_ai_active_sessions_count_change_pct": 20.0
}
],
"total": 5,
"page": 1,
"limit": 10
}
}4. Surveys
GET /surveys
Returns paginated list of survey campaigns.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
types | string | No | - | Comma-separated campaign types |
statuses | string | No | - | Comma-separated campaign statuses |
search | string | No | - | Search by title |
sortBy | string | No | type | type, status, startDate, responseRate |
desc | boolean | No | true | Sort descending |
page | number | No | 1 | Page number |
limit | number | No | 10 | Max: 100 |
department[] | string[] | No | - | Filter by department IDs |
campaign[] | string[] | No | - | Filter by campaign IDs |
Response:
{
"success": true,
"data": {
"campaigns": [
{
"campaignId": "camp-123",
"title": "AI Tool Satisfaction Survey",
"description": "Quarterly survey...",
"status": "ACTIVE",
"type": "SURVEY",
"startDate": "2024-01-01T00:00:00Z",
"endDate": "2024-03-31T00:00:00Z",
"owner": "admin@company.com",
"departments": [{ "departmentId": "dept-123", "departmentName": "Engineering" }],
"invitations": 150,
"responses": 120,
"responseRate": 80.0
}
],
"total": 5,
"page": 1,
"limit": 10
}
}GET /surveys/:survey_id
Path Parameters: survey_id (string, required)
Query Parameters: startDate (optional), endDate (optional), granularity (default: alltime; options: daily, monthly, quarterly, alltime).
Response: Same shape as a single campaign item from the list endpoint, with stats included.
GET /surveys/:survey_id/questions
Path Parameters: survey_id (string, required)
Query Parameters: startDate, endDate, granularity (all optional).
Response:
{
"success": true,
"data": {
"questions": [
{
"questionId": "q-123",
"questionTitle": "How satisfied are you with AI tools?",
"questionType": "MULTIPLE_CHOICE",
"invitations": 150,
"responses": 120,
"responseRate": 80.0
}
],
"departments": [{ "departmentId": "dept-123", "departmentName": "Engineering" }]
}
}GET /surveys/:survey_id/questions/:question_id/options
Path Parameters: survey_id, question_id (both required)
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | No | - | YYYY-MM-DD |
endDate | string | No | - | YYYY-MM-DD |
granularity | string | No | alltime | daily, monthly, quarterly, alltime |
graphType | string | No | bar-chart | bar-chart or time-series |
groupBy | string | No | none | none or departments |
option[] | string[] | No | - | Filter by option IDs |
department[] | string[] | No | - | Filter by department IDs |
graphType=time-series+groupBy=departmentsis not supported (400 error).
Response (graphType=bar-chart, groupBy=none):
{
"success": true,
"data": {
"data": [
{
"optionId": "opt-1",
"optionDisplayOrder": 1,
"optionRating": 5,
"optionText": "Very Satisfied",
"responses": 45,
"responses_pct": 37.5
}
],
"options": [{ "optionId": "opt-1", "optionDisplayOrder": 1, "optionText": "Very Satisfied" }]
}
}Response (graphType=bar-chart, groupBy=departments):
{
"success": true,
"data": {
"data": [
{
"departmentId": "dept-123",
"departmentName": "Engineering",
"optionStats": [
{ "optionId": "opt-1", "optionText": "Very Satisfied", "responses": 20, "responses_pct": 40.0 }
]
}
],
"options": [...]
}
}Response (graphType=time-series):
{
"success": true,
"data": {
"data": [
{
"date": "2024-01-01",
"optionStats": [
{ "optionId": "opt-1", "optionText": "Very Satisfied", "responses": 12, "responses_pct": 35.0 }
]
}
],
"granularity": "monthly",
"options": [...]
}
}GET /surveys/:survey_id/questions/:question_id/responses
Path Parameters: survey_id, question_id (both required)
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | No | - | YYYY-MM-DD |
endDate | string | No | - | YYYY-MM-DD |
search | string | No | - | Search term |
page | number | No | 1 | Page number |
limit | number | No | 10 | Max: 100 |
department[] | string[] | No | - | Filter by department IDs |
role[] | string[] | No | - | Filter by employee roles |
Response:
{
"success": true,
"data": {
"data": [
{
"freeText": "The AI tools have significantly improved my productivity...",
"department_name": "Engineering",
"employee_role": "Senior Engineer",
"createdAt": "2024-03-15T10:30:00Z"
}
],
"pagination": { "page": 1, "limit": 10, "total": 85, "totalPages": 9 },
"roles": [{ "employee_role": "Senior Engineer" }, { "employee_role": "Manager" }]
}
}5. Developer Productivity
All dev-productivity endpoints query dbt analytics marts and operate at weekly granularity.
GET /dev-productivity/velocity
Returns CAV, delivery volume, cycle time, work distribution, team breakdown, daily CAV heatmap.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
startDate | string | Yes | - | YYYY-MM-DD |
endDate | string | Yes | - | YYYY-MM-DD |
managerEmail | string | No | - | Filter by manager’s team hierarchy |
repo | string | No | - | Filter by repository name |
tier | string | No | - | Comma-separated: low, medium, high, very-high |
rangeKind | string | No | rolling | rolling, month, quarter |
Response: (abbreviated - see full schema in Velocity Response Detail)
{
"success": true,
"data": {
"kpis": {
"totalCAV": 1250.5, "totalCAVChange": 8.2,
"avgCAVPerWeek": 312.6, "avgCAVPerWeekChange": 5.0,
"avgCAVPerEng": 15.6, "avgCAVPerEngChange": 3.2,
"avgCAVPerEngAI": 6.2, "avgCAVPerEngAIChange": 10.0,
"avgCAVPerEngHuman": 9.4, "avgCAVPerEngHumanChange": -1.0,
"totalPRs": 480, "totalPRsChange": 12.0,
"avgPRsPerWeek": 120.0, "avgPRsPerWeekChange": 8.0,
"avgPRsPerEng": 6.0, "avgPRsPerEngChange": 5.0,
"avgPRsPerEngAI": 2.5, "avgPRsPerEngAIChange": 15.0,
"engineerCount": 20,
"cycleTimeAiHours": 4.5, "cycleTimeAiHoursChange": -10.0,
"cycleTimeHumanHours": 12.3, "cycleTimeHumanHoursChange": -5.0,
"cycleTimeP50Hours": 6.2, "cycleTimeP90Hours": 24.1
},
"cavSummary": {
"periods": ["2024-01-01", "2024-01-08"],
"complexityPoints": {
"total": [100, 120], "ai": [40, 55], "aiAssisted": [38, 52],
"human": [60, 65], "agent": [2, 3],
"perEng": [5.0, 6.0], "perEngAI": [2.0, 2.75], "perEngHuman": [3.0, 3.25]
}
},
"deliveryVolume": {
"periods": ["2024-01-01"],
"engineerCount": [20],
"prsMerged": { "total": [60], "ai": [25], "human": [35], "aiAssisted": [23], "humanOnly": [35], "agent": [2], "perEng": [3.0] },
"commits": { "total": [200], "ai": [80], "aiAssisted": [78], "human": [120], "agent": [2], "perEng": [10.0] },
"linesAdded": [5000], "linesDeleted": [2000],
"linesChanged": { "total": [3000], "ai": [1200], "aiAssisted": [1150], "human": [1800], "agent": [50] }
},
"cycleTime": {
"periods": ["2024-01-01"],
"aiCycleTime": [4.5], "humanCycleTime": [12.0], "agentCycleTime": [null],
"firstResponse": [2.0], "reviewTime": [8.0], "timeToMerge": [1.5],
"p50": [6.0], "p90": [24.0]
},
"dailyCav": [{ "date": "2024-01-01", "cavAi": 2.0, "cavHuman": 3.0, "cavTotal": 5.0, "totalCav": 100.0, "totalCavAi": 40.0, "totalCavHuman": 60.0, "prsMerged": 12, "engineerCount": 20 }],
"workDistribution": {
"periods": ["2024-01-01"],
"thresholds": { "easyMedium": 33, "mediumHard": 67 },
"easy": { "total": [30], "ai": [15], "human": [15] },
"medium": { "total": [20], "ai": [8], "human": [12] },
"hard": { "total": [10], "ai": [2], "human": [8] },
"throughput": { "total": [150], "ai": [60], "human": [90], "perEng": [7.5], "perEngAI": [3.0], "perEngHuman": [4.5] },
"periodTotals": { "totalCAV": 1250.5, "totalCAVChange": 8.2 }
},
"trueCycleTime": { "periods": ["2024-01-01"], "p50": [6.0], "p90": [24.0] },
"teamBreakdown": [{
"teamName": "Frontend", "leadName": "Jane", "managerEmail": "jane@co.com",
"parentManagerEmail": "vp@co.com", "hasSubTeams": true, "hasDirectReports": true,
"totalPRs": 120,
"members": [{ "email": "dev@co.com", "name": "Dev", "isManager": false, "cavPerWeek": [5.0], "cavAiPerWeek": [2.0], "cavHumanPerWeek": [3.0], "prsPerWeek": [3], "locPerWeek": [500] }],
"cavPerWeek": [5.0], "locPerWeek": [500]
}]
},
"query": { "startDate": "2024-01-01", "endDate": "2024-03-31", "organizationId": "org-123", "granularity": "weekly" }
}GET /dev-productivity/quality
Returns innovation rate, code turnover, review metrics, AI slop, rubber stamp rates.
Query Parameters: startDate, endDate, managerEmail, repo, tier.
Response: (abbreviated)
{
"success": true,
"data": {
"innovationRate": {
"periods": ["2024-01-01"], "features": [65.0], "ktlo": [25.0], "bugFixes": [10.0],
"featuresAi": [70.0], "featuresHuman": [60.0], "featuresAgent": [null],
"currentFeatures": 66.5, "currentFeaturesChange": 4.6,
"currentKtlo": 23.0, "currentKtloChange": -3.0,
"currentBugFixes": 10.5, "currentBugFixesChange": 1.0
},
"codeTurnover": {
"periods": ["2024-01-01"],
"ai30d": [0.12], "human30d": [0.15], "ai90d": [0.08], "human90d": [0.10]
},
"reviewMetrics": {
"prSize": { "periods": [...], "median": [250], "p75": [500], "p95": [1200], "avg": [380], "count": [60] },
"reviewSpeed": { "periods": [...], "timeToFirstReview": [2.5], "timeToFirstApproval": [4.0], "cycleTime": [12.0], "humanTimeToFirstApproval": [5.0], "aiTimeToFirstApproval": [1.5] },
"reviewPushback": { "periods": [...], "pushbackRate": [15.0], "approvalRate": [85.0], "humanReviewerPushback": [18.0], "aiReviewerPushback": [5.0] },
"commentQuality": { "periods": [...], "commentDensity": [0.05], "qualityCommentRatio": [72.0], "botComments": [20], "humanComments": [80], "humanSubstantiveCount": [58], "humanTrivialCount": [22] },
"aiVsHumanReview": { "periods": [...], "aiReviewPct": [20.0], "humanReviewPct": [80.0], "aiReviewCount": [15], "humanReviewCount": [60] },
"aiSlop": { "periods": [...], "overall": [3.2], "signalToNoise": [2.8], "unnecessaryAbstractions": [3.5], "unreviewedPaste": [4.0], "defensiveBloat": [2.5], "reinventingTheWheel": [3.0], "prCount": [25] },
"rubberStampRate": { "periods": [...], "rate": [22.0], "rateAi": [30.0], "rateHuman": [18.0], "rateAgent": [null] }
},
"teams": [{ "team": { "teamId": "dept-123", "teamName": "Frontend", "teamLead": "Jane", "managerEmail": "jane@co.com", "memberCount": 8 }, "metrics": { "turnover30d": 0.12, "features": 65.0, "ktlo": 25.0, "bugFixes": 10.0, "aiCodeShare": 35.0 }, "engineers": [...] }],
"weeklyBreakdown": { "periods": [...], "teams": [...], "reviewerMetrics": { "user@co.com": { "pushbackRate": [...], "qualityCommentRatio": [...], "rubberStampRate": [...], "reviewsCompleted": [...], "avgTurnaroundHours": [...] } } }
}
}GET /dev-productivity/cost
Returns per-tool spend, KPIs, team-level cost breakdown, weekly trends.
Query Parameters: startDate, endDate, managerEmail, tier, departmentIds (CSV).
Response:
{
"success": true,
"data": {
"costByTool": {
"periods": ["2024-01-01", "2024-01-08"],
"claude": [5.20, 6.10], "codex": [3.50, 4.00], "cursor": [8.00, 9.50],
"claudeTotal": [52.0, 61.0], "codexTotal": [35.0, 40.0], "cursorTotal": [80.0, 95.0],
"totalPerWeek": [167.0, 196.0]
},
"costKpis": {
"totalCost": 1450.20, "totalCostChange": 17.4,
"costPerToolUser": 72.51, "costPerToolUserChange": 5.0,
"activeToolUsers": 20, "activeToolUsersChange": 10.0
},
"costByToolKpis": {
"claude": { "total": 455.00, "change": 15.0 },
"codex": { "total": 302.00, "change": 12.0 },
"cursor": { "total": 693.20, "change": 20.0 }
},
"teams": [{ "team": { "teamId": "dept-123", "teamName": "Frontend", "managerEmail": "jane@co.com", "parentManagerEmail": "vp@co.com", "hasSubTeams": false, "hasDirectReports": true }, "metrics": { "totalCost": 350.50, "costPerToolUser": 43.81, "activeToolUsers": 8 }, "costByTool": { "claude": 120.0, "codex": 80.0, "cursor": 150.50 }, "members": [{ "name": "Dev", "email": "dev@co.com", "totalCost": 45.20, "costByTool": { "claude": 15.0, "codex": 10.0, "cursor": 20.20 } }] }],
"weeklyBreakdown": { "periods": [...], "teams": [{ "teamId": "...", "teamName": "...", "members": [{ "name": "Dev", "email": "dev@co.com", "isManager": false, "metrics": { "totalCost": [22.50, 22.70], "claudeCost": [7.50, 7.50], "codexCost": [5.00, 5.00], "cursorCost": [10.00, 10.20] } }] }] },
"roiCalculator": null,
"aiRoi": null
}
}GET /dev-productivity/ai-coding-adoption
Returns AI coding tool adoption: KPIs, trends, per-tool trends, team breakdown, adoption distribution.
Query Parameters: startDate, endDate, managerEmail, repo, tier, departmentIds (CSV), rangeKind.
Response:
{
"success": true,
"data": {
"kpis": { "aiCodeSharePct": 35.2, "wauPct": 65.0, "heavyUsersCount": 12, "topTool": { "toolName": "cursor", "wau": 18 } },
"previousKpis": { "aiCodeSharePct": 30.0, "wauPct": 58.0, "heavyUsersCount": 10, "topTool": { "toolName": "cursor", "wau": 15 } },
"adoptionTrend": [{ "period": "2024-01-01", "wauPct": 60.0, "dau": 8.5, "dauPct": 12.0, "wau": 18 }],
"usageTrendsByTool": [{ "period": "2024-01-01", "tools": [{ "name": "cursor", "wau": 15 }, { "name": "claude_code", "wau": 10 }] }],
"toolsByWau": [{ "name": "cursor", "wau": 18, "previousWau": 15 }, { "name": "claude_code", "wau": 12, "previousWau": 8 }],
"teamBreakdown": [{ "teamId": "dept-123", "teamName": "Frontend", "managerEmail": "jane@co.com", "parentManagerEmail": "vp@co.com", "hasSubTeams": false, "hasDirectReports": true, "memberCount": 10, "metrics": { "wauPct": 70.0, "dauPct": 15.0, "activeUsers": 7, "totalDevs": 10, "nonAiCount": 3, "avgActiveDays": 3.5, "aiCodeSharePct": 38.0, "topTool": "cursor", "totalRequests": 5000 }, "engineers": [{ "name": "Dev", "email": "dev@co.com", "tools": ["cursor"], "topTool": "cursor", "activeDays": 4.2, "totalRequests": 800, "usageLevel": "heavy", "aiCodeSharePct": 42.0, "wauPct": 85.0 }] }],
"aiCodeShare": { "trend": [{ "period": "2024-01-01", "pct": 33.5 }] },
"adoptionDistribution": [{ "period": "2024-01-01", "heavy": 8, "medium": 5, "low": 3, "nonAi": 4 }],
"weeklyBreakdown": { "periods": [...], "teams": [{ "teamId": "...", "members": [{ "name": "Dev", "email": "dev@co.com", "isManager": false, "metrics": { "activeDays": [4, 5], "requests": [200, 250], "cost": [10.5, 12.0], "aiCodeShare": [35.0, 38.0] } }] }] }
}
}GET /dev-productivity/team-performance
Returns team summary and per-employee weekly metrics.
Query Parameters: startDate, endDate, managerEmail.
Response:
{
"success": true,
"data": {
"teamSummary": {
"aiCodeSharePct": 35.2, "aiCodeSharePctChange": 5.0,
"aiUsageTiers": { "heavy": 5, "medium": 8, "low": 3, "nonAi": 4 },
"cavTotal": 12.5, "cavTotalChange": 8.0,
"avgCycleTimeMs": 28800000, "avgCycleTimeMsChange": -10.0,
"innovationRate": 65.0, "innovationRateChange": 4.0,
"codeTurnover30d": 0.12, "codeTurnover30dChange": -5.0,
"totalCostUsd": 450.00, "totalCostUsdChange": 15.0
},
"byEmployee": [{
"email": "dev@co.com", "name": "Dev", "role": "Senior Engineer", "isManager": false,
"aiCodingAdoptionPct": 80.0, "cavPerWeek": 15.2, "avgCycleTimeMs": 25200000,
"innovationRate": 70.0, "aiCodeSharePct": 42.0, "aiUsageLevel": "heavy",
"codeTurnover30d": 0.10, "prsMerged": 12, "costUsd": 25.50,
"weeklyMetrics": [{
"eventWeek": "2024-01-01", "cavTotal": 16.0, "cavAi": 7.0, "cavHuman": 9.0,
"prsMerged": 3, "avgCycleTimeMs": 24000000, "featurePct": 72.0,
"codeTurnover30d": 0.09, "aiCodeSharePct": 40.0, "aiUsageLevel": "heavy",
"activeDays": 5, "costUsd": 6.50
}],
"dailyCav": [{ "date": "2024-01-01", "cavTotal": 3.2, "cavAi": 1.5, "cavHuman": 1.7, "prsMerged": 1 }]
}]
}
}GET /dev-productivity/reports/org
Query Parameters: type (optional, default: ENGINEERING; values: GENERAL, ENGINEERING).
Response: Returns the latest organization-level engineering report object.
GET /dev-productivity/reports/employee
Query Parameters: email (required), type (optional, default: ENGINEERING).
Response: Returns the latest employee-level engineering report object.
GET /dev-productivity/reports/employees
Query Parameters: type (optional), page, limit, search.
Response: Returns paginated list of latest employee reports.
GET /dev-productivity/managers
No query parameters.
Response:
{
"success": true,
"data": {
"managers": [
{ "email": "manager@co.com", "name": "Jane Doe", "reportCount": 12 }
]
}
}GET /dev-productivity/reliability
Query Parameters: startDate, endDate, managerEmail.
Response: Returns system reliability metrics for the organization.
GET /dev-productivity/departments
Query Parameters: startDate, endDate.
Response: Returns department-level aggregate metrics.
GET /dev-productivity/delivery
Query Parameters: startDate, endDate, managerEmail.
Response: Returns delivery cadence metrics.
GET /dev-productivity/service-mappings
Response: Returns service/codebase mapping configuration.
GET /dev-productivity/workgraph
Query Parameters: startDate, endDate, managerEmail.
Response: Returns work dependency graph data.
6. Workflow Intelligence
Workflow endpoints analyze clustered workflows, friction, and AI impact across four-week (or weekly) periods.
Period selection differs from other sections: these endpoints use periodStart / periodEnd (not startDate / endDate). Periods must be week-aligned:
periodStartmust be a Monday,periodEndmust be a Sundayweeklygranularity requires exactly 7 days;four-weeklyrequires exactly 28 days- Supported
granularityvalues:weekly,four-weekly(some endpoints acceptfour-weeklyonly)
Use GET /workflow/completed-periods to discover valid periods.
GET /workflow/overview
Returns organization-level (or reporting-group–scoped) workflow friction and AI-clustering summary.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodStart | string | Yes | - | YYYY-MM-DD (Monday) |
periodEnd | string | Yes | - | YYYY-MM-DD (Sunday) |
granularity | string | Yes | - | weekly or four-weekly |
reportingGroupId | string | No | - | Scope to a reporting group |
Response:
{
"success": true,
"data": {
"avgFrictionScore": 72.5,
"avgFrictionScoreChangePct": -2.3,
"aiClusteredWorkflowsCount": 145,
"clusteredWorkflowsCount": 289,
"aiClusteredWorkflowsPct": 50.17,
"aiClusteredWorkflowsPctChangePct": 3.8,
"highFrictionClusteredWorkflowsCount": 42,
"estimatedTimeSaved": 2850.5,
"highFrictionToolsCount": 8,
"highFrictionToolsCountChangePct": 1.2,
"newClusteredWorkflowsCount": 12,
"improvedClusteredWorkflowsCount": 23,
"worsenedClusteredWorkflowsCount": 5
}
}
newClusteredWorkflowsCount,improvedClusteredWorkflowsCount, andworsenedClusteredWorkflowsCountare only present forgranularity=four-weekly.
GET /workflow/completed-periods
Returns the most recent four-week periods that have completed workflow data. Use these as valid periodStart/periodEnd values for the other workflow endpoints.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
granularity | string | Yes | - | Must be four-weekly |
numPeriods | number | No | 3 | Number of periods to return (1-10) |
Response:
{
"success": true,
"data": {
"granularity": "four-weekly",
"availablePeriods": [
{ "periodStart": "2026-05-25", "periodEnd": "2026-06-21" },
{ "periodStart": "2026-04-27", "periodEnd": "2026-05-24" },
{ "periodStart": "2026-03-30", "periodEnd": "2026-04-26" }
]
}
}GET /workflow/workflows
Returns a paginated breakdown of clustered workflows for a four-week period, sorted and filterable.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodStart | string | Yes | - | YYYY-MM-DD (Monday) |
periodEnd | string | Yes | - | YYYY-MM-DD (Sunday, 28 days) |
reportingGroupId | string | No | - | Scope to a reporting group |
toolIds | string | No | - | Comma-separated tool IDs; matches workflows using any of them |
category | string | No | - | Filter by workflow category |
query | string | No | - | Case-insensitive search on workflow name |
sortBy | string | No | frictionIndex | frictionIndex, totalRuns, avgRunTime, userCount, priorityScore |
sortOrder | string | No | desc | asc or desc |
page | number | No | 1 | Page number (min: 1) |
limit | number | No | 20 | Results per page (max: 100) |
Response:
{
"success": true,
"data": {
"workflows": [
{
"workflowId": "wf-123",
"canonicalName": "Expense Report Submission",
"description": "Process for submitting expense reports",
"frictionIndex": 75,
"frictionScoreChangePct": -4.2,
"isAiAutomatable": true,
"totalRuns": 100,
"avgRunTimeSeconds": 300,
"userCount": 12,
"priorityScore": 85,
"estimatedTimeSavedMinutes": 10,
"aiRuns": 40,
"nonAiRuns": 60,
"avgAiActiveSeconds": 250,
"avgNonAiActiveSeconds": 350,
"category": "core_work",
"topOutcome": "success",
"verdict": "Ai Helps"
}
],
"total": 42,
"page": 1,
"limit": 20
}
}
verdictis one ofAi Helps,Ai Hurts, orUnclear(the latter covers equal AI/non-AI friction or insufficient data).
GET /workflow/workflows/:workflowId
Returns detailed metrics, recommendations, and the step sequence for a single workflow. Returns 404 if the workflow does not exist in the given period.
Path Parameters: workflowId (string, required)
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodStart | string | Yes | - | YYYY-MM-DD (Monday) |
periodEnd | string | Yes | - | YYYY-MM-DD (Sunday, 28 days) |
Response:
{
"success": true,
"data": {
"workflowId": "wf-123",
"canonicalName": "Expense Report Submission",
"description": "Process for submitting expense reports",
"category": "core_work",
"isAiAutomatable": true,
"metrics": {
"frictionScore": 0.75,
"frictionSeverity": "high",
"frictionType": "manual_data_entry",
"avgActiveSeconds": 300,
"userCount": 12,
"totalRuns": 100,
"aiRuns": 40,
"nonAiRuns": 60,
"aiUsage": 40.0,
"automatableScore": 0.8,
"avgAiActiveSeconds": 250,
"avgAiFrictionScore": 0.5,
"avgNonAiActiveSeconds": 350,
"avgNonAiFrictionScore": 0.9
},
"recommendations": {
"commonChallenges": ["Manual data entry", "Receipt upload issues"],
"rootCause": "Too many manual steps",
"idealState": "Automated OCR-based capture",
"gapAnalysis": "No OCR integration today",
"intervention": "Implement OCR for receipts"
},
"sequences": {
"steps": [
{ "stepIndex": 0, "stepAction": "Open form", "toolId": "tool-1", "toolName": "Excel", "frictionTypes": ["manual_data_entry"] }
],
"frictionTypeStats": [ { "frictionType": "manual_data_entry", "stepCount": 1 } ],
"primaryToolStats": [ { "toolId": "tool-1", "toolName": "Excel", "domain": "excel.com", "totalActiveSeconds": 1200 } ],
"additionalToolStats": [ { "toolId": "tool-2", "toolName": "Slack", "domain": "slack.com", "totalActiveSeconds": 300 } ]
}
}
}GET /workflow/recommendations
Returns a paginated list of workflow improvement recommendations, ordered by priority.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodStart | string | Yes | - | YYYY-MM-DD (Monday) |
periodEnd | string | Yes | - | YYYY-MM-DD (Sunday) |
granularity | string | Yes | - | weekly or four-weekly |
reportingGroupId | string | No | - | Scope to a reporting group |
page | number | No | 1 | Page number (min: 1) |
limit | number | No | 20 | Results per page (max: 100) |
Response:
{
"success": true,
"data": {
"recommendations": [
{
"workflowId": "wf-0892",
"canonicalName": "Generate Weekly Report",
"interventionType": "batching",
"intervention": "Consolidate manual report steps into a daily batch job",
"rationale": "Reduces context switching and improves consistency",
"estimatedTimeSaved": 480.5,
"avgActiveSeconds": 1245,
"priorityScore": 92.3,
"commonChallenges": ["Multiple data sources", "Manual formatting"]
}
],
"total": 24,
"page": 1,
"limit": 20
}
}GET /workflow/reporting-groups
Returns a paginated, sortable breakdown of workflow friction metrics per reporting group.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodStart | string | Yes | - | YYYY-MM-DD (Monday) |
periodEnd | string | Yes | - | YYYY-MM-DD (Sunday) |
granularity | string | Yes | - | weekly or four-weekly |
query | string | No | - | Search by reporting group name |
sortBy | string | No | avgFrictionScore | avgFrictionScore, clusteredWorkflowsCount, highFrictionClusteredWorkflowsCount, estimatedTimeSaved |
sortOrder | string | No | desc | asc or desc |
page | number | No | 1 | Page number (min: 1) |
limit | number | No | 20 | Results per page (max: 100) |
Response:
{
"success": true,
"data": {
"groups": [
{
"reportingGroupId": "rg-001",
"reportingGroupName": "Engineering Team",
"avgFrictionScore": 68.3,
"avgFrictionScoreChangePct": -1.5,
"clusteredWorkflowsCount": 87,
"highFrictionClusteredWorkflowsCount": 12,
"estimatedTimeSaved": 1420.75
}
],
"total": 12,
"page": 1,
"limit": 20
}
}GET /workflow/ai/breakdown
Returns AI vs. non-AI clustered-workflow counts and AI-impact verdict tallies (helps / hurts / neutral).
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodStart | string | Yes | - | YYYY-MM-DD (Monday) |
periodEnd | string | Yes | - | YYYY-MM-DD (Sunday, 28 days) |
granularity | string | Yes | - | Must be four-weekly |
reportingGroupId | string | No | - | Scope to a reporting group |
Response:
{
"success": true,
"data": {
"metrics": {
"aiClusteredWorkflowCount": 2450,
"aiClusteredWorkflowChangePct": 12.5,
"aiClusteredWorkflowRunCount": 3680,
"aiClusteredWorkflowPct": 65.3,
"aiClusteredWorkflowPctChangePct": 3.2,
"nonAiClusteredWorkflowCount": 1300,
"nonAiClusteredWorkflowChangePct": -8.1,
"nonAiClusteredWorkflowRunCount": 1950,
"aiHelpsWorkflowCount": 1890,
"aiHelpsWorkflowChangePct": 15.3,
"aiHurtsWorkflowCount": 340,
"aiHurtsWorkflowChangePct": -5.2,
"aiNeutralWorkflowCount": 220,
"aiNeutralWorkflowChangePct": 0.0
}
}
}GET /workflow/ai/category-outcome-breakdown
Returns workflow outcome distribution by category, split into AI-assisted vs. non-AI cohorts.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodStart | string | Yes | - | YYYY-MM-DD (Monday) |
periodEnd | string | Yes | - | YYYY-MM-DD (Sunday, 28 days) |
granularity | string | Yes | - | Must be four-weekly |
reportingGroupId | string | No | - | Scope to a reporting group |
category | string | No | - | Filter to a single workflow category |
Response:
{
"success": true,
"data": {
"outcomes_with_ai": {
"total_clustered_workflow_count": 850,
"outcomes": [
{ "category": "email_drafting", "outcome": "helped", "runCount": 520, "clusteredWorkflowCount": 480, "percentage": 56.47 },
{ "category": "email_drafting", "outcome": "neutral", "runCount": 185, "clusteredWorkflowCount": 170, "percentage": 20.0 }
]
},
"outcomes_without_ai": {
"total_clustered_workflow_count": 620,
"outcomes": [
{ "category": "email_drafting", "outcome": "completed", "runCount": 620, "clusteredWorkflowCount": 620, "percentage": 100.0 }
]
}
}
}Tool Analysis
Per-tool workflow friction and impact. All endpoints accept periodStart, periodEnd, granularity (weekly or four-weekly), and optional reportingGroupId. Change-percentage fields are null for weekly granularity.
GET /workflow/tools/overview
Returns a summary of tool usage and friction across all tools.
Query Parameters: periodStart, periodEnd, granularity (required); reportingGroupId (optional).
Response:
{
"success": true,
"data": {
"totalTools": 42,
"totalRawWorkflowCount": 1250,
"highestFrictionTool": "Slack",
"highestFrictionToolScore": 0.87,
"mostUsedTool": "Microsoft Teams",
"mostUsedToolActiveSeconds": 45230,
"highFrictionToolCount": 8
}
}GET /workflow/tools/search
Returns a paginated, sortable, searchable list of tools.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodStart | string | Yes | - | YYYY-MM-DD (Monday) |
periodEnd | string | Yes | - | YYYY-MM-DD (Sunday) |
granularity | string | Yes | - | weekly or four-weekly |
reportingGroupId | string | No | - | Scope to a reporting group |
query | string | No | - | Case-insensitive search on tool name |
sortBy | string | No | totalActiveSeconds | frictionScore, totalActiveSeconds, occurrenceCount, clusteredWorkflowCount |
sortOrder | string | No | desc | asc or desc |
page | number | No | 1 | Page number (min: 1) |
limit | number | No | 20 | Results per page (max: 100) |
Response:
{
"success": true,
"data": {
"tools": [
{
"toolId": "tool-123",
"toolName": "Slack",
"frictionScore": 0.65,
"frictionScoreChangePct": 5.2,
"totalActiveSeconds": 15420,
"occurrenceCount": 245,
"clusteredWorkflowCount": 18,
"clusteredWorkflowCountWithHighFriction": 6
}
],
"total": 47,
"page": 1,
"limit": 20
}
}GET /workflow/tools/:toolId
Returns detailed metrics for a single tool.
Path Parameters: toolId (string, required)
Query Parameters: periodStart, periodEnd, granularity (required); reportingGroupId (optional).
Response:
{
"success": true,
"data": {
"toolId": "tool-123",
"toolName": "Slack",
"frictionScore": 0.65,
"frictionScoreChangePct": 5.2,
"totalActiveSeconds": 15420,
"totalActiveSecondsChangePct": 3.8,
"occurrenceCount": 245,
"occurrenceCountChangePct": -1.5,
"rawWorkflowCount": 52,
"rawWorkflowCountChangePct": 8.3,
"reportingGroupsCount": 7
}
}GET /workflow/tools/:toolId/verdict
Returns the AI-impact verdict and recommendation for a tool.
Path Parameters: toolId (string, required)
Query Parameters: periodStart, periodEnd, granularity (required); reportingGroupId (optional).
Response:
{
"success": true,
"data": {
"friction": "high",
"recommendation": "Consider optimizing integration points or evaluating alternatives"
}
}GET /workflow/tools/:toolId/category-outcome
Returns workflow outcome distribution for workflows that use the tool vs. those that do not.
Path Parameters: toolId (string, required)
Query Parameters: periodStart, periodEnd, granularity (required); reportingGroupId, category (optional).
Response:
{
"success": true,
"data": {
"outcomesWithTool": {
"totalRawWorkflowCount": 120,
"outcomes": [
{ "outcome": "successful", "rawWorkflowCount": 102, "percentage": 85.0 },
{ "outcome": "failed", "rawWorkflowCount": 18, "percentage": 15.0 }
]
},
"outcomesWithoutTool": {
"totalRawWorkflowCount": 85,
"outcomes": [
{ "outcome": "successful", "rawWorkflowCount": 68, "percentage": 80.0 },
{ "outcome": "failed", "rawWorkflowCount": 17, "percentage": 20.0 }
]
}
}
}GET /workflow/tools/:toolId/frictions
Returns friction-type tallies for workflows that use the tool vs. those that do not.
Path Parameters: toolId (string, required)
Query Parameters: periodStart, periodEnd, granularity (required); reportingGroupId (optional).
Response:
{
"success": true,
"data": {
"frictionsWithTool": [
{ "frictionType": "timeout", "rawWorkflowCount": 23, "occurrenceCount": 45 },
{ "frictionType": "authentication_error", "rawWorkflowCount": 12, "occurrenceCount": 18 }
],
"frictionsWithoutTool": [
{ "frictionType": "timeout", "rawWorkflowCount": 89, "occurrenceCount": 142 },
{ "frictionType": "authentication_error", "rawWorkflowCount": 34, "occurrenceCount": 52 }
]
}
}GET /workflow/tools/:toolId/workflows
Returns a paginated, sortable list of workflows comparing usage with vs. without the tool.
Path Parameters: toolId (string, required)
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
periodStart | string | Yes | - | YYYY-MM-DD (Monday) |
periodEnd | string | Yes | - | YYYY-MM-DD (Sunday) |
granularity | string | Yes | - | weekly or four-weekly |
reportingGroupId | string | No | - | Scope to a reporting group |
sortBy | string | No | rawWorkflowCountWithTool | rawWorkflowCountWithTool, rawWorkflowCountWithoutTool, avgActiveSecondsWithTool, avgActiveSecondsWithoutTool, avgFrictionScoreWithTool, avgFrictionScoreWithoutTool |
sortOrder | string | No | desc | asc or desc |
page | number | No | 1 | Page number (min: 1) |
limit | number | No | 20 | Results per page (max: 100) |
Response:
{
"success": true,
"data": {
"workflows": [
{
"workflowId": "wf-001",
"canonicalName": "Daily Standup Sync",
"category": "communication",
"rawWorkflowCountWithTool": 45,
"rawWorkflowCountWithoutTool": 28,
"avgActiveSecondsWithTool": 180.5,
"avgActiveSecondsWithoutTool": 245.2,
"avgFrictionScoreWithTool": 0.35,
"avgFrictionScoreWithoutTool": 0.62
}
],
"total": 18,
"page": 1,
"limit": 20
}
}7. Common Patterns
Date Validation
- Format:
YYYY-MM-DD startDatemust be <=endDatestartDatecannot be > 1 day in the future
Pagination
{ "data": [...], "total": 50, "page": 1, "limit": 10 }Array Parameters
Use bracket notation: ?department[]=dept1&department[]=dept2
Granularity Options
| Value | Description |
|---|---|
daily | Per-day aggregation |
weekly | Per-week (Monday start) |
biweekly | Two-week periods |
four-weekly | Four consecutive completed weeks (rolling) |
monthly | Calendar month |
twelve-weekly | Twelve consecutive completed weeks (rolling) |
Error Codes
| Code | Description |
|---|---|
| 400 | Bad Request (validation failure, invalid parameters) |
| 401 | Unauthorized (missing/invalid authentication) |
| 404 | Not Found (resource does not exist) |
| 500 | Internal Server Error |
Null vs. Missing Fields
- Fields with
nullindicate the metric is available but has no data for the period - Missing/absent fields indicate the metric is not applicable for the given parameters (e.g., WAU metrics don’t appear with daily granularity)
*Change/*ChangePctfields arenullwhen there is no prior period to compare against