Skip to main content
All endpoints require a valid Bearer token. State-mutating requests must include a csrf_token — obtain one from GET /api/security/csrf-token.

Activity Feed

Get filtered activity

GET /api/analytics/filtered-activity Returns a filtered activity feed of user events for the authenticated user. Use this endpoint to build audit views or personal activity streams. Required permission: api.analytics.filtered_activity.view
type
string
default:"all"
Filter by activity category: all, page_visits, or actions.
curl -X GET "https://propops.yourcompany.com/api/analytics/filtered-activity?type=page_visits" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "activities": [
    {
      "activity_type": "page_visit",
      "activity_details": "{\"page\":\"/jobs\",\"title\":\"Jobs\"}",
      "created_at": "2024-06-01T09:00:00Z",
      "ip_address": "203.0.113.1",
      "parsed_details": { "page": "/jobs", "title": "Jobs" },
      "display_title": "Page Visit: /jobs (Jobs)"
    }
  ],
  "count": 1,
  "filter": "page_visits"
}

AI Analysis

PropOps integrates with Google Gemini to provide AI-assisted analysis of job health, branch performance, and financial data.

Trigger AI analysis

POST /api/analytics/ai-analysis Initiates a Gemini AI analysis. This is the only method — there is no GET variant. Required permission: api.analytics.ai_analysis
analysis_type
string
required
Type of analysis to trigger:
  • quick_insights — Fast overview of key metrics and anomalies
  • performance_deep_dive — In-depth performance analysis
  • cost_optimization — Cost and spend optimisation recommendations
  • branch_comparison — Cross-branch comparison
  • predictive_trends — Forward-looking trend predictions
focus_area
string
Optional scope for the analysis: jobs, branches, financial, or operational.
time_period
string
default:"30days"
Period for analysis: 7days, 30days, 90days, 6months, 1year.
branch_ids
array
Optional array of branch IDs to scope the analysis. Omit for platform-wide analysis.
include_recommendations
boolean
default:"true"
Include AI-generated recommendations in the response.
user_query
string
Optional natural language question to guide the analysis.
csrf_token
string
required
CSRF token.
curl -X POST "https://propops.yourcompany.com/api/analytics/ai-analysis" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"analysis_type":"quick_insights","time_period":"30days","csrf_token":"<csrf-token>"}'
{
  "success": true,
  "message": "Analysis triggered successfully."
}

Gemini Usage

This endpoint is restricted to admin accounts only. It provides visibility into AI token consumption for cost management and quota monitoring.

Get Gemini token usage

GET /api/analytics/gemini-usage Returns token consumption statistics and API call counts for the Gemini integration, broken down by day for the last 30 days. Required permission: api.analytics.gemini_usage (admin only)
curl -X GET "https://propops.yourcompany.com/api/analytics/gemini-usage" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "usage": {
    "total_credits_used": 284500,
    "total_sessions": 42,
    "total_messages": 186,
    "calls_today": 8,
    "daily_usage": [
      {
        "date": "2024-06-01",
        "api_calls": 8,
        "credits": 12400
      },
      {
        "date": "2024-06-02",
        "api_calls": 5,
        "credits": 8200
      }
    ]
  },
  "limits": {
    "requests_per_minute": 15,
    "requests_per_day": 1500,
    "tokens_per_minute": 1000000,
    "requests_per_month": 45000
  },
  "remaining": {
    "today": 1492,
    "percentage_used": 0.53
  },
  "rate_limited": false
}

Reports

Financial report

GET /api/reports/financial Returns job-level financial data grouped by branch, suitable for accountancy review and AI-assisted report generation. Required permission: page.reports.financial
Optional search string filtered against branch name, address, job ref, and job title.
curl -X GET "https://propops.yourcompany.com/api/reports/financial" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "groups": [
    {
      "branch_id": 1,
      "branch_uuid": "abc-123",
      "branch_name": "London North",
      "branch_city": "London",
      "job_count": 2,
      "agent_amount_total": 500.00,
      "contractor_amount_total": 360.00,
      "inhouse_amount_total": 140.00,
      "client_paid_total": 500.00,
      "agent_paid_total": 140.00,
      "contractor_paid_total": 360.00,
      "inhouse_paid_total": 140.00,
      "jobs": [
        {
          "job_id": 1,
          "job_uuid": "def-456",
          "job_ref": "JOB-001",
          "job_title": "Boiler Service - Unit 001",
          "from_name": "Agent Name",
          "contractor_name": "Contractor_001",
          "agent_amount": 250.00,
          "contractor_amount": 180.00,
          "inhouse_amount": 70.00,
          "client_paid": 250.00,
          "agent_paid": 70.00,
          "contractor_paid": 180.00,
          "inhouse_paid": 70.00,
          "payment_status_id": 2,
          "payment_status_name": "Paid",
          "created_on": "2024-06-02"
        }
      ]
    }
  ],
  "totals": {
    "branch_count": 1,
    "job_count": 2,
    "agent_amount_total": 500.00,
    "contractor_amount_total": 360.00,
    "inhouse_amount_total": 140.00,
    "client_paid_total": 500.00,
    "agent_paid_total": 140.00,
    "contractor_paid_total": 360.00,
    "inhouse_paid_total": 140.00
  },
  "filters": {
    "search": ""
  }
}

