Creem integration

Creem analytics: MRR, churn and revenue by traffic source

BugOtter reads your Creem store and shows what each app earns, net of the tax Creem collects: MRR and how it moved, revenue after refunds, trials, cancellations and declined payments. Pass the visit id in your checkout's metadata and subscriptions are linked to the traffic source that brought them.

  • Net of taxrevenue and MRR
  • Test modecreem_test_ keys
  • Every 15 minsync

Three things to know

  • Net of tax

    Creem is the merchant of record. Its tax is subtracted from both revenue and MRR.
  • Subscribers by source

    Add the visit id to the checkout's metadata, and every renewal keeps its source.
  • Try it in test mode

    A creem_test_ key reads Creem's test API and is labelled Test mode.

Connect Creem

Copy one key. Test keys work the same way.

  1. Copy your API key

    In Creem, open Developers → API keys.
    Live keycreem_…
  2. Paste it on Revenue

    BugOtter checks the key by reading one product, then stores it encrypted.
  3. Let the first sync run

    Every product and subscription, and 90 days of transactions.
  4. Match products to apps

    BugOtter suggests an app for each product from its URL and name. Confirm it once.
  • Live keys start with creem_. For test mode, flip the test mode switch in Creem's sidebar first; that key starts with creem_test_.
  • Only the key's last 4 characters are shown. A test key is labelled Test mode and read from Creem's separate test API.
  • Once matched, that product's revenue, MRR and declined payments land on the right app.

Every 15 min

After the first sync, it repeats every 15 minutes.

Or right away with Sync now.

Key location, test mode and API hosts checked Nov 4, 2026 in Creem's API introduction.

What you'll see

One app's revenue in the live demo. Creem, Stripe, Polar and Lemon Squeezy all feed the same view.

One app's Revenue tab in BugOtter: MRR, a waterfall of how MRR moved, a forecast, revenue, paying subscribers and trials
  1. MRR per app, net of tax.
  2. How it moved: new, upgrades, downgrades and cancellations.
  3. A 30-day forecast if the last 30 days repeat.
  4. Trials, and what they're worth if they pay.
  • Revenue after refunds, from paid, refunded and partly refunded transactions. Chargebacks count as refunded.
  • Leaving soon: subscriptions with a scheduled cancellation, and the day they end.
  • Declined payments. Declined and uncollectible charges open an issue on the app and alert you.
  • Customers, anonymous: paying, cancelling or at risk, lifetime paid, and first-visit source for subscribers.
  • Revenue per traffic source for subscriptions whose checkout carried the visit id.

Link Creem subscriptions to traffic sources

Add the visit id to the checkout's metadata. BugOtter reads it from the subscription, so every renewal keeps its source.

BugOtter's Where it comes from card: revenue for the last 30 days by product, by country or by source
  1. By source: revenue per traffic source, for linked subscriptions.
  2. By product, with payments and share of revenue.

First, read the visit id in the browser and send it with your checkout request:

Browser
// In the browser, before you start the checkout
const visitorId = window.bo?.visitorId?.(); // "bo_…" or undefined

await fetch("/api/checkout", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ productId, visitorId }),
});

Then add it to the checkout's metadata as bugotter_visitor_id:

Server: create the Creem checkout
// On your server: create the Creem checkout
const base = process.env.CREEM_API_KEY!.startsWith("creem_test_")
  ? "https://test-api.creem.io"
  : "https://api.creem.io";

const res = await fetch(`${base}/v1/checkouts`, {
  method: "POST",
  headers: { "x-api-key": process.env.CREEM_API_KEY!, "Content-Type": "application/json" },
  body: JSON.stringify({
    product_id: productId,
    success_url: "https://yourapp.com/thanks",
    ...(typeof visitorId === "string" && visitorId
      ? { metadata: { bugotter_visitor_id: visitorId } }
      : {}),
  }),
});
const { checkout_url } = await res.json(); // send the customer here

That's your app's existing call to POST /v1/checkouts with one more field. Using the Creem SDK or a framework plugin? Pass the same metadata object to its checkout call.

