Local API & Automation

Automate posture tracking with launch arguments, a local REST API, and Prometheus metrics.

Overview

SitApp includes a local HTTP server (default port 6543) and command-line flags that let you automate tracking and export posture data without touching the UI. This is useful for:

Launch Arguments

--auto-start

Begin posture tracking immediately after the app finishes initializing. No clicks needed. Requires that you've completed onboarding and calibration at least once before.

# Start SitApp and begin tracking immediately
sitapp --auto-start

--export=<path>

When the app quits, write the current session's posture stats to the specified file as JSON. The parent directory is created automatically if it doesn't exist.

# Track all day, export stats when you close the app
sitapp --auto-start --export=$HOME/posture/today.json

The exported JSON looks like this:

{
  "session": {
    "good": 847,
    "bad": 153,
    "total": 1000,
    "goodPercentage": 85,
    "badPercentage": 15,
    "startedAt": "2025-03-15T09:00:00.000Z",
    "exportedAt": "2025-03-15T17:30:00.000Z",
    "durationSeconds": 30600
  }
}

REST API

The local API runs on the same server SitApp uses internally, at http://localhost:6543. All endpoints return JSON.

MethodEndpointDescription
GET/api/statsCurrent session statistics
POST/api/tracking/startStart posture tracking
POST/api/tracking/stopStop posture tracking
GET/api/readingsGranular posture readings (time-series)
GET/metricsPrometheus metrics

GET /api/stats

Returns the current session's posture statistics and monitoring state.

# Check your current session stats
curl http://localhost:6543/api/stats
{
  "monitoring": true,
  "session": {
    "good": 420,
    "bad": 80,
    "total": 500,
    "goodPercentage": 84,
    "badPercentage": 16,
    "startedAt": "2025-03-15T09:00:00.000Z",
    "durationSeconds": 3600
  }
}

POST /api/tracking/start

Start posture tracking. Returns 400 if the app isn't calibrated yet.

# Start tracking from a script
curl -X POST http://localhost:6543/api/tracking/start
{"status": "started"}          # Success
{"status": "already_tracking"} # Already running
{"error": "Not calibrated..."}  # 400 - calibrate first

POST /api/tracking/stop

Stop posture tracking.

curl -X POST http://localhost:6543/api/tracking/stop
{"status": "stopped"}          # Success
{"status": "already_stopped"}  # Already stopped
Tip: The API returns 503 with {"error": "App not fully initialized"} if the app is still starting up. Wait a few seconds and retry.

Time-Series Readings

SitApp stores every posture reading locally with timestamps and confidence scores. Query this data for detailed analysis.

GET /api/readings

Returns granular posture readings, sessions, and breaks for a time range. Defaults to the last 24 hours.

# Get today's readings
curl http://localhost:6543/api/readings

# Get readings for a specific time range (ISO 8601)
curl "http://localhost:6543/api/readings?from=2026-04-07T09:00:00Z&to=2026-04-07T17:00:00Z"

# Limit to 100 readings
curl "http://localhost:6543/api/readings?limit=100"
{
  "query": { "from": 1743937200000, "to": 1744023600000, "limit": 10000 },
  "readingCount": 83,
  "readings": [
    {
      "timestamp": 1743937233000,
      "time": "2026-04-07T09:00:33.000Z",
      "posture": "good",
      "confidence": 0.95,
      "location": null
    },
    ...
  ],
  "sessions": [
    {
      "sessionId": "6583136f-c0dc-...",
      "startedAt": "2026-04-07T09:25:33.000Z",
      "endedAt": "2026-04-07T09:26:55.000Z",
      "durationSeconds": 82
    }
  ],
  "breaks": []
}
Tip: The --export flag also includes granular readings for the current session alongside the summary statistics.

Export Data with Readings

When using --export, the JSON file now includes a readings array with every posture reading from the session:

# Export includes granular readings
sitapp --auto-start --export=$HOME/posture/today.json
{
  "session": {
    "good": 50, "bad": 33, "total": 83,
    "goodPercentage": 60, "badPercentage": 40,
    "startedAt": "2026-04-07T09:25:33.000Z",
    "exportedAt": "2026-04-07T10:30:00.000Z",
    "durationSeconds": 3867
  },
  "readings": [
    { "timestamp": 1743937233000, "time": "2026-04-07T09:25:33.000Z", "posture": "good", "confidence": 0.95, "location": null },
    ...
  ],
  "readingCount": 83
}

Prometheus & Grafana

SitApp exposes a /metrics endpoint in Prometheus text exposition format, ready to scrape.

Prometheus Configuration

Add this job to your prometheus.yml:

scrape_configs:
  - job_name: 'sitapp'
    scrape_interval: 15s
    static_configs:
      - targets: ['localhost:6543']

Available Metrics

MetricTypeDescription
sitapp_monitoringgauge1 if tracking is active, 0 if not
sitapp_session_good_totalgaugeGood posture readings this session
sitapp_session_bad_totalgaugeBad posture readings this session
sitapp_session_totalgaugeTotal readings this session
sitapp_session_good_percentagegaugeGood posture percentage
sitapp_session_duration_secondsgaugeCurrent session duration in seconds

Example: Grafana Dashboard

Once Prometheus is scraping, create a Grafana dashboard with panels for:

Multi-Device Setups

If you use SitApp on more than one machine, it helps to know which data lives where:

DataScopeDetails
Daily & monthly summariesPer-accountSynced to the cloud. Your posture score, total duration, and session count are the same on every machine you sign in to.
Preferences & settingsPer-machineAlert position, sensitivity, sound preferences, and other settings are stored locally. You'll need to configure each machine separately.
Granular posture readingsPer-machineThe time-series database (/api/readings, --export) stays on the machine that recorded it. Readings are never uploaded.
Calibration modelsPer-machineEach machine has its own calibration, tuned to that desk and camera setup.
Prometheus metricsPer-machineThe /metrics endpoint reports the current machine's session only.
Tip: If you want a complete picture across machines, run your export script or Prometheus scrape on each one individually. The daily summaries in the dashboard already combine all sessions from your account, regardless of which machine recorded them.

Example: Daily Export Script

Here's a simple script that exports your posture data at the end of each day and appends it to a log:

#!/bin/bash
# Save today's posture stats
DATE=$(date +%Y-%m-%d)
curl -s http://localhost:6543/api/stats \
  | jq ".date = \"$DATE\"" \
  >> ~/posture-log.jsonl

# Optional: sync to Exist.io or another service
# curl -X POST https://exist.io/api/2/attributes/update/ ...