User report

GET /api/reports/users Returns user activity and account data for administrative reporting. Required permission: page.reports.users
page
integer
default:"1"
Detail table page number.
limit
integer
default:"25"
Detail table page size (max 100).
search
string
Optional search against staff name, email, job ref, and job title.
user_id
integer
Optional filter by staff account ID.
curl -X GET "https://propops.yourcompany.com/api/reports/users" \
  -H "Authorization: Bearer <token>"

Branch Performance

Get branch performance metrics

GET /api/analytics/branch-performance Returns performance scores, rankings, and KPI data for all branches. Supports four views: all branches, top performers, branches needing attention, and side-by-side comparison. Required permission: api.analytics.branch_performance
Account types: Staff only
action
string
default:"all"
View to return: all, top, attention, or compare.
limit
integer
default:"5"
Maximum branches to return for the top action.
branch_1
integer
First branch ID for the compare action.
branch_2
integer
Second branch ID for the compare action.
start_date
string
Start of the metrics window (YYYY-MM-DD). Defaults to 90 days ago.
end_date
string
End of the metrics window (YYYY-MM-DD). Defaults to today.
curl -X GET "https://propops.yourcompany.com/api/analytics/branch-performance?action=top&limit=3" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": [
    {
      "branch_id": 2,
      "branch_name": "London South",
      "performance_score": 94.2,
      "rank": 1,
      "jobs_completed": 87,
      "sla_compliance_percent": 96.5,
      "avg_resolution_hours": 22.1,
      "recall_rate_percent": 1.1
    },
    {
      "branch_id": 5,
      "branch_name": "Manchester Central",
      "performance_score": 91.7,
      "rank": 2,
      "jobs_completed": 63,
      "sla_compliance_percent": 93.0,
      "avg_resolution_hours": 28.4,
      "recall_rate_percent": 1.6
    }
  ],
  "message": "Operation completed successfully"
}

Compare two branches

GET /api/analytics/branch-performance?action=compare&branch_1=2&branch_2=5 Returns a side-by-side KPI comparison for exactly two branches.
curl -X GET "https://propops.yourcompany.com/api/analytics/branch-performance?action=compare&branch_1=2&branch_2=5" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": {
    "branch_1": {
      "branch_id": 2,
      "branch_name": "London South",
      "performance_score": 94.2,
      "sla_compliance_percent": 96.5,
      "avg_resolution_hours": 22.1
    },
    "branch_2": {
      "branch_id": 5,
      "branch_name": "Manchester Central",
      "performance_score": 91.7,
      "sla_compliance_percent": 93.0,
      "avg_resolution_hours": 28.4
    }
  },
  "message": "Operation completed successfully"
}

Job Health Check

Get problematic jobs

GET /api/analytics/job-health-check Automatically detects problematic jobs across eight categories: stuck new orders, overdue quotes, stale quoted jobs, long-running jobs, high cost jobs, cost overrun jobs, missing contractors, and missing certificates. Results help identify jobs that need immediate action. Required permission: api.analytics.job_health_check
Account types: Staff only
category
string
default:"all"
Filter to a single category. One of: stuck_new_orders, overdue_quotes, stale_quoted_jobs, long_running_jobs, high_cost_jobs, cost_overrun_jobs, missing_contractors, missing_certificates.
curl -X GET "https://propops.yourcompany.com/api/analytics/job-health-check" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": {
    "stuck_new_orders": [
      {
        "ID": 1032,
        "uuid": "550e8400-e29b-41d4-a716-446655441032",
        "job_ref": "JOB-1032",
        "job_title": "Roof leak repair",
        "days_stuck": 5,
        "branch_name": "London North"
      }
    ],
    "missing_contractors": [
      {
        "ID": 1044,
        "uuid": "550e8400-e29b-41d4-a716-446655441044",
        "job_ref": "JOB-1044",
        "job_title": "Boiler fault",
        "priority_name": "High",
        "days_open": 3
      }
    ]
  },
  "summary": {
    "total_issues": 8,
    "categories": {
      "stuck_new_orders": 1,
      "missing_contractors": 2,
      "overdue_quotes": 3,
      "missing_certificates": 2
    }
  },
  "message": "Operation completed successfully"
}

Recent Activity

Get recent system activity

