Skip to main content
All dashboard endpoints require a valid Bearer token. Most are restricted to Staff and Agent account types; endpoints noted otherwise are more broadly accessible.

Stats

Overall dashboard stats

GET /api/dashboard/stats Returns aggregate counts for the dashboard sidebar stats card — accepted jobs, recalls, revenue, and new jobs today. Required permission: api.dashboard.stats.manage
Account types: Staff only
curl -X GET "https://propops.yourcompany.com/api/dashboard/stats" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": {
    "accepted": {
      "count": 142,
      "total": 48500.00,
      "formatted_total": "£48,500.00"
    },
    "recall": {
      "count": 7
    },
    "new_jobs": {
      "count": 12
    },
    "timestamp": "2024-06-14T08:22:00+00:00"
  }
}

Chiplets count

GET /api/dashboard/chiplets-count Returns counts for the configurable dashboard chiplets (mini-stat cards). Each entry includes a count and an available flag indicating whether the calling user has permission to view that chiplet. Required permission: api.dashboard.chiplets
Account types: Staff, Agent
curl -X GET "https://propops.yourcompany.com/api/dashboard/chiplets-count" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": {
    "amendment_requests": { "count": 5, "available": true },
    "overdue_jobs": { "count": 3, "available": true },
    "overdue_certs": { "count": 2, "available": true },
    "incomplete_onboarding": { "count": 4, "available": true }
  },
  "timestamp": "2024-06-14T08:22:00+00:00"
}

SecOps chiplets

GET /api/dashboard/secops-chiplets Returns security-focused chiplet counts for Staff users with security dashboard access. Required permission: api.dashboard.secops_chiplets.read
Account types: Staff only
curl -X GET "https://propops.yourcompany.com/api/dashboard/secops-chiplets" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": {
    "open_security_alerts": 3,
    "failed_logins_24h": 14,
    "active_sessions": 27,
    "file_integrity_violations": 1
  }
}

Charts

Dashboard charts

GET /api/dashboard/charts Returns time-series data for the dashboard chart panel — new jobs, accepted jobs, and overdue invoices over the last 7 days. Required permission: api.dashboard.charts.manage
curl -X GET "https://propops.yourcompany.com/api/dashboard/charts" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": {
    "new_jobs": {
      "total_today": 4,
      "trend": [
        { "date": "2024-06-08", "label": "Sat", "count": 2 },
        { "date": "2024-06-09", "label": "Sun", "count": 0 }
      ]
    },
    "accepted_jobs": {
      "total_active": 142,
      "trend": [
        { "date": "2024-06-08", "label": "Sat", "count": 3 },
        { "date": "2024-06-09", "label": "Sun", "count": 1 }
      ]
    },
    "overdue_invoices": {
      "total": 7,
      "test_data_count": 0,
      "trend": [
        { "date": "2024-06-08", "label": "Sat", "count": 1 },
        { "date": "2024-06-09", "label": "Sun", "count": 0 }
      ]
    }
  },
  "timestamp": "2024-06-14T08:22:00+00:00"
}

Jobs by type

GET /api/dashboard/jobs-by-type Returns a breakdown of job counts grouped by job type — useful for pie or bar charts. Required permission: api.dashboard.jobs_by_type.read
curl -X GET "https://propops.yourcompany.com/api/dashboard/jobs-by-type" \
  -H "Authorization: Bearer <token>"
type
string
Filter to a specific job type name.
status
string
Filter to a specific job status name.
Search term to filter jobs.
search_scope
string
default:"all"
Scope of the search field.
search_mode
string
default:"like"
Search matching mode.
{
  "success": true,
  "data": [
    { "job_type": "Plumbing", "count": 42 },
    { "job_type": "Electrical", "count": 31 },
    { "job_type": "Gas & Heating", "count": 27 },
    { "job_type": "General Maintenance", "count": 19 }
  ]
}

Job lists

New jobs

GET /api/dashboard/new-jobs Returns a list of jobs created within the last 24 hours for the dashboard feed. Required permission: api.dashboard.new_jobs.read
curl -X GET "https://propops.yourcompany.com/api/dashboard/new-jobs" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": [
    {
      "ID": 1050,
      "uuid": "b4a3c2d1-e0f9-4321-abcd-ef0123456789",
      "job_ref": "JOB-1050",
      "job_title": "Leak under kitchen sink",
      "status_name": "Open",
      "priority_name": "High",
      "full_address": "15 Oak Road, Manchester, M1 1AA",
      "contractor_name": null,
      "created_at": "2024-06-14T08:22:00Z"
    }
  ],
  "count": 12
}

Completed jobs

GET /api/dashboard/completed-jobs Returns a list of jobs marked as completed within the last 24 hours. Required permission: api.dashboard.completed_jobs.read
curl -X GET "https://propops.yourcompany.com/api/dashboard/completed-jobs" \
  -H "Authorization: Bearer <token>"

Booked today

GET /api/dashboard/booked-today Returns jobs with a works start date of today. Required permission: api.dashboard.booked_today.read
curl -X GET "https://propops.yourcompany.com/api/dashboard/booked-today" \
  -H "Authorization: Bearer <token>"