Two limits, honestly:

  • One-time purchases aren't linked, because Creem transactions don't carry metadata and there's no subscription to read it from.
  • By default the visit id lasts for the browser tab, so someone who comes back days later in a new tab starts a new visit.

How MRR is counted for Creem

Yearly ÷ 12

What the subscription last actually paid, minus tax, turned into a month.

Monthly, every 3 months (÷ 3), every 6 months (÷ 6) and yearly (÷ 12).
  • What counts: active, past-due and unpaid subscriptions, and ones with a scheduled cancellation until they end. Trials count once they pay. Canceled, paused and expired don't.
  • Amount: since it's what was actually paid, discounts are already in, and a subscription with several units counts all of them. If it hasn't paid yet, the product's price times units is the fallback.
  • Tax: left out of both MRR and revenue. It's Creem's to pay as merchant of record, not your income.
  • Currencies stay separate, never converted.

Curious how annual plans move the number? The MRR calculator shows it.

Read-only toward Creem

BugOtter never creates checkouts, issues refunds, cancels subscriptions or emails your customers. Because a Creem key can't be limited, that promise is in BugOtter's code: it only calls Creem's read endpoints.

Connecting and disconnecting are only in the app, never through the MCP server. Disconnecting deletes the Creem data BugOtter copied; delete the key in Creem too if you're done.

Creem next to the other payment providers

BugOtter reads four providers. Here's what each one gives you.

What BugOtter reads from each payment provider
FeatureStripePolarLemon SqueezyCreem
Access
The key you give BugOtterYesRestricted key, Read onlyYesOrganization token, read scopesPartlyAPI key (can't be limited)PartlyAPI key (can't be limited)
Revenue
Revenue after refundsYesYesYesYes
MRR and how it movedYesYesYesYes
Trials and when they endYesYesYesYes
Cancellations scheduled (leaving soon)YesYesYesYes
Why customers cancelledYesYesNoNo
Refunds on the day they happenedYesPartlyWith refunds:readPartlyOrders from the last 90 daysPartlyDated by the payment
Failed payment alertsYesNoYesYes
Linking and testing
Revenue by traffic sourceYesPayment Links: automatic. Your checkout: metadataYesCheckout metadataNoNot yetPartlySubscriptions, via checkout metadata
Test modeYesrk_test_ keys, marked Test modeNoNot yet (the sandbox is a separate API)YesTest-mode API keysYescreem_test_ keys, marked Test mode

Questions

Is a Creem key safe to give BugOtter?

Creem API keys can't be limited to reading yet, so the key could make changes in principle. BugOtter's Creem code only sends read requests to three search endpoints (products, subscriptions, transactions). It never creates checkouts, refunds or cancels anything, and coding agents can't reach the connection over MCP. Delete the key in Creem whenever you like.

Does BugOtter count the tax Creem collects?

No. Creem is the merchant of record and collects the tax. BugOtter takes what the customer paid and subtracts the tax amount Creem reports on each transaction, for both revenue and MRR.

Why aren't my one-time Creem sales linked to traffic sources?

BugOtter links Creem payments through the subscription's metadata. One-time purchases have no subscription, and Creem transactions don't carry metadata, so there's nothing to read the visit id from. They still count fully in revenue.

Can I try it in Creem's test mode?

Yes. Turn on test mode in Creem, copy the creem_test_ key, and BugOtter reads Creem's test API and labels the connection Test mode. Disconnect and paste the live key when you're ready.

Why don't refunds show on the day they happened?

Creem doesn't say when a refund was made, only that a transaction was refunded. BugOtter subtracts it from the original payment's day. Chargebacks count as fully refunded.

Is there a size limit?

BugOtter reads up to 50,000 products, subscriptions or transactions per list. A bigger store gets a clear sync error rather than quietly missing numbers. Tell us and we'll raise it.

Know which post brought each Creem subscriber.

14 days of everything, no card needed. Plans from $10 a month, billed yearly.