Skip to main content
System endpoints let you monitor instance health, manage maintenance windows, configure application settings, and inspect system logs. Most endpoints are restricted to Staff users.

Health & heartbeat

Heartbeat

POST /api/system/heartbeat Updates the authenticated user’s last_activity timestamp and returns current system state. Called automatically by the browser client every 60 seconds to maintain the online-users list and keep the session alive.
A GET /api/system/heartbeat?health_check=1 variant is also available without authentication for uptime monitors. It returns a minimal status payload without updating any session state.
Permission: None — all authenticated users
Auth: Session or Bearer token
curl -X POST "https://propops.yourcompany.com/api/system/heartbeat" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "valid": true,
  "message": "Activity updated"
}

System status

GET /api/system/status
POST /api/system/status
Returns online user count, or status for a specific user. Also supports a force_license_check action (Staff only, POST). Required permission: api.system.status.manage
Account types: Staff only
user_id
integer
If provided, returns status details for a specific user (status, last_activity, status_color, status_text).
action
string
POST action. Supported value: force_license_check (Staff only).
curl -X GET "https://propops.yourcompany.com/api/system/status" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "online_users_count": 12
}
Get a specific user’s status (?user_id=42):
{
  "success": true,
  "status": "online",
  "last_activity": "2024-06-14T10:00:00Z",
  "status_color": "#22c55e",
  "status_text": "Online"
}

Maintenance mode

Get maintenance mode status

GET /api/system/maintenance-mode Returns the current maintenance mode state and reason. Available to unauthenticated requests so the login page can detect maintenance windows. Permission: None (public)
curl -X GET "https://propops.yourcompany.com/api/system/maintenance-mode"
{
  "success": true,
  "data": {
    "enabled": false,
    "message": "",
    "staff_only": true
  }
}

Toggle maintenance mode

POST /api/system/maintenance-mode Enables or disables maintenance mode. When enabled, all non-Staff users are shown a maintenance screen. Staff users retain full access. Required permission: api.system.maintenance_mode.manage
Account types: Staff only
Requires CSRF token.
enabled
boolean
required
true to enable maintenance mode, false to disable.
reason
string
Human-readable message shown to users during maintenance (e.g. “Scheduled upgrade”).
csrf_token
string
required
CSRF token from GET /api/security/csrf-token.
curl -X POST "https://propops.yourcompany.com/api/system/maintenance-mode" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "reason": "Applying database upgrade — back in 10 minutes",
    "csrf_token": "<csrf-token>"
  }'
{
  "success": true,
  "message": "Maintenance mode enabled"
}

Settings

Get application settings

GET /api/system/settings Returns the current application configuration (branding, defaults, feature flags). Some settings are redacted for non-Staff users. Required permission: api.system.settings.manage
Account types: Staff only
curl -X GET "https://propops.yourcompany.com/api/system/settings" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": {
    "organisation_name": "Acme Property Management",
    "default_vat_rate": 20.0,
    "default_currency": "GBP",
    "sla_default_hours": 48,
    "require_contractor_certs": true,
    "enable_whatsapp": false,
    "enable_ai_analysis": true,
    "gdpr_retention_days": 365
  }
}

System logs

Get system logs

GET /api/system/logs Returns paginated application log entries. Restricted to Staff with log-viewing permission. Required permission: api.system.logs.manage
Account types: Staff only
level
string
Filter by log level: error, warning, info, debug.
service
string
Filter by service name (e.g. jobs-manage, notifications).
from
string
ISO 8601 start datetime for date range filter.
to
string
ISO 8601 end datetime for date range filter.
page
integer
default:"1"
Page number.
limit
integer
default:"50"
Results per page (max 200).
curl -X GET "https://propops.yourcompany.com/api/system/logs?level=error&limit=20" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": [
    {
      "id": 8821,
      "level": "error",
      "service": "mail",
      "message": "SMTP connection refused: Connection timed out",
      "context": { "host": "smtp.mailgun.org", "port": 587 },
      "created_at": "2024-06-14T09:45:00Z"
    }
  ],
  "total": 48,
  "page": 1,
  "limit": 20
}

Device tokens

Register a device token

