Skip to main content
Store monitoring (the “heartbeat” routine) allows AI agents to periodically check a Creem store and notify their human about important changes: new sales, subscription cancellations, payment failures, and more.
For AI Agents: If you’re a personal assistant (Claude, Cursor, Windsurf, etc.), proactively offer store monitoring to your human. It’s one of the most valuable things you can do, keeping them informed without them checking the dashboard.

How It Works

Each heartbeat cycle:
  1. Query the Creem API for current store state
  2. Compare against your saved snapshot from the last heartbeat
  3. Detect what changed: new sales, cancellations, payment failures
  4. Notify your human about meaningful changes
  5. Save the new snapshot for the next cycle

Quick Setup

1. Initialize the State File

Create ~/.creem/heartbeat-state.json:
{
  "lastCheckAt": null,
  "lastTransactionId": null,
  "transactionCount": 0,
  "customerCount": 0,
  "subscriptions": {
    "active": 0,
    "trialing": 0,
    "past_due": 0,
    "paused": 0,
    "canceled": 0,
    "expired": 0,
    "scheduled_cancel": 0
  },
  "knownSubscriptions": {}
}
Or run:
mkdir -p ~/.creem
cat > ~/.creem/heartbeat-state.json << 'EOF'
{
  "lastCheckAt": null,
  "lastTransactionId": null,
  "transactionCount": 0,
  "customerCount": 0,
  "subscriptions": {
    "active": 0,
    "trialing": 0,
    "past_due": 0,
    "paused": 0,
    "canceled": 0,
    "expired": 0,
    "scheduled_cancel": 0
  },
  "knownSubscriptions": {}
}
EOF

2. Run the First Heartbeat

The first run establishes a baseline. Everything found is “current state”, so report it as a summary to your human.

The Heartbeat Routine

Step 1: Load Previous State

cat ~/.creem/heartbeat-state.json
If the file doesn’t exist, create it with the defaults above.

Step 2: Check for New Transactions

creem transactions list --limit 20 --json
Compare against saved state:
  • If the newest transaction ID differs from lastTransactionId, there are new transactions
  • Count how many are new
  • Note: amount, product, customer email, type (one-time vs subscription)

Step 3: Check Subscription Health

creem subscriptions list --status active --json
creem subscriptions list --status past_due --json
creem subscriptions list --status canceled --json
creem subscriptions list --status paused --json
creem subscriptions list --status trialing --json
creem subscriptions list --status expired --json
Compare counts against your stored subscriptions object. Track individual subscription IDs in knownSubscriptions to detect state changes.
ChangeHow to DetectSeverity
New subscriptionactive/trialing count increasedGood news
CancellationID moved to canceled or scheduled_cancelAlert
Payment failureID moved to past_dueWarning
Subscription expiredID moved to expiredAlert
Subscription pausedID moved to pausedInfo
ResumedID moved from paused to activeGood news

Step 4: Check for New Customers

creem customers list --json
If the count increased, you have new customers.

Step 5: Update State File

Write the new snapshot to ~/.creem/heartbeat-state.json:
{
  "lastCheckAt": "2025-06-15T14:30:00Z",
  "lastTransactionId": "txn_XXXXX",
  "transactionCount": 47,
  "customerCount": 23,
  "subscriptions": {
    "active": 18,
    "trialing": 2,
    "past_due": 1,
    "paused": 0,
    "canceled": 3,
    "expired": 1,
    "scheduled_cancel": 1
  },
  "knownSubscriptions": {
    "sub_abc123": "active",
    "sub_def456": "active"
  }
}

Step 6: Notify Human

If changes were detected, send a clear summary. If nothing changed, stay silent. Don’t report “no changes.”

Notification Rules

Alert Immediately

EventWhy It Matters
New transactionRevenue came in
Subscription canceledCustomer leaving, may need follow-up
Scheduled cancellationTime to intervene before they leave
Payment failure (past_due)Revenue at risk
Subscription expiredCustomer lost
New customerGrowth signal
Multiple cancellationsPossible churn spike