GET /api/analytics/recent-activity Returns a feed of the most recent user and system events — useful for dashboard activity widgets and live audit trails. Required permission: api.analytics.recent_activity.manage
Account types: Staff only
limit
integer
default:"50"
Number of recent activity items to return (max 100).
job_uuid
string
Filter activities related to a specific job UUID.
curl -X GET "https://propops.yourcompany.com/api/analytics/recent-activity?limit=10" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": {
    "activities": [
      {
        "activity_type": "page_visit",
        "created_at": "2024-06-14T10:12:00Z",
        "user_name": "Jane Smith",
        "action": "Page Visit",
        "summary": "/jobs",
        "page": "/jobs"
      }
    ],
    "total": 1,
    "filters": { "job_uuid": null, "limit": 50 }
  },
  "activities": [...],
  "count": 1
}

Page Tracking

Track a page view

POST /api/analytics/page-tracking Records a page view event for the authenticated user. Called automatically by the browser client on every navigation. Not intended for direct integration use. Required permission: api.analytics.page_tracking.view
action
string
required
Tracking type: page_visit or user_action.
page
string
required
The page path being tracked (e.g. /jobs). Required for page_visit.
title
string
Page title. Used with page_visit.
referrer
string
Referrer URL. Used with page_visit.
action_type
string
Client-side action type. Required for user_action (e.g. button_interaction, form_submission).
curl -X POST "https://propops.yourcompany.com/api/analytics/page-tracking" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"action": "page_visit", "page": "/jobs", "title": "Jobs"}'
{
  "success": true
}

AI Chat Sessions

List chat sessions

GET /api/analytics/chat-sessions Returns all AI chat sessions belonging to the authenticated user, ordered by most recently updated. Each session groups a conversation thread with the Gemini AI assistant. Required permission: api.analytics.chat_sessions
curl -X GET "https://propops.yourcompany.com/api/analytics/chat-sessions" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "sessions": [
    {
      "id": "a3f1...",
      "session_name": "Job health analysis – June 2024",
      "message_count": 8,
      "total_credits": 12400,
      "is_active": true,
      "created_at": "2024-06-10T09:00:00Z",
      "updated_at": "2024-06-14T11:30:00Z"
    }
  ]
}

Create a chat session

POST /api/analytics/chat-sessions Creates a new AI chat session for the authenticated user. Required permission: api.analytics.chat_sessions
Requires CSRF token.
session_name
string
Display name for the session (e.g. “Branch performance review Q2”). Defaults to New Chat.
csrf_token
string
required
CSRF token from GET /api/security/csrf-token.
curl -X POST "https://propops.yourcompany.com/api/analytics/chat-sessions" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"session_name": "Branch performance review Q2", "csrf_token": "<csrf-token>"}'
{
  "success": true,
  "session_id": "a3f1c8...",
  "message": "New chat session created"
}

Update a chat session

PUT /api/analytics/chat-sessions Updates the display name or active state of an existing chat session. Required permission: api.analytics.chat_sessions
Requires CSRF token.
session_id
string
required
ID of the session to update.
session_name
string
New display name (optional).
is_active
boolean
Set to true to make this the active session (deactivates all others).
csrf_token
string
required
CSRF token.

AI Chat Messages

Get messages for a session

GET /api/analytics/chat-messages?session_id=<id> Returns all messages in a specific AI chat session. Only the owner of the session can retrieve its messages. Required permission: api.analytics.chat_messages
session_id
string
required
ID of the chat session.
curl -X GET "https://propops.yourcompany.com/api/analytics/chat-messages?session_id=14" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "messages": [
    {
      "id": "a1b2...",
      "role": "user",
      "content": "How many jobs are overdue in London South this month?",
      "credits_used": 0,
      "created_at": "2024-06-14T11:00:00Z"
    },
    {
      "id": "c3d4...",
      "role": "assistant",
      "content": "London South currently has 4 overdue jobs this month...",
      "credits_used": 820,
      "created_at": "2024-06-14T11:00:05Z"
    }
  ]
}

Save a message

POST /api/analytics/chat-messages Saves a message to a chat session. Both user and assistant messages are stored this way. Required permission: api.analytics.chat_messages
session_id
string
required
ID of the chat session.
role
string
required
Message role: user or assistant.
content
string
required
Message text content.
credits_used
integer
default:"0"
Credits consumed by this message (applies to assistant messages).
curl -X POST "https://propops.yourcompany.com/api/analytics/chat-messages" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "a3f1c8...",
    "role": "user",
    "content": "Which contractor has the highest recall rate this quarter?"
  }'
{
  "success": true,
  "message_id": "b7e2..."
}

Dashboard & System

Dashboard aggregate stats, chiplets, charts, and job-feed endpoints are documented in the Dashboard API. System health, heartbeat, and maintenance-mode endpoints are documented in the System API.