Revenue
Attach amounts to any event. Ask your agent which channel made the most money, what a signup from Hacker News is worth, or how ARR from the spring campaign is trending.
The Money type
Clamp has one special property shape: Money. An amount and an ISO 4217 currency code. Send it on any event and Clamp stores it as a first-class numeric column, not a string.
type Money = {
amount: number // in major units (29.00, not 2900)
currency: string // ISO 4217, e.g. "USD", "EUR", "JPY"
}Tracking revenue
Any event property whose value is a Money object is treated as revenue. You can attach more than one (total, tax, mrr) and query each independently.
import { track } from "@clamp-sh/analytics"
track("checkout_completed", {
plan: "pro",
interval: "annual",
total: { amount: 348.00, currency: "USD" },
tax: { amount: 52.20, currency: "USD" },
})import { track } from "@clamp-sh/analytics/server"
await track("subscription_created", {
anonymousId: "anon_abc123",
properties: {
plan: "pro",
mrr: { amount: 29.00, currency: "USD" },
},
})The server SDK is where most production revenue tracking lives. Browser calls are fine for prototyping, but authoritative numbers (after a Stripe webhook fires, after a refund, after proration) belong on the server. See Server-side.
Data attributes
With the dataAttributes extension enabled, mark any element with data-clamp-money-key="amount currency" and Clamp parses it into a Money property when the event fires.
<button
data-clamp-event="checkout_clicked"
data-clamp-plan="pro"
data-clamp-money-price="29.00 USD"
>
Start on Pro — $29/mo
</button>
// Fires: track("checkout_clicked", {
// plan: "pro",
// price: { amount: 29, currency: "USD" }
// })Useful for pricing pages, CMS content, and anywhere the amounts live in markup already. See Data attributes for the full syntax.
Querying revenue
The get_revenue MCP tool aggregates any Money property on any event. Group by channel, country, UTM source, or custom property.
"How much revenue did we make this month?"
→ get_revenue({ event: "checkout_completed", property: "total", period: "30d" })
"Break down MRR by plan"
→ get_revenue({
event: "subscription_created",
property: "mrr",
group_by: "plan"
})
"Which channel drove the most revenue?"
→ get_revenue({
event: "checkout_completed",
property: "total",
group_by: "channel"
})
"Revenue from the spring-launch campaign"
→ get_revenue({
event: "checkout_completed",
property: "total",
utm_campaign: "spring-launch"
})Currency handling
Clamp does not convert currencies. Each Money value is stored with its original currency and aggregated per currency in the response. If you charge in mixed currencies, get_revenue returns a breakdown like { USD: 12400, EUR: 3200 }. Convert downstream with whatever rate your finance team uses.
Refunds and negatives
Negative amounts are allowed. Track refunds as their own event with a negative total, or flip the sign on the original event’s Money property when you reprocess it server-side.
await track("refund_issued", {
anonymousId,
properties: {
original_event_id: "evt_xxx",
total: { amount: -29.00, currency: "USD" },
},
})get_revenue sums everything, so refunds net out automatically when grouped alongside the original events.