Analytics API
All endpoints require authentication and analytics:view permission. Date range defaults to the last 90 days when from/to are omitted. Dates use YYYY-MM-DD format.
Utilisation
Section titled “Utilisation”Get Utilisation
Section titled “Get Utilisation”GET /api/analytics/utilisationPer-person allocated vs capacity hours over a date range. Capacity is approximated as calendar days x 8 h (no holiday/weekend exclusion). Allocated hours are summed from active allocations overlapping the range.
Query parameters:
| Param | Type | Description |
|---|---|---|
from | string | Start date (default: 90 days ago) |
to | string | End date (default: today) |
squad_id | string | Filter by squad |
user_id | string | Filter by user |
Response: { data, meta }
Each item in data:
| Field | Type | Description |
|---|---|---|
user_id | string | User ID |
name | string | User name |
email | string | User email |
squad | string|null | Squad name |
capacity_hours | number | Total capacity hours in range |
allocated_hours | number | Total allocated hours in range |
utilisation_pct | number | Percentage utilised (0-100+) |
Get Utilisation Trends
Section titled “Get Utilisation Trends”GET /api/analytics/utilisation/trendsWeekly utilisation percentages for sparkline/chart rendering. Each bucket represents a Mon-Sun week.
Query parameters:
| Param | Type | Description |
|---|---|---|
from | string | Start date (default: 90 days ago) |
to | string | End date (default: today) |
squad_id | string | Filter by squad |
Response: { data, meta }
Each item in data:
| Field | Type | Description |
|---|---|---|
week | string | Human-readable week label (e.g. “14 Apr”) |
week_start | string | ISO date of Monday |
week_end | string | ISO date of Sunday |
allocated_hours | number | Total allocated hours that week |
capacity_hours | number | Total capacity hours (active employees x 40h) |
utilisation_pct | number | Percentage utilised |
Deals Pipeline
Section titled “Deals Pipeline”Get Pipeline
Section titled “Get Pipeline”GET /api/analytics/deals/pipelineCurrent pipeline by stage with deal counts, values, and win rate.
Response: { data, summary, meta }
Each item in data:
| Field | Type | Description |
|---|---|---|
stage_id | string | Pipeline stage ID |
stage_name | string | Stage name |
stage_type | string | Stage type |
position | number | Stage position |
deal_count | number | Number of deals in stage |
total_value | number | Sum of estimated budgets |
summary:
| Field | Type | Description |
|---|---|---|
total_deals | number | Total deals across all stages |
total_value | number | Total pipeline value |
win_rate_pct | number | Win rate percentage |
Get Deal Velocity
Section titled “Get Deal Velocity”GET /api/analytics/deals/velocityAverage days from deal creation to close, grouped by stage. Approximated from created_at to actual_close_date.
Query parameters:
| Param | Type | Description |
|---|---|---|
from | string | Start date (default: 90 days ago) |
to | string | End date (default: today) |
Response: { data, meta, _note }
Each item in data:
| Field | Type | Description |
|---|---|---|
stage_name | string | Pipeline stage name |
position | number | Stage position |
deal_count | number | Closed deals in this stage |
avg_days_to_close | number|null | Average days to close |
Recruitment Funnel
Section titled “Recruitment Funnel”Get Funnel
Section titled “Get Funnel”GET /api/analytics/recruitment/funnelCandidate counts by stage for active applications with stage-to-stage conversion rates.
Query parameters:
| Param | Type | Description |
|---|---|---|
job_id | string | Filter by recruitment job |
Response: { data, meta }
Each item in data:
| Field | Type | Description |
|---|---|---|
stage_id | string | Pipeline stage ID |
stage_name | string | Stage name |
stage_type | string | Stage type |
position | number | Stage position |
candidate_count | number | Active candidates in stage |
conversion_rate_pct | number|null | Conversion rate from previous stage |
Get Time to Hire
Section titled “Get Time to Hire”GET /api/analytics/recruitment/time-to-hireAverage days from application to hire, grouped by department.
Query parameters:
| Param | Type | Description |
|---|---|---|
from | string | Start date (default: 90 days ago) |
to | string | End date (default: today) |
department | string | Filter by department |
Response: { data, summary, meta }
Each item in data:
| Field | Type | Description |
|---|---|---|
department | string | Department name |
hired_count | number | Number of hires |
avg_days_to_hire | number|null | Average days to hire |
min_days | number|null | Fastest hire (days) |
max_days | number|null | Slowest hire (days) |
summary:
| Field | Type | Description |
|---|---|---|
total_hired | number | Total hires in range |
avg_days_to_hire | number|null | Overall average |
Get Leave Conflicts
Section titled “Get Leave Conflicts”GET /api/analytics/leave/conflictsOverlapping approved/pending leave within the same squad. Returns up to 200 conflict pairs.
Query parameters:
| Param | Type | Description |
|---|---|---|
from | string | Start date (default: 90 days ago) |
to | string | End date (default: today) |
squad_id | string | Filter by squad |
Response: { data, meta }
Each item in data:
| Field | Type | Description |
|---|---|---|
leave1_id | string | First leave request ID |
person1_name | string | First person’s name |
squad | string | Shared squad |
leave1_type | string | First leave type |
leave1_start | string | First leave start date |
leave1_end | string | First leave end date |
leave2_id | string | Second leave request ID |
person2_name | string | Second person’s name |
leave2_type | string | Second leave type |
leave2_start | string | Second leave start date |
leave2_end | string | Second leave end date |
Get Leave Summary
Section titled “Get Leave Summary”GET /api/analytics/leave/summaryLeave balance and taken summary per active person, grouped by leave type.
Query parameters:
| Param | Type | Description |
|---|---|---|
year | string | Year to filter (default: current year) |
Response: { data, meta }
Each item in data:
| Field | Type | Description |
|---|---|---|
person_id | string | Person ID |
person_name | string | Person’s full name |
squad | string|null | Squad name |
leave_balances | array | Array of { leave_type, balance_hours, entitlement_hours, taken_hours } |
Budget & Finance
Section titled “Budget & Finance”Get Budget Alerts
Section titled “Get Budget Alerts”GET /api/analytics/budget/alertsBudgets approaching or exceeding a spend threshold. Burn percentage is calculated as logged hours / budgeted hours.
Query parameters:
| Param | Type | Description |
|---|---|---|
threshold | number | Alert threshold 0-100 (default: 80) |
Response: { data, meta }
Each item in data:
| Field | Type | Description |
|---|---|---|
budget_id | string | Budget ID |
budget_name | string | Budget name |
resource_type | string | Resource type |
resource_id | string | Resource ID |
total_amount | number|null | Budget amount |
status | string | Budget status |
budgeted_hours | number | Total budgeted hours |
logged_hours | number | Total logged hours |
entry_count | number | Time entry count |
burn_pct | number | Burn percentage |
Get Budget Forecast
Section titled “Get Budget Forecast”GET /api/analytics/budget/forecastProjected hours spend for each budget based on current allocations.
Query parameters:
| Param | Type | Description |
|---|---|---|
from | string | Start date (default: 90 days ago) |
to | string | End date (default: today) |
Response: { data, meta }
Each item in data:
| Field | Type | Description |
|---|---|---|
budget_id | string | Budget ID |
budget_name | string | Budget name |
total_amount | number|null | Budget total |
status | string | Budget status |
forecast_hours | number | Projected hours from allocations |
forecast_vs_budget_pct | number|null | Forecast as percentage of budget |
Retention Signals
Section titled “Retention Signals”Get Retention Signals
Section titled “Get Retention Signals”GET /api/analytics/retention/signalsScored list of retention risk indicators for active employees, sorted by risk score descending.
Signals detected:
no_recent_allocations— no active allocations in the last 90 days (+30 pts)long_tenure_5plus_years— employed 5+ years (+20 pts)
Response: { data, meta }
Each item in data:
| Field | Type | Description |
|---|---|---|
person_id | string | Person ID |
name | string | Person name |
squad | string|null | Squad |
start_date | string|null | Employment start date |
risk_score | number | Composite risk score |
risk_factors | string[] | List of detected risk factor keys |