POST /api/system/device-tokens Registers a device push-notification token (FCM or APNS) for the authenticated user. Used by mobile and PWA clients to receive push notifications. Permission: All authenticated users
token
string
required
The device push token issued by the operating system or browser.
platform
string
required
Platform identifier: web, ios, or android.
csrf_token
string
required
CSRF token from GET /api/security/csrf-token.
curl -X POST "https://propops.yourcompany.com/api/system/device-tokens" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
    "platform": "web",
    "csrf_token": "<csrf-token>"
  }'
{
  "success": true,
  "message": "Device token registered"
}

Delete a device token

DELETE /api/system/device-tokens Removes a device token for the authenticated user. Call this on logout to stop notifications reaching the device. Permission: All authenticated users
Requires CSRF token.
token
string
required
The device push token to remove.
csrf_token
string
required
CSRF token.
curl -X DELETE "https://propops.yourcompany.com/api/system/device-tokens" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
    "csrf_token": "<csrf-token>"
  }'
{
  "success": true,
  "message": "Device token removed"
}

Web push subscriptions

Subscribe to web push

POST /api/system/web-push-subscriptions Saves a Web Push API subscription object (generated by the browser’s pushManager.subscribe()) for the authenticated user. Permission: All authenticated users
Requires CSRF token.
subscription
object
required
The full PushSubscription JSON object from the browser, including endpoint, keys.p256dh, and keys.auth.
csrf_token
string
required
CSRF token.
curl -X POST "https://propops.yourcompany.com/api/system/web-push-subscriptions" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "subscription": {
      "endpoint": "https://fcm.googleapis.com/fcm/send/...",
      "keys": {
        "p256dh": "BNcRdre...",
        "auth": "tBHItJI5svbpez7KI4CCXg=="
      }
    },
    "csrf_token": "<csrf-token>"
  }'
{
  "success": true,
  "message": "Web push subscription saved"
}

Help & Documentation

Fetch help documentation

GET /api/help Fetches documentation from the PropOps internal knowledge base (powered by Craft.do). Supports listing all topics, retrieving a specific document, full-text search, and context-sensitive page-level help. Required permission: api.help.read
Auth: Session or Bearer token required
action
string
default:"list"
Operation to perform:
  • list — Return all available help topics
  • get — Return a specific document by ID
  • search — Full-text search across all help content
  • page_help — Retrieve contextual help content for a given app page
  • page_list — List all page-level help entries
  • page_doc — Retrieve a specific page-level documentation document
id
string
Document ID (required for action=get and action=page_doc).
q
string
Search query (required for action=search).
page_path
string
App page path (required for action=page_help, e.g. /jobs).
bust
integer
Set to 1 to bypass the server-side documentation cache and force a fresh fetch.
curl -X GET "https://propops.yourcompany.com/api/help?action=list" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "data": [
    {
      "id": "7CD324BD-9ACE-40B1-AE61-52D2B786260A",
      "title": "Getting Started",
      "type": "page"
    },
    {
      "id": "AA11BB22-CC33-4444-DD55-EE6677889900",
      "title": "Job Management",
      "type": "page"
    }
  ]
}
Retrieve a specific document (action=get):
curl -X GET "https://propops.yourcompany.com/api/help?action=get&id=AA11BB22-CC33-4444-DD55-EE6677889900" \
  -H "Authorization: Bearer <token>"
{
  "success": true,
  "found": true,
  "id": "AA11BB22-CC33-4444-DD55-EE6677889900",
  "title": "Job Management",
  "blocks": [
    { "type": "text", "content": "Jobs are the core unit of work in PropOps..." },
    { "type": "page", "content": "Creating a new job..." }
  ],
  "status": "published",
  "created": "2024-01-01T00:00:00Z",
  "created_by": "Admin User",
  "created_by_uuid": "550e8400-e29b-41d4-a716-446655440099"
}
Search (action=search):
curl -X GET "https://propops.yourcompany.com/api/help?action=search&q=invoice" \
  -H "Authorization: Bearer <token>"
Responses are cached server-side for two hours. Append ?bust=1 to force a fresh fetch from the knowledge base.
This endpoint returns 503 Service Unavailable if the Craft documentation service is not configured for your instance.