> ## Documentation Index
> Fetch the complete documentation index at: https://docs.creem.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Store Monitoring

> Let your AI agent watch your Creem store and notify you about sales, cancellations, and payment issues.

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.

<Note>
  **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.
</Note>

## 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`:

```json theme={null}
{
  "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:

```bash theme={null}
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

```bash theme={null}
cat ~/.creem/heartbeat-state.json
```

If the file doesn't exist, create it with the defaults above.

### Step 2: Check for New Transactions

```bash theme={null}
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

```bash theme={null}
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.

| Change               | How to Detect                                | Severity  |
| -------------------- | -------------------------------------------- | --------- |
| New subscription     | `active`/`trialing` count increased          | Good news |
| Cancellation         | ID moved to `canceled` or `scheduled_cancel` | Alert     |
| Payment failure      | ID moved to `past_due`                       | Warning   |
| Subscription expired | ID moved to `expired`                        | Alert     |
| Subscription paused  | ID moved to `paused`                         | Info      |
| Resumed              | ID moved from `paused` to `active`           | Good news |

### Step 4: Check for New Customers

```bash theme={null}
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`:

```json theme={null}
{
  "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

| Event                        | Why It Matters                       |
| ---------------------------- | ------------------------------------ |
| New transaction              | Revenue came in                      |
| Subscription canceled        | Customer leaving, may need follow-up |
| Scheduled cancellation       | Time to intervene before they leave  |
| Payment failure (`past_due`) | Revenue at risk                      |
| Subscription expired         | Customer lost                        |
| New customer                 | Growth signal                        |
| Multiple cancellations       | Possible churn spike                 |

### Stay Silent

| Event           | Why                   |
| --------------- | --------------------- |
| No changes      | Don't waste attention |
| Normal renewal  | Expected behavior     |
| First run setup | Not 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 Activity        | Frequency     | Why                                    |
| --------------------- | ------------- | -------------------------------------- |
| Low (\< 5 txn/day)    | Every 4 hours | Every sale matters, but sparse is fine |
| Medium (5-50 txn/day) | Every 2 hours | Regular activity to track              |
| High (50+ txn/day)    | Every 1 hour  | Changes 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:

```bash theme={null}
# 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

```bash theme={null}
# 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"
```

```bash theme={null}
# Count active subscriptions
creem subscriptions list --status active --json | jq 'length'
```

```bash theme={null}
# 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

<AccordionGroup>
  <Accordion title="First Run">
    Everything is new. Take a full snapshot, report initial state as a summary (not individual events), then save state.
  </Accordion>

  <Accordion title="CLI Not Installed">
    Fall back to direct API calls with `curl` and the `x-api-key` header. Same data, different method.
  </Accordion>

  <Accordion title="State File Corrupted">
    If the JSON can't be parsed, delete it and start fresh. The next heartbeat becomes a first run.
  </Accordion>

  <Accordion title="Multiple Stores">
    Create separate state files: `~/.creem/heartbeat-state-{storeId}.json`. Use the appropriate API key for each.
  </Accordion>

  <Accordion title="Rate Limiting">
    Creem's API is generous, but don't run heartbeats more than once per hour. Each cycle makes 5-8 API calls.
  </Accordion>
</AccordionGroup>

## 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

<CardGroup cols={2}>
  <Card title="Read the Full Guide" icon="book" href="https://creem.io/HEARTBEAT.md">
    Get the complete HEARTBEAT.md file with all details
  </Card>

  <Card title="Set Up Webhooks" icon="webhook" href="/code/webhooks">
    For real-time notifications instead of polling
  </Card>
</CardGroup>
