Developer docs

Push any number with one HTTP request and see it on your iPhone. Everything below works with curl, Python, Home Assistant, n8n, a cron job or an AI agent. New here? The guide walks through the app first.


Architecture

Decoupled by design. Easy to extend.

Your Services
→
Collector Scripts
→
WidgetDash API
→
iOS Widget

The server is fully generic. It stores whatever you push. Collectors are independent scripts you write and run yourself, so anyone can build one for any service.


Quick Start

Live in minutes. Three commands.

1. Create an account

# Create an account and get your API keys
curl -X POST https://api.widgetdash.app/api/v1/users \
  -H "Content-Type: application/json" \
  -d '{"name": "your-name"}'

2. Push data (use your write key)

curl -X PUT https://api.widgetdash.app/api/v1/data/my-source \
  -H "Authorization: Bearer YOUR_WRITE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "My Service",
    "icon": "chart.bar.fill",
    "category": "monitoring",
    "metrics": [
      {"label": "Users Online", "value": "42", "type": "number", "color": "green"},
      {"label": "Status", "value": "Healthy", "type": "status", "color": "green"}
    ]
  }'

3. Read data (use your read key)

curl https://api.widgetdash.app/api/v1/widget \
  -H "Authorization: Bearer YOUR_READ_KEY"

API Reference

Every endpoint, in one place.

MethodEndpointAuthDescription
POST /api/v1/users None Create account, get API keys
GET /api/v1/users/me Read Get account info
DELETE /api/v1/users/me Write Delete the account and all its data (body {"confirm":"DELETE"})
POST /api/v1/users/me/rotate-keys Write Replace both API keys; the old ones stop working at once
PUT /api/v1/data/{source_key} Write Push data from collector
GET /api/v1/widget Read Get all widget data
GET /api/v1/data/{source_key} Read Get specific source data
POST /api/v1/sources Write Register data source
GET /api/v1/sources Read List data sources
DELETE /api/v1/sources/{source_key} Write Delete data source
GET /health None Health check
GET /api/v1/version None Version info

Metric Types

Every metric carries a type. The type decides how the widget renders it.

number

A large, bold number. Use it for counts, totals, and headline figures.

1,284

text

A plain string. Use it for labels, names, descriptions, or any short value.

us-east-1

status

A colored badge. Ideal for health checks, states, and alerts.

Healthy

progress

A bar for values from 0-100. Great for utilization, quotas, and completion.

72%

timestamp

A moment in time, shown as how long ago it was. Send ISO 8601 (2026-10-18T05:00:00Z) or Unix seconds; the widget keeps it current between pushes. Great for last backup, last deploy, last sync.

13h ago

Wide Metrics

On a Large widget, a source's metrics share rows, up to four side by side, and text in a shared row shows up to two lines. For a long value like the title of what you last watched, add "wide": true and the metric gets a full row of its own, where it is in your list (iOS app 1.8 or later). Put wide metrics last to keep the others together.

Available Colors

green
red
yellow
blue
gray
orange
purple
cyan

Color Rules

Set thresholds once and leave color out of your metrics: the server picks the color every time the widget reads. Send color_rules with any push; it's kept until you send new rules, and {} clears them. The first rule whose conditions all match wins; a rule with only a color is the default. A color sent in the push always wins.

{
  "metrics": [ ... ],
  "color_rules": {
    "Days left":   [{"below": 3, "color": "red"}, {"below": 7, "color": "yellow"}, {"color": "green"}],
    "Status":      [{"equals": "Down", "color": "red"}, {"color": "green"}],
    "Last backup": [{"older_than": "24h", "color": "red"}, {"color": "green"}]
  }
}

Conditions: below / above compare the first number in the value ("40 days", "61%", "1,284"), equals matches text (any case), older_than / newer_than check a timestamp's age (30m, 12h, 7d), so a backup turns red on its own once it's too old.


Writing a Collector

A collector is any script that pushes data to WidgetDash on a schedule.

How collectors work

Tip: Push on every run, even when nothing changed. The server compares each push with the previous one: an identical payload only refreshes the widget's "updated" time, so it never looks stale, while Live Activities and changed_at move only when a value actually changes. No need to hash payloads or skip writes.

Example: Python collector

import httpx, os, time

API_KEY = os.environ["WIDGET_API_KEY"]
SERVER = "https://api.widgetdash.app"

while True:
    # Fetch your data (replace with your own logic)
    users_online = get_users_count()

    httpx.put(f"{SERVER}/api/v1/data/my-app",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={
            "display_name": "My App",
            "icon": "person.3.fill",
            "category": "app",
            "metrics": [
                {"label": "Online", "value": str(users_online), "type": "number", "color": "green"}
            ]
        })
    time.sleep(60)

Quick Setup

Scan a QR code and the app configures itself.

1

Create Account

Sign up on the dashboard (or just open the iPhone app, which creates a free account) to get your read and write keys.

2

Scan QR Code

Open the WidgetDash app and scan the code below, or the one on your dashboard.

3

Done

The settings apply at once. Your widgets start showing data right away.

Generate your setup QR code



iOS Widget

Your data at a glance, right on your Home Screen.

1

Download

Get the free WidgetDash app from the App Store (iOS 17.6 or later).

2

Connect

Scan the QR code on your dashboard, or enter your write key in the app (a read key connects view-only).

3

Add Widget

Long-press your Home Screen and add the WidgetDash widget in small, medium or large, or add it to your Lock Screen.