overdue
string
Pass true to filter to only overdue booked jobs.

No contractor assigned

GET /api/dashboard/no-contractor Returns open jobs that have not yet had a contractor assigned. Useful for identifying work that needs actioning. Required permission: api.dashboard.no_contractor.read
curl -X GET "https://propops.yourcompany.com/api/dashboard/no-contractor" \
  -H "Authorization: Bearer <token>"

Overdue quotes

GET /api/dashboard/overdue-quotes Returns jobs where a quote has been outstanding beyond the SLA deadline. Required permission: api.dashboard.overdue_quotes.read
curl -X GET "https://propops.yourcompany.com/api/dashboard/overdue-quotes" \
  -H "Authorization: Bearer <token>"

Missing certifications

GET /api/dashboard/missing-certs Returns jobs where the assigned contractor has at least one certification required for the job type that is missing or expired. Required permission: api.dashboard.missing_certs.read
curl -X GET "https://propops.yourcompany.com/api/dashboard/missing-certs" \
  -H "Authorization: Bearer <token>"
days
integer
Only return jobs completed more than this many days ago without a certificate. Omit to return all.

Pinned jobs

GET /api/dashboard/pinned-jobs Returns all jobs pinned by the authenticated user. Required permission: api.dashboard.pinned_jobs.read
curl -X GET "https://propops.yourcompany.com/api/dashboard/pinned-jobs" \
  -H "Authorization: Bearer <token>"
filter
string
default:"my_pins"
Pin filter scope. Defaults to my_pins.
{
  "success": true,
  "data": [
    {
      "ID": 1023,
      "uuid": "abc123...",
      "job_ref": "JOB-1023",
      "job_title": "Roof inspection",
      "status_name": "In Progress",
      "pinned_at": "2024-06-10T11:00:00Z"
    }
  ]
}

Recall jobs

GET /api/dashboard/recall Returns a list of jobs that have been recalled (completed and then reopened). Required permission: api.dashboard.recall.read
curl -X GET "https://propops.yourcompany.com/api/dashboard/recall" \
  -H "Authorization: Bearer <token>"
advanced
string
Pass true to enable advanced mode (larger default page size).
page
integer
default:"1"
Page number for pagination.
limit
integer
Results per page (1–100). Defaults to 5 in standard mode and 20 in advanced mode.

Incomplete onboarding

GET /api/dashboard/incomplete-onboarding Returns a count and list of users who have not yet completed the onboarding wizard. Staff only. Required permission: api.dashboard.incomplete_onboarding.read
Account types: Staff only
curl -X GET "https://propops.yourcompany.com/api/dashboard/incomplete-onboarding" \
  -H "Authorization: Bearer <token>"

Batch requests

Batch dashboard data

GET /api/dashboard/batch Fetches multiple dashboard widgets in a single request, reducing round-trips for the initial page load. Each widget is loaded using its own permission check; widgets the caller lacks permission for are returned with success: false. Required permission: api.dashboard.batch.read
widgets
string
required
Comma-separated list of widget names to fetch (maximum 6). Widget names correspond to the dashboard endpoint filenames: stats, new-jobs, completed-jobs, booked-today, no-contractor, missing-certs, incomplete-onboarding, jobs-by-type, recall, pinned-jobs, overdue-quotes, chiplets-count.
curl -X GET "https://propops.yourcompany.com/api/dashboard/batch?widgets=stats,new-jobs,pinned-jobs" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": {
    "stats": {
      "success": true,
      "data": {
        "accepted": { "count": 142, "total": 48500.00, "formatted_total": "£48,500.00" },
        "recall": { "count": 7 },
        "new_jobs": { "count": 12 }
      },
      "total": 0
    },
    "new-jobs": {
      "success": true,
      "data": [
        { "ID": 1050, "job_ref": "JOB-1050", "job_title": "Leak under kitchen sink" }
      ],
      "total": 12
    }
  },
  "count": 2,
  "timestamp": "2024-06-14T08:22:00+00:00"
}

Update a job from the dashboard

POST /api/dashboard/update-job Performs a quick status or completion-date update on a job directly from the dashboard. Uses a standard HTML form-encoded body (not JSON). Required permission: api.dashboard.update_job.manage
uuid
string
required
Job UUID.
status_id
integer
New status ID to set on the job. At least one of status_id or date_completed must be provided.
date_completed
string
Completion date (YYYY-MM-DD). If provided without status_id, the status is automatically set to 7 (Completed).
silent
string
Pass true to suppress email notifications for this update.
_token
string
required
CSRF token. Obtain from csrf_token() (also accepted as csrf_token).
curl -X POST "https://propops.yourcompany.com/api/dashboard/update-job" \
  -H "Authorization: Bearer <token>" \
  -d "uuid=b4a3c2d1-e0f9-4321-abcd-ef0123456789&status_id=3&_token=<csrf-token>"
{
  "success": true,
  "message": "Job updated successfully"
}