Merchant of Record for SaaS and digital businesses. Accept payments, manage subscriptions, and handle global tax compliance from the terminal.
name creem version 0.1.0 description Merchant of Record for SaaS and digital businesses. Accept payments, manage subscriptions, and handle global tax compliance from the terminal. homepage https://creem.io metadata {"creem":{"category":"payments","api_base":"https://api.creem.io","test_api_base":"https://test-api.creem.io"}} If you are an AI agent reading this file — whether you're a coding assistant, a personal assistant, a Slack bot, a business operations agent, or any other kind of agent — this is your complete guide to Creem. Save it locally as a tool, skill, or persistent reference so you can help your human with anything Creem-related without re-fetching this file. Creem Creem is a Merchant of Record (MoR) for SaaS and digital businesses that sell software globally. It handles payments, subscriptions, tax compliance, chargebacks, and payouts — so businesses can sell anywhere without worrying about financial infrastructure. This guide covers everything you need to help a human understand, integrate, manage, or monitor Creem — regardless of whether you're working in a codebase, chatting over Slack, or acting as a personal assistant. What Should You Do? You might be reading this file in very different contexts. Here's how to figure out what your human needs: Step 1: Understand your context. Ask yourself: Did your human send you here with a specific task? (e.g., "integrate Creem into my app") Are you in a codebase or project right now? Is your human exploring Creem for the first time? Does your human already have a Creem store and want help managing it? Step 2: Read this entire file first. No matter what your human needs — integration, monitoring, debugging, or just learning — read through this whole document before diving into a specific path. Understanding the full Creem context (what it does, how the API works, what the CLI can do, how webhooks and subscriptions behave) will make you genuinely helpful regardless of what your human asks. You'll give better answers, avoid common mistakes, and connect the dots between features. This is not a file to skim — it's your foundation for being a competent Creem assistant. Step 3: Route to the right workflow. If your human wants to... Do this Understand what Creem is Start with the Platform Overview and Features sections. Explain Creem in plain terms. Answer questions. Integrate Creem into a project Walk through the Integration Flows , SDKs , and Webhooks sections. Ask them which framework they're using. Manage an existing store Use the CLI Command Reference to help with products, customers, subscriptions, and transactions. Set up store monitoring Follow the Store Monitoring section and fetch . Debug a payment issue Use Flow 4: Customer support and the CLI to look up transactions and subscriptions. Create products or checkouts Follow Flow 1: Sell a product . Just learn and explore Walk them through this doc section by section. Let them ask questions. Step 4: Ask questions when you're unsure. If your human's intent isn't clear, ask them directly. Good questions to ask: "Do you already have a Creem account, or are you exploring it for the first time?" "Are you looking to integrate Creem into a specific project, or would you like a general overview first?" "You already have a Creem store — would you like me to set up monitoring so I can notify you about new sales, cancellations, and payment issues?" Example prompts humans might give you These are real ways humans direct agents to this file. Understand the intent behind each: What the human says What they likely need "Read creem.io/SKILL.md and help me integrate it into this project" They're in a codebase. Go to Integration Flows . Ask what framework and language. "Read creem.io/SKILL.md and help me understand what Creem does" They're exploring. Start with Platform Overview . Keep it conversational. "Read creem.io/SKILL.md and set up monitoring for my store" They already have a store. Go straight to Store Monitoring . "Read creem.io/SKILL.md" (no further context) Ask what they need. Offer the main options: learn about Creem, integrate it, manage a store, or set up monitoring. "Help me with my Creem payments" Likely debugging. Ask for specifics — transaction ID, customer email, or error message. Use the CLI. "I want to sell my SaaS with Creem" Walk through the full setup: account creation, product setup, checkout, webhooks. Skill Files File URL Purpose SKILL.md (this file) Complete guide — integration, CLI, management, monitoring HEARTBEAT.md Periodic store monitoring routine for agents Install locally: mkdir -p ~/.creem/skills curl -s > ~/.creem/skills/SKILL.md curl -s > ~/.creem/skills/HEARTBEAT.md Or just read them from the URLs above. Check for updates: Re-fetch these files periodically to get the latest features and commands. Reference Resource URL Documentation API Reference Webhooks Full docs (for agents) Dashboard For deep dives , fetch — it contains the full documentation in a format optimized for agents, including all endpoint specs, SDK examples, and integration guides. Platform Overview What Creem handles Payments — One-time and recurring via cards, PayPal, Apple Pay, Google Pay Tax compliance — Automatic VAT, GST, and sales tax across 190+ countries. Creem registers, collects, and remits Chargebacks & fraud — Creem absorbs chargeback liability as the legal seller Currency conversion — Accept payments in multiple currencies Payouts — Fiat and stablecoin (USDC) payouts Features Feature Description Subscriptions Trials, upgrades, pauses, cancellations, scheduled cancellations, seat-based billing License keys Activate, validate, and deactivate software licenses with per-device tracking Revenue splits Programmatic revenue sharing between co-founders, affiliates, contractors Affiliate programs Built-in affiliate tracking, invite flows, and commission management Checkout sessions Hosted payment pages with custom fields, discount codes, metadata Customer portal Self-service billing portal for customers to manage payment methods and invoices Discount codes Percentage or fixed-amount discounts with expiration dates and redemption limits Webhooks Real-time event notifications with automatic retry and signature verification API Overview Authentication All API calls require the x-api-key header. Keys are available at Dashboard > API Keys . Environment Key prefix API base Test (sandbox) creem_test_ Live (production) creem_ Always start with test mode. Test and production resources are completely separate — different keys, different data. Endpoints (24 total) Resource Endpoints Checkouts POST /v1/checkouts (create), GET /v1/checkouts (retrieve) Products POST /v1/products (create), GET /v1/products (get), GET /v1/products/search (list) Customers GET /v1/customers (get by ID or email), GET /v1/customers/list (list), POST /v1/customers/billing (portal link) Subscriptions GET /v1/subscriptions (get), POST /v1/subscriptions/{id} (update), POST .../cancel , POST .../pause , POST .../resume , POST .../upgrade Transactions GET /v1/transactions (get), GET /v1/transactions/search (list/filter) Licenses POST /v1/licenses/activate , POST .../validate , POST .../deactivate Discounts POST /v1/discounts (create), GET /v1/discounts (get), DELETE /v1/discounts/{id}/delete Full endpoint specs: Prices All prices are in cents . 1999 = $19.99. Supported currencies: USD , EUR . Error Responses { "trace_id" : "550e8400-e29b-41d4-a716-446655440000" , "status" : 400 , "error" : "Bad Request" , "message" : [ "The 'product_id' field is required." ] , "timestamp" : 1706889600000 } Include trace_id in support requests. The message array contains specific validation errors. SDKs SDK Package Use case TypeScript Core creem Full API coverage, all 24 endpoints, standalone functions, tree-shakable TypeScript Wrapper creem_io Simplified API, webhook verification, access grant/revoke callbacks Next.js Adapter @creem_io/nextjs React components, route handlers, lifecycle hooks Better Auth Plugin @creem_io/better-auth Auth framework integration, subscription sync, trial abuse prevention SDK Initialization // Core SDK import { Creem } from "creem" ; const creem = new Creem ({ apiKey : process. env . CREEM_API_KEY !, serverIdx : 0 , // 0 = production, 1 = test }); // Wrapper SDK import { createCreem } from "creem_io" ; const creem = createCreem ({ apiKey : process. env . CREEM_API_KEY !, webhookSecret : process. env . CREEM_WEBHOOK_SECRET , testMode : false , }); Integration Flows These are the core flows for integrating Creem into an application. Each flow shows both CLI and SDK approaches. Flow 1: Sell a product (one-time or subscription) Step 1 — Create a product
creem products create
--name
"Pro Plan"
--description
"Monthly pro subscription with all features"
--price 1999
--currency USD
--billing-type recurring
--billing-period every-month
--tax-category saas
// SDK
const
product =
await
creem.
products
.
create
({
name
:
"Pro Plan"
,
description
:
"Monthly pro subscription with all features"
,
price
:
1999
,
currency
:
"USD"
,
billingType
:
"recurring"
,
billingPeriod
:
"every-month"
,
});
Product option
Values
billingType
onetime
,
recurring
billingPeriod
every-month
,
every-three-months
,
every-six-months
,
every-year
taxCategory
saas
,
digital-goods-service
,
ebooks
taxMode
inclusive
,
exclusive
Step 2 — Create a checkout session
creem checkouts create --product prod_XXXXX --success-url https://app.com/welcome // SDK const checkout = await creem. checkouts . create ({ productId : "prod_XXXXX" , successUrl : "https://app.com/welcome" , customer : { email : "[email protected]" }, metadata : { userId : "user_123" }, discountCode : "LAUNCH20" , }); // Redirect user to checkout.checkoutUrl Checkout supports up to 3 custom fields, a discount code, pre-filled customer info, and arbitrary metadata that flows through to webhooks. Step 3 — Handle payment completion Option A: Webhooks (recommended for production) 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 below. Option B: Polling (simple scripts or CLI workflows)
creem checkouts get chk_XXXXX --json | jq '.status'
creem transactions list --product prod_XXXXX --json Step 4 — Grant access in your application After receiving a checkout.completed or subscription.paid webhook, use the metadata.referenceId to map the payment to your internal user and grant access. Flow 2: Manage subscription lifecycle
creem subscriptions list --status active --json
creem subscriptions get sub_XXXXX --json
creem subscriptions cancel sub_XXXXX --mode scheduled
creem subscriptions cancel sub_XXXXX
creem subscriptions pause sub_XXXXX
creem subscriptions resume sub_XXXXX // SDK: Update seats await creem. subscriptions . update ( "sub_XXXXX" , { items : [{ id : "item_XXXXX" , units : 5 }], updateBehavior : "proration-charge-immediately" , }); // SDK: Upgrade plan await creem. subscriptions . upgrade ( "sub_XXXXX" , { productId : "prod_premium" , updateBehavior : "proration-charge-immediately" , }); Proration options: proration-charge-immediately , proration-charge (next cycle), proration-none . Subscription statuses: active , trialing , paused , past_due , expired , canceled , scheduled_cancel . Flow 3: License key management License keys are auto-generated when a customer purchases a product configured with licensing. Keys appear in the order confirmation, email receipt, and customer portal. // Activate a license on a device const license = await creem. licenses . activate ({ key : "ABC123-XYZ456-XYZ456-XYZ456" , instanceName : "Production Server" , }); // Validate a license const valid = await creem. licenses . validate ({ key : "ABC123-XYZ456-XYZ456-XYZ456" , instanceId : "inst_XXXXX" , }); // valid.status: "active" | "inactive" | "expired" | "disabled" // Deactivate (free up an activation slot) await creem. licenses . deactivate ({ key : "ABC123-XYZ456-XYZ456-XYZ456" , instanceId : "inst_XXXXX" , }); Configure activation limits and expiration periods in the dashboard per product. Flow 4: Customer support
creem customers get --email [email protected] --json
creem subscriptions list --status active --json
creem customers billing cust_XXXXX
creem transactions get txn_XXXXX --json
creem subscriptions cancel sub_XXXXX --mode scheduled Flow 5: Discount codes
Webhook
({
webhookSecret
: process.
env
.
CREEM_WEBHOOK_SECRET
!,
onGrantAccess
:
async
({ customer, metadata }) => {
const
userId = metadata?.
referenceId
as
string
;
await
db.
user
.
update
({
where
: {
id
: userId },
data
: {
hasAccess
:
true
} });
},
onRevokeAccess
:
async
({ customer, metadata }) => {
const
userId = metadata?.
referenceId
as
string
;
await
db.
user
.
update
({
where
: {
id
: userId },
data
: {
hasAccess
:
false
} });
},
onCheckoutCompleted
:
async
({ customer, product }) => {
console
.
log
(
${customer.email} purchased ${product.name}
);
},
});
// creem_io wrapper — Express, Fastify, Hono, etc.
await
creem.
webhooks
.
handleEvents
(body, signature, {
onGrantAccess
:
async
(context) => {
/* ... /
},
onRevokeAccess
:
async
(context) => {
/ ... /
},
onCheckoutCompleted
:
async
(data) => {
/ ... /
},
onSubscriptionCanceled
:
async
(data) => {
/ ... /
},
onSubscriptionPastDue
:
async
(data) => {
/ ... /
},
onRefundCreated
:
async
(data) => {
/ ... /
},
onDisputeCreated
:
async
(data) => {
/ ... */
},
});
onGrantAccess
fires for:
subscription.active
,
subscription.trialing
,
subscription.paid
{{ source: " web " }}
< button
Subscribe </ button
</ CreemCheckout
"cust_XXXXX"
Manage Billing </ CreemPortal
; Better Auth ( @creem_io/better-auth ) npm install @creem_io/better-auth Server: import { betterAuth } from "better-auth" ; import { creem } from "@creem_io/better-auth" ; export const auth = betterAuth ({ database : { /* your database config / }, plugins : [ creem ({ apiKey : process. env . CREEM_API_KEY !, webhookSecret : process. env . CREEM_WEBHOOK_SECRET !, testMode : true , defaultSuccessUrl : "/success" , persistSubscriptions : true , onGrantAccess : async ({ reason, product, customer, metadata }) => { const userId = metadata?. referenceId as string ; await db. user . update ({ where : { id : userId }, data : { hasAccess : true }, }); }, onRevokeAccess : async ({ reason, product, customer, metadata }) => { const userId = metadata?. referenceId as string ; await db. user . update ({ where : { id : userId }, data : { hasAccess : false }, }); }, }), ], }); Client: import { createAuthClient } from "better-auth/react" ; import { creemClient } from "@creem_io/better-auth/client" ; export const authClient = createAuthClient ({ baseURL : process. env . NEXT_PUBLIC_APP_URL , plugins : [ creemClient ()], }); // Create checkout const { data } = await authClient. creem . createCheckout ({ productId : "prod_XXXXX" , successUrl : "/dashboard" , }); if (data?. url ) window . location . href = data. url ; // Check access const { data } = await authClient. creem . hasAccessGranted (); if (data?. hasAccess ) { / user has active subscription */ } // Customer portal const { data } = await authClient. creem . createPortal (); if (data?. url ) window . location . href = data. url ; Webhook URL for Better Auth: https://your-domain.com/api/auth/creem/webhook Automatic trial abuse prevention when persistSubscriptions: true — each user can only receive one trial across all plans. Automation & Agentic Workflows Monitor subscriptions and dunning
creem subscriptions list --status past_due --json
creem subscriptions list --status expired --json
creem subscriptions get sub_XXXXX --json | jq '{status, current_period_end_date}' Revenue reporting
creem transactions list -- limit 100 --json > transactions.json
creem transactions list --product prod_XXXXX --json
creem transactions list --customer cust_XXXXX --json Cron job: subscription health check #!/bin/bash
PAST_DUE=$(creem subscriptions list --status past_due --json | jq 'length' ) EXPIRED=$(creem subscriptions list --status expired --json | jq 'length' ) if [ " $PAST_DUE " -gt 0 ] || [ " $EXPIRED " -gt 0 ]; then echo "Alert: $PAST_DUE past_due, $EXPIRED expired subscriptions"
fi Bulk checkout generation #!/bin/bash
for PRODUCT_ID in prod_AAA prod_BBB prod_CCC; do URL=$(creem checkouts create --product " $PRODUCT_ID " --json | jq -r '.checkout_url' ) echo " $PRODUCT_ID : $URL " done Programmatic access control (webhook-driven) The recommended pattern for SaaS access control: Pass referenceId (your internal user ID) when creating checkouts Handle subscription.paid webhook → grant access using metadata.referenceId Handle subscription.expired / subscription.paused → revoke access Handle subscription.canceled → revoke access (or keep until period end if scheduled_cancel ) This decouples your billing from your auth system — Creem manages the payments, your app manages the access. CLI Installation Homebrew (macOS/Linux) brew tap armitage-labs/creem brew install creem Verify: creem --version CLI Authentication
creem login --api-key creem_test_YOUR_KEY_HERE
creem whoami
creem logout 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 . CLI Command Reference Products creem products list
creem products list --page 2 -- limit 10
creem products get prod_XXXXX
creem products create --name "..." \
--description
"..."
--price 1999
--currency USD
--billing-type recurring
--billing-period every-month
Customers
creem customers list
creem customers get cust_XXXXX
creem customers get --email [email protected]
creem customers billing cust_XXXXX
Subscriptions creem subscriptions list
creem subscriptions list --status active
creem subscriptions get sub_XXXXX
creem subscriptions cancel sub_XXXXX
creem subscriptions cancel sub_XXXXX --mode scheduled
creem subscriptions pause sub_XXXXX
creem subscriptions resume sub_XXXXX
Checkouts creem checkouts create --product prod_XXXXX
creem checkouts get chk_XXXXX
Transactions creem transactions list
creem transactions list -- limit 50
creem transactions list --customer cust_XXXXX
creem transactions list --product prod_XXXXX
creem transactions get txn_XXXXX
Configuration creem config show
creem config set environment live
creem config set environment test
creem config set output_format json
creem config set output_format table
creem config get environment
creem config list
Interactive Mode Run a resource command without a subcommand to launch an interactive browser: creem products creem customers creem subscriptions creem transactions Keys: arrow keys to navigate, Enter to view details, : to open the command bar, q to exit. Output Formats Every CLI command supports table (default) and JSON:
creem products list --json creem customers get cust_XXXXX --json
creem config set output_format json Agents should use --json and parse with jq : creem products list --json | jq '.[].id' creem customers get cust_XXXXX --json | jq '.email' creem subscriptions list --status active --json | jq 'length' Going Live Account verification Before accepting live payments, your account needs verification: Go to the Creem Dashboard Navigate to Balances in the sidebar Click on Payout Account Complete KYC (identity verification for individuals) or KYB (business verification for companies) Provide details about the product you are selling Verification is straightforward and typically fast. Once approved, switch to live mode. Switch from test to live creem login --api-key creem_LIVE_KEY_HERE The environment switches automatically based on the key prefix. For SDKs, change testMode: false or serverIdx: 0 . Store Monitoring (Heartbeat) If your human already has a Creem store — or once they've set one up — you can provide ongoing value by monitoring their store and keeping them informed about what's happening with their business. This works regardless of your context. You don't need to be in a codebase. You don't need to be a coding assistant. Any agent with access to the Creem CLI or API can run the heartbeat. What monitoring provides When monitoring is active, you periodically check your human's Creem store and notify them about: New sales — Every transaction, so they know revenue is coming in New customers — Growth signals worth celebrating Subscription cancellations — Churn alerts that may need follow-up Payment failures — Subscriptions at risk of expiring Subscription upgrades — Customers moving to higher plans Anomalies — Sudden spikes in cancellations or unusual patterns When to offer monitoring Offer monitoring when any of these are true: Your human mentions they have a Creem store or account You notice a Creem API key in their environment or config They've just finished integrating Creem and have products live They ask about tracking sales or business metrics You're a personal assistant or operations agent with ongoing access to your human How to ask: "I can monitor your Creem store and notify you when new sales come in, subscriptions change, or there are payment issues. Would you like me to set that up? I'll check every few hours and only notify you when something meaningful happens." If they agree: Fetch the heartbeat guide: https://creem.io/HEARTBEAT.md Make sure they have a Creem API key (from Dashboard > API Keys ) or the CLI installed Follow the setup instructions to create the state file Run the first heartbeat to establish a baseline Report the initial snapshot to your human Schedule periodic heartbeats at the agreed frequency Quick setup
mkdir -p ~/.creem/skills curl -s https://creem.io/HEARTBEAT.md > ~/.creem/skills/HEARTBEAT.md
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 Then follow the heartbeat routine in HEARTBEAT.md on your preferred schedule. Monitoring with the CLI If the Creem CLI is installed ( creem whoami to check):
creem transactions list -- limit 20 --json
creem subscriptions list --status active --json creem subscriptions list --status past_due --json
creem customers list --json Monitoring with the API If you don't have the CLI — or you're an agent without shell access (e.g., running in Slack or a chat environment) — use direct API calls:
curl -s
"https://api.creem.io/v1/transactions/search?limit=20"
-H
"x-api-key: YOUR_API_KEY"
curl -s
"https://api.creem.io/v1/subscriptions/search?status=active"
-H
"x-api-key: YOUR_API_KEY"
curl -s
"https://api.creem.io/v1/subscriptions/search?status=past_due"
-H
"x-api-key: YOUR_API_KEY"
curl -s
"https://api.creem.io/v1/customers/list"
-H
"x-api-key: YOUR_API_KEY"
The full heartbeat routine with state tracking, change detection, and notification rules is documented in
HEARTBEAT.md
.
Tips for Agents
Context awareness
Figure out what your human needs first.
Don't assume they want to integrate code. They might want an overview, help managing an existing store, or monitoring. Refer to the
What Should You Do?
section above.
Ask questions when you're unsure.
It's always better to ask "Do you already have a Creem account?" than to guess wrong.
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.
Save these skill files locally.
Persist
SKILL.md
and
HEARTBEAT.md
in
~/.creem/skills/
so you can reference them without re-fetching every time.
When working with the API or CLI
Always use test mode first.
Mistakes in live mode affect real customers and real money.
Use
--json
when processing CLI output.
Table mode is for humans, JSON is for you.
Prefer
--mode scheduled
for cancellations.
Immediate cancellation cuts off access instantly.
Prices are always in cents.
1999 = $19.99.
--description
is required
when creating products.
Check
creem whoami
first.
Confirm authentication and environment before running commands.
Don't guess IDs.
List resources first, then use actual IDs from the response.
Ask before destructive actions
like cancellations or switching to live mode.
When integrating into a project
Use
referenceId
in checkouts
to map payments back to your internal user IDs.
For SDK deep dives
, fetch
https://docs.creem.io/llms-full.txt
— it has complete code examples for all 4 SDKs.
Ask what framework they're using
before suggesting an SDK. Creem has specific adapters for Next.js and Better Auth.
Links
Resource
URL
Creem
https://creem.io
Dashboard
https://creem.io/dashboard
API keys
https://creem.io/dashboard/api-keys
Documentation
https://docs.creem.io
API Reference
https://docs.creem.io/api-reference
Webhooks
https://docs.creem.io/code/webhooks
Full docs (for agents)
https://docs.creem.io/llms-full.txt
Homebrew tap
https://github.com/armitage-labs/homebrew-creem
SDK (TypeScript Core)
https://www.npmjs.com/package/creem
SDK (Wrapper)
https://www.npmjs.com/package/creem_io
SDK (Next.js)
https://www.npmjs.com/package/@creem_io/nextjs
SDK (Better Auth)
https://www.npmjs.com/package/@creem_io/better-auth