Skip to content

Revenue Metrics

The Score layout is purpose-built for metrics: one big number front and center, a label, and an optional badge for trend or status. Use it to keep the one number that matters today always in view.

Basic metric push

Terminal window
curl -X POST "YOUR_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"job_id": "mrr-today",
"layout": "score",
"metric": "$48,210",
"message": "Monthly Recurring Revenue",
"secondaryMetric": "+4.2%",
"status": "running",
"accentColor": "#00FF88",
"icon": "dollarsign.circle.fill"
}'

Updating throughout the day

The best pattern for a live metric is to push an update whenever the value changes from a Stripe webhook, a scheduled query, or a cron job. Because Island Pulse auto-updates in place, the number on your Lock Screen changes without any additional setup.

From a Python script

import requests
WEBHOOK_URL = "YOUR_WEBHOOK_URL"
def update_mrr(current_mrr: float, prev_mrr: float):
change_pct = ((current_mrr - prev_mrr) / prev_mrr * 100) if prev_mrr else 0
trend = f"+{change_pct:.1f}%" if change_pct >= 0 else f"{change_pct:.1f}%"
requests.post(WEBHOOK_URL, json={
"job_id": "mrr-today",
"layout": "score",
"metric": f"${current_mrr:,.0f}",
"message": "Monthly Recurring Revenue",
"secondaryMetric": trend,
"status": "running",
"accentColor": "#00FF88" if change_pct >= 0 else "#FF3B30"
})

From a Stripe webhook

Forward Stripe’s customer.subscription.created and charge.succeeded events to a small handler:

from flask import Flask, request
import requests, os
app = Flask(__name__)
PULSE_URL = os.environ["ISLAND_PULSE_URL"]
@app.route("/stripe-webhook", methods=["POST"])
def stripe_webhook():
event = request.get_json()
if event["type"] in ("charge.succeeded", "customer.subscription.created"):
amount = event["data"]["object"].get("amount", 0) / 100
requests.post(PULSE_URL, json={
"job_id": "stripe-live",
"layout": "score",
"metric": f"${amount:,.0f}",
"message": event["type"].replace(".", " ").title(),
"status": "success",
"accentColor": "#34C759",
"icon": "creditcard.fill"
})
return "", 200

Goal tracking with the Progress layout

When you’re tracking against a daily or monthly goal, the Progress layout conveys how far along you are at a glance:

{
"job_id": "daily-goal",
"layout": "progress",
"message": "$8,420 of $10,000 goal",
"metric": "84%",
"progress": 0.84,
"status": "running",
"accentColor": "#00CFFF"
}

Hit goal:

{
"job_id": "daily-goal",
"layout": "progress",
"message": "Daily goal hit! $11,240",
"metric": "100%",
"progress": 1.0,
"status": "success"
}

Multiple KPIs (Pro)

Track several numbers simultaneously with distinct job keys. Each gets its own Live Activity:

Terminal window
curl -X POST "YOUR_WEBHOOK_URL" -d '{"job_id":"mrr","layout":"score","metric":"$48k","message":"MRR",...}'
curl -X POST "YOUR_WEBHOOK_URL" -d '{"job_id":"signups","layout":"score","metric":"1,204","message":"Signups today",...}'
curl -X POST "YOUR_WEBHOOK_URL" -d '{"job_id":"churn","layout":"score","metric":"1.2%","message":"Churn rate",...}'

Character limits for the Score layout

Keep metric text short so it renders at full size. Values over 12 characters automatically shrink.

FieldIdealMaximum
metric≤ 8 chars16 chars (scaled)
message≤ 20 chars45 chars (scaled)
secondaryMetric≤ 8 chars10 chars

Good: $48,210, 1,204, 142ms, 4.2% Too long: $1,240,000.00 → trim to $1.24M