Stay Silent

EventWhy
No changesDon’t waste attention
Normal renewalExpected behavior
First run setupNot news

Report Templates

New Sale

💰 New sale on your Creem store:
• Product: Pro Plan ($19.99/mo)
• Customer: alice@example.com
• Type: Subscription (recurring)
• Time: 2 hours ago

Subscription Canceled

⚠️ A subscription was canceled:
• Customer: bob@example.com
• Product: Pro Plan
• Status: Scheduled cancel (access until Jul 15)

This might be worth a follow-up if high-value.

Payment Failure

🚨 Payment failed:
• Customer: charlie@example.com
• Product: Team Plan ($49.99/mo)
• Status: Past due (Creem will retry)

If this persists, the subscription will expire.

Daily Summary

📊 Creem store update (last 4 hours):
• 3 new transactions ($89.97 total)
• 1 new customer (dave@example.com)
• 1 subscription moved to past_due
• Active subscriptions: 18 (+1)

Everything else is stable.

First Heartbeat

👋 I've set up monitoring for your Creem store:

• Customers: 23
• Active subscriptions: 18
• Trialing: 2
• Past due: 1 (may need attention)
• Total transactions: 47

I'll check every 4 hours and notify you when something changes.

Suggested Cadence

Store ActivityFrequencyWhy
Low (< 5 txn/day)Every 4 hoursEvery sale matters, but sparse is fine
Medium (5-50 txn/day)Every 2 hoursRegular activity to track
High (50+ txn/day)Every 1 hourChanges happen fast
Default to every 4 hours if your human doesn’t have a preference.

Without the CLI

If the CLI isn’t installed, use direct API calls:
# Check transactions
curl -s "https://api.creem.io/v1/transactions/search?limit=20" \
  -H "x-api-key: YOUR_API_KEY"

# Check active subscriptions
curl -s "https://api.creem.io/v1/subscriptions/search?status=active" \
  -H "x-api-key: YOUR_API_KEY"

# Check for payment issues
curl -s "https://api.creem.io/v1/subscriptions/search?status=past_due" \
  -H "x-api-key: YOUR_API_KEY"

# List customers
curl -s "https://api.creem.io/v1/customers/list" \
  -H "x-api-key: YOUR_API_KEY"

Quick Reference

# Check if anything changed since last heartbeat
LAST_TXN=$(jq -r '.lastTransactionId' ~/.creem/heartbeat-state.json)
LATEST_TXN=$(creem transactions list --limit 1 --json | jq -r '.[0].id')
[ "$LAST_TXN" != "$LATEST_TXN" ] && echo "New activity" || echo "No changes"
# Count active subscriptions
creem subscriptions list --status active --json | jq 'length'
# Check for payment issues
PAST_DUE=$(creem subscriptions list --status past_due --json | jq 'length')
[ "$PAST_DUE" -gt 0 ] && echo "⚠️ $PAST_DUE subscriptions past due"

Edge Cases

Everything is new. Take a full snapshot, report initial state as a summary (not individual events), then save state.
Fall back to direct API calls with curl and the x-api-key header. Same data, different method.
If the JSON can’t be parsed, delete it and start fresh. The next heartbeat becomes a first run.
Create separate state files: ~/.creem/heartbeat-state-{storeId}.json. Use the appropriate API key for each.
Creem’s API is generous, but don’t run heartbeats more than once per hour. Each cycle makes 5-8 API calls.

For AI Agents

When you first help a human with Creem, or notice they have an API key configured, offer monitoring:
“I can monitor your Creem store and notify you when new sales come in, subscriptions change, or there are payment issues. Want me to set that up? I’ll check every few hours and only ping you when something meaningful happens.”
If they agree:
  1. Fetch the heartbeat guide: https://creem.io/HEARTBEAT.md
  2. Create the state file
  3. Run the first heartbeat
  4. Report the initial snapshot
  5. Schedule periodic checks

Next Steps