creem
Creem simplifies payment processing and subscription management for SaaS businesses, ensuring global tax compliance and financial infrastructure.
Install this skill
Security score
The creem skill was audited on Mar 26, 2026 and we found 32 security issues across 4 threat categories. Review the findings below before installing.
Categories Tested
Security Issues
Command substitution pattern
| 668 | # Run daily to alert on problem subscriptions |
| 669 | |
| 670 | PAST_DUE=$(creem subscriptions list --status past_due --json | jq 'length') |
| 671 | EXPIRED=$(creem subscriptions list --status expired --json | jq 'length') |
| 672 |
Command substitution pattern
| 669 | |
| 670 | PAST_DUE=$(creem subscriptions list --status past_due --json | jq 'length') |
| 671 | EXPIRED=$(creem subscriptions list --status expired --json | jq 'length') |
| 672 | |
| 673 | if [ "$PAST_DUE" -gt 0 ] || [ "$EXPIRED" -gt 0 ]; then |
Command substitution pattern
| 684 | |
| 685 | for PRODUCT_ID in prod_AAA prod_BBB prod_CCC; do |
| 686 | URL=$(creem checkouts create --product "$PRODUCT_ID" --json | jq -r '.checkout_url') |
| 687 | echo "$PRODUCT_ID: $URL" |
| 688 | done |
Curl to non-GitHub URL
| 79 | ```bash |
| 80 | mkdir -p ~/.creem/skills |
| 81 | curl -s https://creem.io/SKILL.md > ~/.creem/skills/SKILL.md |
| 82 | curl -s https://creem.io/HEARTBEAT.md > ~/.creem/skills/HEARTBEAT.md |
| 83 | ``` |
Curl to non-GitHub URL
| 80 | mkdir -p ~/.creem/skills |
| 81 | curl -s https://creem.io/SKILL.md > ~/.creem/skills/SKILL.md |
| 82 | curl -s https://creem.io/HEARTBEAT.md > ~/.creem/skills/HEARTBEAT.md |
| 83 | ``` |
| 84 |
Curl to non-GitHub URL
| 907 | # Save the heartbeat guide locally |
| 908 | mkdir -p ~/.creem/skills |
| 909 | curl -s https://creem.io/HEARTBEAT.md > ~/.creem/skills/HEARTBEAT.md |
| 910 | |
| 911 | # Initialize the state file |
Curl to non-GitHub URL
| 955 | ```bash |
| 956 | # Check recent transactions |
| 957 | curl -s "https://api.creem.io/v1/transactions/search?limit=20" \ |
| 958 | -H "x-api-key: YOUR_API_KEY" |
| 959 |
Curl to non-GitHub URL
| 959 | |
| 960 | # Check active subscriptions |
| 961 | curl -s "https://api.creem.io/v1/subscriptions/search?status=active" \ |
| 962 | -H "x-api-key: YOUR_API_KEY" |
| 963 |
Curl to non-GitHub URL
| 963 | |
| 964 | # Check for payment issues |
| 965 | curl -s "https://api.creem.io/v1/subscriptions/search?status=past_due" \ |
| 966 | -H "x-api-key: YOUR_API_KEY" |
| 967 |
Curl to non-GitHub URL
| 967 | |
| 968 | # List customers |
| 969 | curl -s "https://api.creem.io/v1/customers/list" \ |
| 970 | -H "x-api-key: YOUR_API_KEY" |
| 971 | ``` |
Access to home directory dotfiles
| 78 | |
| 79 | ```bash |
| 80 | mkdir -p ~/.creem/skills |
| 81 | curl -s https://creem.io/SKILL.md > ~/.creem/skills/SKILL.md |
| 82 | curl -s https://creem.io/HEARTBEAT.md > ~/.creem/skills/HEARTBEAT.md |
Access to home directory dotfiles
| 79 | ```bash |
| 80 | mkdir -p ~/.creem/skills |
| 81 | curl -s https://creem.io/SKILL.md > ~/.creem/skills/SKILL.md |
| 82 | curl -s https://creem.io/HEARTBEAT.md > ~/.creem/skills/HEARTBEAT.md |
| 83 | ``` |
Access to home directory dotfiles
| 80 | mkdir -p ~/.creem/skills |
| 81 | curl -s https://creem.io/SKILL.md > ~/.creem/skills/SKILL.md |
| 82 | curl -s https://creem.io/HEARTBEAT.md > ~/.creem/skills/HEARTBEAT.md |
| 83 | ``` |
| 84 |
Access to home directory dotfiles
| 728 | ``` |
| 729 | |
| 730 | **CRITICAL:** Never share your API key with any service, tool, or agent other than the Creem CLI or API. Keys are stored locally at `~/.creem/config.json`. |
| 731 | |
| 732 | --- |
Access to home directory dotfiles
| 906 | ```bash |
| 907 | # Save the heartbeat guide locally |
| 908 | mkdir -p ~/.creem/skills |
| 909 | curl -s https://creem.io/HEARTBEAT.md > ~/.creem/skills/HEARTBEAT.md |
| 910 |
Access to home directory dotfiles
| 907 | # Save the heartbeat guide locally |
| 908 | mkdir -p ~/.creem/skills |
| 909 | curl -s https://creem.io/HEARTBEAT.md > ~/.creem/skills/HEARTBEAT.md |
| 910 | |
| 911 | # Initialize the state file |
Access to home directory dotfiles
| 910 | |
| 911 | # Initialize the state file |
| 912 | mkdir -p ~/.creem |
| 913 | cat > ~/.creem/heartbeat-state.json << 'EOF' |
| 914 | { |
Access to home directory dotfiles
| 911 | # Initialize the state file |
| 912 | mkdir -p ~/.creem |
| 913 | cat > ~/.creem/heartbeat-state.json << 'EOF' |
| 914 | { |
| 915 | "lastCheckAt": null, |
Access to home directory dotfiles
| 981 | - **Ask questions when you're unsure.** It's always better to ask "Do you already have a Creem account?" than to guess wrong. |
| 982 | - **Offer store monitoring proactively.** If your human has a Creem store, suggest setting up the heartbeat. Fetch `https://creem.io/HEARTBEAT.md` and follow the routine. They'll appreciate knowing about new sales and issues without checking the dashboard. |
| 983 | - **Save these skill files locally.** Persist `SKILL.md` and `HEARTBEAT.md` in `~/.creem/skills/` so you can reference them without re-fetching every time. |
| 984 | |
| 985 | ### When working with the API or CLI |
Webhook reference
| 178 | | ------------------ | ----------------------- | ------------------------------------------------------------------------ | |
| 179 | | TypeScript Core | `creem` | Full API coverage, all 24 endpoints, standalone functions, tree-shakable | |
| 180 | | TypeScript Wrapper | `creem_io` | Simplified API, webhook verification, access grant/revoke callbacks | |
| 181 | | Next.js Adapter | `@creem_io/nextjs` | React components, route handlers, lifecycle hooks | |
| 182 | | Better Auth Plugin | `@creem_io/better-auth` | Auth framework integration, subscription sync, trial abuse prevention | |
Webhook reference
| 267 | Option A: **Webhooks** (recommended for production) |
| 268 | |
| 269 | Register a webhook endpoint in the dashboard and handle the `checkout.completed` event. For subscriptions, use `subscription.paid` to grant access and `subscription.expired` to revoke it. See the [Webhooks section](#webhooks) below. |
| 270 | |
| 271 | Option B: **Polling** (simple scripts or CLI workflows) |
Webhook reference
| 281 | **Step 4 — Grant access in your application** |
| 282 | |
| 283 | After receiving a `checkout.completed` or `subscription.paid` webhook, use the `metadata.referenceId` to map the payment to your internal user and grant access. |
| 284 | |
| 285 | ### Flow 2: Manage subscription lifecycle |
Webhook reference
| 421 | ### Signature verification |
| 422 | |
| 423 | Webhooks are signed with HMAC-SHA256. Verify the `creem-signature` header against the raw request body using your webhook secret. |
| 424 | |
| 425 | ```typescript |
Webhook reference
| 443 | Failed deliveries (non-200 responses) are retried: **30s → 1m → 5m → 1h**. Webhooks can also be manually resent from the dashboard. |
| 444 | |
| 445 | ### SDK webhook handlers |
| 446 | |
| 447 | The SDKs provide convenience wrappers with `onGrantAccess` / `onRevokeAccess` callbacks: |
Webhook reference
| 448 | |
| 449 | ```typescript |
| 450 | // Next.js App Router — app/api/webhook/creem/route.ts |
| 451 | import { Webhook } from "@creem_io/nextjs"; |
| 452 |
Webhook reference
| 449 | ```typescript |
| 450 | // Next.js App Router — app/api/webhook/creem/route.ts |
| 451 | import { Webhook } from "@creem_io/nextjs"; |
| 452 | |
| 453 | export const POST = Webhook({ |
Webhook reference
| 451 | import { Webhook } from "@creem_io/nextjs"; |
| 452 | |
| 453 | export const POST = Webhook({ |
| 454 | webhookSecret: process.env.CREEM_WEBHOOK_SECRET!, |
| 455 | onGrantAccess: async ({ customer, metadata }) => { |
Webhook reference
| 496 | > `onGrantAccess` fires for: `subscription.active`, `subscription.trialing`, `subscription.paid` > `onRevokeAccess` fires for: `subscription.paused`, `subscription.expired` |
| 497 | |
| 498 | ### Webhook payload structure |
| 499 | |
| 500 | ```json |
Webhook reference
| 509 | ``` |
| 510 | |
| 511 | > Full webhook reference: <https://docs.creem.io/code/webhooks> |
| 512 | |
| 513 | --- |
Webhook reference
| 628 | ``` |
| 629 | |
| 630 | Webhook URL for Better Auth: `https://your-domain.com/api/auth/creem/webhook` |
| 631 | |
| 632 | > Automatic trial abuse prevention when `persistSubscriptions: true` — each user can only receive one trial across all plans. |
Webhook reference
| 689 | ``` |
| 690 | |
| 691 | ### Programmatic access control (webhook-driven) |
| 692 | |
| 693 | The recommended pattern for SaaS access control: |
Webhook reference
| 694 | |
| 695 | 1. Pass `referenceId` (your internal user ID) when creating checkouts |
| 696 | 2. Handle `subscription.paid` webhook → grant access using `metadata.referenceId` |
| 697 | 3. Handle `subscription.expired` / `subscription.paused` → revoke access |
| 698 | 4. Handle `subscription.canceled` → revoke access (or keep until period end if `scheduled_cancel`) |
Install this skill with one command
/learn @creem-io/creem