### Start a generic activity with PATCH Source: https://pushward.app/docs/api/activities Example of starting a generic activity by setting state to 'ongoing' with content. This triggers a push-to-start action. Uses merge-patch semantics; fields not sent are preserved. ```bash curl -X PATCH https://api.pushward.app/activities/dishwasher \ -H "Authorization: Bearer hlk_YOUR_TOKEN" \ -H "Content-Type: application/merge-patch+json" \ -d '{ "state": "ongoing", "content": { "template": "generic", "progress": 0.65, "state": "Washing", "icon": "washer", "remaining_time": 1800, "subtitle": "Cycle 2 of 3", "accent_color": "blue" } }' ``` -------------------------------- ### Create, start, update, and end an activity with the Pushward API Source: https://pushward.app/docs/examples Uses fetch to POST a new activity and PATCH its state through ongoing to ended. Requires a valid API token in TOKEN. The example sets a generic template with progress, state text, icon, and accent_color for each update. ```JavaScript const BASE_URL = "https://api.pushward.app"; const TOKEN = "hlk_YOUR_KEY"; const headers = { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", }; // Create activity await fetch(`${BASE_URL}/activities`, { method: "POST", headers, body: JSON.stringify({ slug: "my-build", name: "My Build", }), }); // Start activity await fetch(`${BASE_URL}/activities/my-build`, { method: "PATCH", headers, body: JSON.stringify({ state: "ongoing", content: { template: "generic", progress: 0.0, state: "Starting...", icon: "arrow.triangle.branch", accent_color: "cyan", }, }), }); // Update progress await fetch(`${BASE_URL}/activities/my-build`, { method: "PATCH", headers, body: JSON.stringify({ state: "ongoing", content: { template: "generic", progress: 0.75, state: "Running tests...", icon: "arrow.triangle.branch", accent_color: "cyan", }, }), }); // End activity await fetch(`${BASE_URL}/activities/my-build`, { method: "PATCH", headers, body: JSON.stringify({ state: "ended", content: { template: "generic", progress: 1.0, state: "Complete", icon: "checkmark.circle.fill", accent_color: "green", }, }), }); ``` -------------------------------- ### Install the PushWard Unraid plugin Source: https://pushward.app/docs/integrations/unraid Paste this URL into the Unraid web UI under Plugins → Install Plugin. Requires Unraid 6.12 or later. ```text https://github.com/mac-lucky/pushward-unraid-plugin/raw/main/pushward-unraid.plg ``` -------------------------------- ### GET /auth/me Response Source: https://pushward.app/docs/api/authentication Example JSON response from the /auth/me endpoint, showing user profile details and current usage quotas. ```json { "id": "550e8400-e29b-41d4-a716-446655440000", "nickname": "Alice", "activity_count": 3, "subscribed": false, "quota_period_month": 202606, "notifications_used": 128, "notifications_limit": 500, "live_activity_updates_used": 86, "live_activity_updates_limit": 250, "widget_updates_used": 12, "widget_updates_limit": 50, "emails_used": 3, "emails_limit": 50, "quota_resets_at": "2026-07-01T00:00:00Z" } ``` -------------------------------- ### Manage Pushward activities with Go Source: https://pushward.app/docs/examples Demonstrates how to create, start, update, and end an activity using the standard net/http package. Replace the token constant with your actual API key. ```go package main import ( "bytes" "encoding/json" "fmt" "net/http" ) const ( baseURL = "https://api.pushward.app" token = "hlk_YOUR_KEY" ) func main() { // Create activity post("/activities", map[string]any{ "slug": "my-build", "name": "My Build", }) // Start activity patch("/activities/my-build", map[string]any{ "state": "ongoing", "content": map[string]any{ "template": "generic", "progress": 0.0, "state": "Starting...", "icon": "arrow.triangle.branch", "accent_color": "cyan", }, }) // Update progress patch("/activities/my-build", map[string]any{ "state": "ongoing", "content": map[string]any{ "template": "generic", "progress": 0.75, "state": "Running tests...", "icon": "arrow.triangle.branch", "accent_color": "cyan", }, }) // End activity patch("/activities/my-build", map[string]any{ "state": "ended", "content": map[string]any{ "template": "generic", "progress": 1.0, "state": "Complete", "icon": "checkmark.circle.fill", "accent_color": "green", }, }) } func post(path string, body map[string]any) { doRequest("POST", path, body) } func patch(path string, body map[string]any) { doRequest("PATCH", path, body) } func doRequest(method, path string, body map[string]any) { data, _ := json.Marshal(body) req, _ := http.NewRequest(method, baseURL+path, bytes.NewReader(data)) req.Header.Set("Authorization", "Bearer "+token) req.Header.Set("Content-Type", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { fmt.Printf("Error: %v\n", err) return } defer resp.Body.Close() fmt.Printf("%s %s -> %d\n", method, path, resp.StatusCode) } ``` -------------------------------- ### PATCH /widgets/power - Home energy flow example Source: https://pushward.app/docs/widgets/templates/flow Example request body for the flow widget showing solar input, home output, battery storage, and grid exchange. The exchange rate is negative (-1400) to indicate exporting to the grid. Only the slots sent are drawn. ```json { "content": { "template": "flow", "label": "Power", "subtitle": "Solar · grid · home", "icon": "point.3.filled.connected.trianglepath.dotted", "unit": "W", "accent_color": "mint", "flow": { "inputs": [ { "name": "Solar", "rate": 3200, "total": 12.4, "icon": "sun.max.fill", "color": "yellow" } ], "output": { "name": "Home", "rate": 1000, "total": 9.8, "icon": "house.fill" }, "storage": { "name": "Battery", "rate": 800, "level": 76, "icon": "battery.75percent", "color": "green" }, "exchange": { "name": "Grid", "rate": -1400, "total": 3.1, "icon": "bolt.fill", "color": "cyan" } } } } ``` -------------------------------- ### PATCH /widgets/deploys Source: https://pushward.app/docs/widgets/templates/value Example configuration for a Value widget displaying daily deployment counts with a trend indicator. ```json { "content": { "template": "value", "value": 18, "label": "Deploys", "subtitle": "Today · 14 prod · 4 staging", "icon": "shippingbox.fill", "accent_color": "cyan", "trend": "up" } } ``` -------------------------------- ### Manage Pushward activities with Python Source: https://pushward.app/docs/examples Demonstrates how to create, start, update, and end an activity using the requests library. Ensure the TOKEN variable is replaced with your actual API key. ```python import requests BASE_URL = "https://api.pushward.app" TOKEN = "hlk_YOUR_KEY" HEADERS = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json", } # Create activity requests.post(f"{BASE_URL}/activities", headers=HEADERS, json={ "slug": "my-build", "name": "My Build", }) # Start activity requests.patch(f"{BASE_URL}/activities/my-build", headers=HEADERS, json={ "state": "ongoing", "content": { "template": "generic", "progress": 0.0, "state": "Starting...", "icon": "arrow.triangle.branch", "accent_color": "cyan", }, }) # Update progress requests.patch(f"{BASE_URL}/activities/my-build", headers=HEADERS, json={ "state": "ongoing", "content": { "template": "generic", "progress": 0.75, "state": "Running tests...", "icon": "arrow.triangle.branch", "accent_color": "cyan", }, }) # End activity requests.patch(f"{BASE_URL}/activities/my-build", headers=HEADERS, json={ "state": "ended", "content": { "template": "generic", "progress": 1.0, "state": "Complete", "icon": "checkmark.circle.fill", "accent_color": "green", }, }) ``` -------------------------------- ### PATCH /widgets/devices - battery template example Source: https://pushward.app/docs/widgets/templates/battery Example request body for the battery widget with four devices. The template field must be "battery", and devices is required with 1 to 8 objects. The icon field uses SF Symbols or MDI icons prefixed with mdi:. ```json { "content": { "template": "battery", "label": "Devices", "icon": "battery.75percent", "accent_color": "green", "devices": [ { "name": "Vacuum", "level": 68, "icon": "fan.fill" }, { "name": "Front lock", "level": 45, "icon": "lock.fill", "charging": true }, { "name": "Doorbell", "level": 18, "icon": "video.fill" }, { "name": "Sensor hub", "level": 92, "icon": "sensor.fill" } ] } } ``` -------------------------------- ### Streaming Deploy Log Example Source: https://pushward.app/docs/live-activities/log A JSON payload demonstrating the structure of a log template Live Activity, including state, icon, accent color, and a list of log lines. ```json { "state": "ongoing", "content": { "template": "log", "state": "pushward-server", "icon": "doc.text", "accent_color": "purple", "lines": [ { "text": "Rollout complete — 3/3 pods healthy", "at": 1718990000, "level": "info" }, { "text": "Image pull slow on node arm-2", "at": 1718989950, "level": "warn" }, { "text": "Applied manifest revision d86246c", "at": 1718989930, "level": "info" }, { "text": "Sync started by webhook", "at": 1718989900, "level": "info" } ] } } ``` -------------------------------- ### Now playing with cover art and ThumbHash Source: https://pushward.app/docs/live-activities/generic Example of a generic template configuration including an image URL, poster shape, and ThumbHash for fallback rendering. ```json { "state": "ongoing", "content": { "template": "generic", "progress": 0.35, "state": "Playing", "subtitle": "S02E04 - The Constant", "icon": "play.fill", "image_url": "https://images.example.com/lost/s02e04.jpg", "image_shape": "poster", "image_thumbhash": "GYpSpSh4eHt4eHh4eHh4eHh4iIeH", "accent_color": "indigo" } } ``` -------------------------------- ### device_sort example - lowest battery first, then alphabetical Source: https://pushward.app/docs/widgets/templates/battery Example request body with device_sort keys to order devices by level ascending, then by name ascending. The same field may not appear in both keys. The server stores the sorted array, so responses and GET requests return reordered devices. ```json { "content": { "template": "battery", "device_sort": [ { "field": "level", "direction": "asc" }, { "field": "name", "direction": "asc" } ], "devices": [ { "name": "Vacuum", "level": 68 }, { "name": "Front lock", "level": 45 }, { "name": "Doorbell", "level": 45 }, { "name": "Sensor hub", "level": 92 } ] } } ``` -------------------------------- ### Gauge complete JSON example Source: https://pushward.app/docs/live-activities/gauge Example JSON payload for a gauge update with state 'ended', value 250, range 0-250, unit '°C', state 'Ready', icon 'checkmark.circle.fill', and accent color 'green'. ```json { "state": "ended", "content": { "template": "gauge", "value": 250, "min_value": 0, "max_value": 250, "unit": "°C", "state": "Ready", "icon": "checkmark.circle.fill", "accent_color": "green" } } ``` -------------------------------- ### PATCH /widgets/oncall-pages - Progress widget example Source: https://pushward.app/docs/widgets/templates/progress Example request body for a progress widget showing incident acknowledgements. Uses template "progress", value 0.6, label, subtitle, icon, accent_color, and stat_rows with three rows. ```json { "content": { "template": "progress", "value": 0.6, "label": "Pages", "subtitle": "6 of 10 acked · INC-2841", "icon": "checklist", "accent_color": "green", "stat_rows": [ { "label": "Acked", "value": "6" }, { "label": "Total", "value": "10" }, { "label": "Severity", "value": "SEV-2" } ] } } ``` -------------------------------- ### Single Value Timeline Example Source: https://pushward.app/docs/live-activities/timeline A basic implementation for monitoring a single value, such as temperature, with smoothing enabled. ```json { "state": "ongoing", "content": { "template": "timeline", "value": {"Temperature": 13.7}, "unit": "°C", "state": "Heating", "icon": "thermometer.medium", "accent_color": "orange", "smoothing": true } } ``` -------------------------------- ### List Activities Response (200) Source: https://pushward.app/docs/api/activities Example response body for listing activities. Contains an 'items' array and a 'next_cursor' for pagination. Pass 'next_cursor' back as 'after' until it is null or empty. ```json { "items": [ { "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "kind": "owned", "slug": "ci-pipeline", "name": "CI Pipeline", "state": "ended", "priority": 0, "content": {}, "ended_ttl": 3600, "stale_ttl": null, "dismissal_ttl": null, "delete_at": "2025-06-15T12:00:00Z", "created_at": "2025-06-15T10:00:00Z", "updated_at": "2025-06-15T11:00:00Z", "ended_at": "2025-06-15T11:00:00Z" }, { "id": "550e8400-e29b-41d4-a716-446655440000", "kind": "owned", "slug": "dishwasher", "name": "Dishwasher", "state": "ongoing", "priority": 3, "content": { "template": "generic", "progress": 0.65, "state": "Washing", "icon": "washer", "remaining_time": 1800, "subtitle": "Cycle 2 of 3", "accent_color": "blue" }, "ended_ttl": null, "stale_ttl": null, "dismissal_ttl": null, "delete_at": null, "created_at": "2025-06-15T10:30:00Z", "updated_at": "2025-06-15T11:00:00Z", "ended_at": null } ], "next_cursor": "eyJzIjoib3Zlbi10aW1lciIsImkiOjE5fQ" } ``` -------------------------------- ### GET /widgets Source: https://pushward.app/docs/widgets/api Lists every widget owned by the calling user. ```APIDOC ## GET /widgets ### Description List every widget owned by the calling user. ### Method GET ### Endpoint /widgets ### Request Example curl https://api.pushward.app/widgets \ -H "Authorization: Bearer hlk_YOUR_TOKEN" ### Response #### Success Response (200) - **items** (array) - List of widgets. Each widget contains slug, name, content, created_at, updated_at. #### Response Example { "items": [ { "slug": "cpu-load", "name": "CPU Load", "content": { "template": "progress", "value": 0.42, "label": "load avg", "icon": "cpu", "accent_color": "cyan" }, "created_at": "2026-05-10T12:00:00Z", "updated_at": "2026-05-10T12:00:00Z" } ] } ``` -------------------------------- ### stat_list row with timer: backup example Source: https://pushward.app/docs/widgets/templates/stat-list Example content for a stat_list widget with a timer on the first row. The timer uses a relative style and a past date to count up. The value field remains required and serves as the static fallback for builds before 1.6. ```json { "content": { "template": "stat_list", "label": "Backups", "stat_rows": [ { "label": "Last run", "value": "12 min ago", "timer": { "date": "2027-05-10T08:00:00Z", "style": "relative" } }, { "label": "Repos", "value": "14" }, { "label": "Failed", "value": "0" } ] } } ``` -------------------------------- ### List widgets with curl Source: https://pushward.app/docs/widgets/api GET /widgets lists every widget owned by the calling user. Requires the same integration key with the widgets flag. The response is a 200 with an items array. ```bash curl https://api.pushward.app/widgets \ -H "Authorization: Bearer hlk_YOUR_TOKEN" ``` ```json { "items": [ { "slug": "cpu-load", "name": "CPU Load", "content": { "template": "progress", "value": 0.42, "label": "load avg", "icon": "cpu", "accent_color": "cyan" }, "created_at": "2026-05-10T12:00:00Z", "updated_at": "2026-05-10T12:00:00Z" } ] } ``` -------------------------------- ### Example Payload for Steps Template Source: https://pushward.app/docs/live-activities/steps A standard JSON payload for the steps template, defining the current state, progress, and step configuration. ```json { "state": "ongoing", "content": { "template": "steps", "progress": 0.375, "state": "Build Container Image", "icon": "arrow.triangle.branch", "subtitle": "pushward-server / CI/CD", "current_step": 2, "total_steps": 8, "step_rows": [1, 1, 3, 1, 1, 2, 1, 1], "step_labels": ["Lint", "Build", "Test", "Scan", "Publish", "Deploy", "Verify", "Notify"], "accent_color": "green" } } ``` -------------------------------- ### PATCH /widgets/incident - status widget example Source: https://pushward.app/docs/widgets/templates/status Example request body for setting a status widget to a warning incident state. The severity 'warning' picks a triangle icon and warning color. The subtitle is split into tag pills by separators like '·' and ','. ```json { "content": { "template": "status", "severity": "warning", "label": "Incident", "subtitle": "INC-2841 · api-gateway · investigating", "url_action": { "title": "Ack", "icon": "checkmark.circle.fill", "url": "https://example.com/ack/2841" } } } ``` -------------------------------- ### PATCH /widgets/error-rate - gauge widget example Source: https://pushward.app/docs/widgets/templates/gauge Example request body for creating a gauge widget showing an error rate against an SLO. The value must be within min_value and max_value, otherwise the request is rejected with 422. The unit is appended to the value and to the MIN/MAX end labels. ```json { "content": { "template": "gauge", "value": 2.4, "min_value": 0, "max_value": 5, "unit": "%", "label": "Errors", "subtitle": "api-gateway · last 5m · SLO 1.0%", "icon": "chart.line.uptrend.xyaxis", "accent_color": "red" } } ``` -------------------------------- ### GET /activities Source: https://pushward.app/docs/api/activities Fetches a page of activities with optional limit and cursor-based pagination using the 'after' query parameter. ```APIDOC ## GET /activities ### Description Fetches a page of activities with optional limit and cursor-based pagination using the 'after' query parameter. ### Method GET ### Endpoint /activities ### Parameters #### Query Parameters - **limit** (integer) - Optional - Maximum number of activities to return. - **after** (string) - Optional - Cursor for pagination, obtained from the previous response. ### Request Example curl "https://api.pushward.app/activities?limit=50&after=eyJzIjoib3Zlbi10aW1lciIsImkiOjE5fQ" \ -H "Authorization: Bearer hlk_YOUR_TOKEN" ### Response #### Success Response (200) - **activities** (array) - List of activity objects. - **next_cursor** (string) - Cursor for the next page, if any. #### Response Example { "activities": [], "next_cursor": null } ``` -------------------------------- ### Create Activity Response (201 Created) Source: https://pushward.app/docs/api/activities Example response body for a successful activity creation. Always returns 201 Created. The response includes the activity object with fields like id, slug, state, and timestamps. ```json { "id": "550e8400-e29b-41d4-a716-446655440000", "kind": "owned", "slug": "dishwasher", "name": "Dishwasher", "state": "ended", "priority": 3, "content": {}, "ended_ttl": null, "stale_ttl": null, "dismissal_ttl": null, "delete_at": null, "created_at": "2025-06-15T10:30:00Z", "updated_at": "2025-06-15T10:30:00Z", "ended_at": null } ``` -------------------------------- ### Create an activity via POST Source: https://pushward.app/docs Creates a new activity with a unique slug and display name. The activity starts in the ended state by default. ```bash curl -X POST https://api.pushward.app/activities \ -H "Authorization: Bearer hlk_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "slug": "my-build", "name": "My Build" }' ``` -------------------------------- ### Get a single activity by slug Source: https://pushward.app/docs/api/activities Fetches a single activity by its slug. Replace 'dishwasher' with the actual slug and 'hlk_YOUR_TOKEN' with your API token. ```bash curl https://api.pushward.app/activities/dishwasher \ -H "Authorization: Bearer hlk_YOUR_TOKEN" ``` -------------------------------- ### POST /activities Source: https://pushward.app/docs/api/activities Creates a new activity. Starts in the 'ended' state and automatically subscribes all user devices. Re-POSTing the same slug is idempotent and refreshes the existing activity's name, priority, and TTLs while preserving state and content. ```APIDOC ## POST /activities ### Description Creates a new activity. Starts in the 'ended' state and automatically subscribes all user devices. Re-POSTing the same slug is idempotent and refreshes the existing activity's name, priority, and TTLs while preserving state and content. ### Method POST ### Endpoint /activities ### Parameters #### Request Body - **slug** (string) - Required - URL-safe identifier, unique per user - **name** (string) - Required - Human-readable display name - **priority** (integer) - Optional - Eviction priority 0-10 (default: 0). Higher = kept longer server-side and ordered ahead of other Live Activities on the iOS Lock Screen and Dynamic Island (mapped to APNs relevance-score). - **ended_ttl** (integer) - Optional - Seconds after 'ended' transition before server auto-deletes the activity - **stale_ttl** (integer) - Optional - Seconds of inactivity while 'ongoing' before server auto-ends the activity - **dismissal_ttl** (integer) - Optional - Seconds after 'ended' before the Live Activity is removed from the Lock Screen. 0 removes it immediately; max 14400 (4h, the iOS ceiling). When unset, removal follows ended_ttl. ### Request Example curl -X POST https://api.pushward.app/activities \ -H "Authorization: Bearer hlk_YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slug": "dishwasher", "name": "Dishwasher", "priority": 3 }' ### Response #### Success Response (201 Created) - **id** (string) - Activity ID - **kind** (string) - Activity kind (e.g., "owned") - **slug** (string) - URL-safe identifier - **name** (string) - Display name - **state** (string) - Activity state (e.g., "ended") - **priority** (integer) - Eviction priority - **content** (object) - Activity content - **ended_ttl** (integer|null) - Seconds after ended before auto-delete - **stale_ttl** (integer|null) - Seconds of inactivity before auto-end - **dismissal_ttl** (integer|null) - Seconds after ended before removal from Lock Screen - **delete_at** (string|null) - Timestamp when activity will be deleted - **created_at** (string) - Creation timestamp - **updated_at** (string) - Last update timestamp - **ended_at** (string|null) - Timestamp when activity ended #### Response Example { "id": "550e8400-e29b-41d4-a716-446655440000", "kind": "owned", "slug": "dishwasher", "name": "Dishwasher", "state": "ended", "priority": 3, "content": {}, "ended_ttl": null, "stale_ttl": null, "dismissal_ttl": null, "delete_at": null, "created_at": "2025-06-15T10:30:00Z", "updated_at": "2025-06-15T10:30:00Z", "ended_at": null } ``` -------------------------------- ### Start a Live Activity via PATCH Source: https://pushward.app/docs Updates the activity state to ongoing to initiate a Live Activity on the device's Lock Screen. ```bash curl -X PATCH https://api.pushward.app/activities/my-build \ -H "Authorization: Bearer hlk_YOUR_KEY" \ -H "Content-Type: application/merge-patch+json" \ -d '{ "state": "ongoing", "content": { "template": "generic", "progress": 0.0, "state": "Starting...", "icon": "arrow.triangle.branch", "accent_color": "cyan" } }' ``` -------------------------------- ### Firing Alert Example Source: https://pushward.app/docs/live-activities/alert A JSON payload representing an active, critical alert with two deep-link buttons. ```json { "state": "ongoing", "content": { "template": "alert", "progress": 0.0, "state": "CPU usage is 94.2%", "icon": "exclamationmark.triangle.fill", "subtitle": "Grafana · nas-01", "severity": "critical", "severity_label": "SEV1", "fired_at": 1750009000, "accent_color": "red", "url": "https://grafana.example.com/alerting/1afz29v7z/edit", "secondary_url": "https://grafana.example.com/d/abc123?viewPanel=1" } } ``` -------------------------------- ### List Activities with curl (GET /activities) Source: https://pushward.app/docs/api/activities Lists activities for the current user. Returns a cursor-paginated envelope sorted by slug. Use the 'limit' query parameter to control page size. Requires an Authorization header. ```bash curl "https://api.pushward.app/activities?limit=50" \ -H "Authorization: Bearer hlk_YOUR_TOKEN" ``` -------------------------------- ### PATCH /widgets/blinds Source: https://pushward.app/docs/widgets/api Updates a widget's content, including tap actions. This example configures a Home Assistant blinds widget with silent POST actions for opening and closing blinds, and a custom-scheme fallback for the tap action. ```APIDOC ## PATCH /widgets/blinds ### Description Updates a widget's content, including tap actions. This example configures a Home Assistant blinds widget with silent POST actions for opening and closing blinds, and a custom-scheme fallback for the tap action. ### Method PATCH ### Endpoint https://api.pushward.app/widgets/blinds ### Parameters #### Request Body - **content** (object) - Required - The widget content configuration. - **label** (string) - Optional - Display label for the widget. - **icon** (string) - Optional - SF Symbol name for the widget icon. - **url_action** (object) - Optional - Action triggered on URL tap. - **title** (string) - Optional - Title for the action. - **icon** (string) - Optional - SF Symbol name for the action icon. - **url** (string) - Required - The URL to dispatch. - **method** (string) - Optional - HTTP method for silent dispatch (e.g., POST). - **headers** (object) - Optional - HTTP headers for silent dispatch. - **body** (string) - Optional - HTTP body for silent dispatch. - **secondary_url_action** (object) - Optional - Action triggered on secondary URL tap. - **title** (string) - Optional - Title for the action. - **icon** (string) - Optional - SF Symbol name for the action icon. - **url** (string) - Required - The URL to dispatch. - **method** (string) - Optional - HTTP method for silent dispatch (e.g., POST). - **headers** (object) - Optional - HTTP headers for silent dispatch. - **body** (string) - Optional - HTTP body for silent dispatch. - **tap_action** (object) - Optional - Action triggered on widget tap. - **url** (string) - Required - The URL to dispatch. ### Request Example { "content": { "label": "Living Room", "icon": "blinds.horizontal.closed", "url_action": { "title": "Open", "icon": "arrow.up.to.line", "url": "https://homeassistant.example.com/api/services/cover/open_cover", "method": "POST", "headers": { "Authorization": "Bearer HA_LONG_LIVED_TOKEN" }, "body": "{\"entity_id\":\"cover.blinds_living_room\"}" }, "secondary_url_action": { "title": "Close", "icon": "arrow.down.to.line", "url": "https://homeassistant.example.com/api/services/cover/close_cover", "method": "POST", "headers": { "Authorization": "Bearer HA_LONG_LIVED_TOKEN" }, "body": "{\"entity_id\":\"cover.blinds_living_room\"}" }, "tap_action": { "url": "homeassistant://navigate/lovelace/blinds" } } } ### Response #### Success Response (200) No response body is documented. ### Notes - HTTP actions fire silently by default (foreground defaults to false). - Set foreground: true to open the URL in Safari. - method, headers, and body are rejected on custom-scheme URLs. - Content-Type: application/json is set automatically when a body is present and no Content-Type header is supplied. - The widget extension's URLSession budget is ~30 seconds. - PushWard's own pushward:// deep links work as custom-scheme targets. ``` -------------------------------- ### GET /auth/me Source: https://pushward.app/docs/api/authentication Get the current user's profile, activity count, and current quota usage. Integration keys read their own live usage here; the iOS app polls this endpoint for its Usage screen. ```APIDOC ## GET /auth/me ### Description Get the current user's profile, activity count, and current quota usage. Integration keys read their own live usage here; the iOS app polls this endpoint for its Usage screen. ### Method GET ### Endpoint /auth/me ### Response #### Success Response (200) - **id** (string) - User ID - **nickname** (string | null) - Display name - **activity_count** (integer) - Number of activities owned by the user - **subscribed** (boolean) - Whether the user has an active subscription - **quota_period_month** (integer) - `YYYYMM` bucket for the current monthly usage period (UTC) - **notifications_used** / **notifications_limit** (integer) - Notifications sent this period and your tier's cap. `*_limit` is omitted when uncapped. - **live_activity_updates_used** / **live_activity_updates_limit** (integer) - Live Activity updates this month and your tier's cap - **widget_updates_used** / **widget_updates_limit** (integer) - Widget updates this month and your tier's cap - **emails_used** / **emails_limit** (integer) - Emails sent this month and your tier's cap (free 50, paid 200) - **quota_resets_at** (string) - ISO 8601 instant the active counters reset #### Response Example ``` { "id": "550e8400-e29b-41d4-a716-446655440000", "nickname": "Alice", "activity_count": 3, "subscribed": false, "quota_period_month": 202606, "notifications_used": 128, "notifications_limit": 500, "live_activity_updates_used": 86, "live_activity_updates_limit": 250, "widget_updates_used": 12, "widget_updates_limit": 50, "emails_used": 3, "emails_limit": 50, "quota_resets_at": "2026-07-01T00:00:00Z" } ``` ``` -------------------------------- ### Create a CPU-load widget with curl Source: https://pushward.app/docs/widgets/api POST /widgets registers a widget by slug. Requires an integration key (hlk_) with the widgets flag enabled. Re-POSTing the same slug refreshes fields and still returns 201. The response always includes the X-Resource-Action header indicating created or updated. ```bash curl -X POST https://api.pushward.app/widgets \ -H "Authorization: Bearer hlk_YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slug": "cpu-load", "name": "CPU Load", "content": { "template": "progress", "value": 0.42, "label": "load avg", "icon": "cpu", "accent_color": "cyan" } }' ``` ```json { "slug": "cpu-load", "name": "CPU Load", "content": { "template": "progress", "value": 0.42, "label": "load avg", "icon": "cpu", "accent_color": "cyan" }, "created_at": "2026-05-10T12:00:00Z", "updated_at": "2026-05-10T12:00:00Z" } ``` -------------------------------- ### Gauge update JSON example Source: https://pushward.app/docs/live-activities/gauge Example JSON payload for a gauge update with state 'ongoing', value 125, range 0-250, unit '°C', state 'Heating', icon 'thermometer.medium', and accent color 'orange'. ```json { "state": "ongoing", "content": { "template": "gauge", "value": 125, "min_value": 0, "max_value": 250, "unit": "°C", "state": "Heating", "icon": "thermometer.medium", "accent_color": "orange" } } ``` -------------------------------- ### Create the player activity with curl POST to /activities Source: https://pushward.app/docs/live-activities/media Creates the activity 'living-room-player' once with a bearer token. The same activity is then patched with player state. URL is https://api.pushward.app/activities; must include the 'Authorization: Bearer hlk_YOUR_TOKEN' header. ```shell curl -X POST https://api.pushward.app/activities \ -H "Authorization: Bearer hlk_YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slug": "living-room-player", "name": "Living Room" }' ``` -------------------------------- ### PATCH trend widget: p95 latency example Source: https://pushward.app/docs/widgets/templates/trend PATCH request body for the trend widget, showing a p95 latency example. The value is the current reading, points are the sparkline history (oldest first), and trend is an annotation, not derived from points. ```json { "content": { "template": "trend", "value": 371, "unit": "ms", "points": [312, 305, 298, 310, 322, 331, 340, 336, 329, 348, 355, 362, 371], "label": "p95 latency", "subtitle": "api-gateway · last hour", "icon": "waveform.path.ecg", "accent_color": "teal", "trend": "up" } } ``` -------------------------------- ### Create the approval activity Source: https://pushward.app/docs/live-activities/approval Initializes a new activity with the slug 'approval-request' using a POST request to the activities endpoint. ```bash curl -X POST https://api.pushward.app/activities \ -H "Authorization: Bearer hlk_YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slug": "approval-request", "name": "Approval Needed" }' ``` -------------------------------- ### Create activity with curl Source: https://pushward.app/docs/examples Creates a new activity with slug 'my-build' and name 'My Build'. Requires an integration key (replace hlk_YOUR_KEY). ```bash curl -X POST https://api.pushward.app/activities \ -H "Authorization: Bearer hlk_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"slug": "my-build", "name": "My Build"}' ``` -------------------------------- ### GET /activities/{slug} Source: https://pushward.app/docs/api/activities Retrieves a single activity by its slug. ```APIDOC ## GET /activities/{slug} ### Description Retrieves a single activity by its slug. ### Method GET ### Endpoint /activities/{slug} ### Parameters #### Path Parameters - **slug** (string) - Required - The unique identifier of the activity. ### Request Example curl https://api.pushward.app/activities/dishwasher \ -H "Authorization: Bearer hlk_YOUR_TOKEN" ### Response #### Success Response (200) - **activity** (object) - The activity object. #### Response Example { "slug": "dishwasher", "state": "ongoing", "content": {} } ``` -------------------------------- ### Live Progress with Duration Source: https://pushward.app/docs/live-activities/steps Enables live_progress and sets a duration to allow the UI to calculate and display an ETA for the current step. ```json { "state": "ongoing", "content": { "template": "steps", "state": "Heating water", "icon": "dishwasher", "subtitle": "Eco 50", "current_step": 2, "total_steps": 4, "step_labels": ["Pre-wash", "Wash", "Rinse", "Dry"], "step_weights": [1, 6, 1, 2], "live_progress": true, "duration": "90m", "accent_color": "teal" } } ``` -------------------------------- ### PATCH /widgets/cert-renewal countdown widget example Source: https://pushward.app/docs/widgets/templates/countdown Example request body for updating a countdown widget. The end_date must be after 2000-01-01 and no more than 366 days in the future; a past date counts up. The start_date must be strictly before end_date and adds a progress bar. The expired_text is shown after the end date passes, max 64 characters. ```json { "content": { "template": "countdown", "end_date": "2027-05-10T16:13:00Z", "start_date": "2027-05-10T13:00:00Z", "expired_text": "Renewing", "label": "Cert renewal", "subtitle": "api.pushward.app", "icon": "lock.shield.fill", "accent_color": "indigo" } } ``` -------------------------------- ### Free-Tier Quota Response Source: https://pushward.app/docs/api/activities Example of a 429 Too Many Requests response when the monthly quota is exceeded. ```http HTTP/1.1 429 Too Many Requests Content-Type: application/problem+json Retry-After: 1209600 { "type": "about:blank", "title": "Too Many Requests", "status": 429, "detail": "Monthly notification quota exceeded for the free tier.", "instance": "/notifications", "code": "quota.exceeded", "kind": "notifications", "used": 501, "limit": 500, "reset_at": "2026-06-01T00:00:00Z" } ``` -------------------------------- ### Create Activity with curl (POST /activities) Source: https://pushward.app/docs/api/activities Creates a new activity. Starts in 'ended' state. Requires an Authorization header with a bearer token. The request body must include 'slug' and 'name'; 'priority' is optional. Response is always 201 Created. ```bash curl -X POST https://api.pushward.app/activities \ -H "Authorization: Bearer hlk_YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slug": "dishwasher", "name": "Dishwasher", "priority": 3 }' ``` -------------------------------- ### Resolved Alert Example Source: https://pushward.app/docs/live-activities/alert A JSON payload representing a resolved alert with a single deep-link button. ```json { "state": "ended", "content": { "template": "alert", "progress": 1.0, "state": "Resolved — CPU usage normalized", "icon": "checkmark.circle.fill", "subtitle": "Grafana · nas-01", "severity": "critical", "accent_color": "green", "url": "https://grafana.example.com/alerting/1afz29v7z/edit" } } ``` -------------------------------- ### Start a countdown payload Source: https://pushward.app/docs/live-activities/countdown A JSON payload used to initiate a countdown timer with a 25-minute duration and an alarm enabled. ```json { "state": "ongoing", "content": { "template": "countdown", "progress": 0.0, "state": "Baking", "icon": "flame", "subtitle": "25 min timer", "duration": "25m", "warning_threshold": 60, "completion_message": "Done baking!", "accent_color": "orange", "alarm": true } } ``` -------------------------------- ### Follow the PushWard monitor log Source: https://pushward.app/docs/integrations/unraid Runs tail -f on the monitor log to follow Live Activity updates. Notification-delivery problems are logged to the Unraid system log under the pushward tag. ```bash tail -f /var/log/pushward-monitor.log ```