Skip to main content

Analytics

The analytics resource on the SDK is how you read finished numbers back out of MarginFront. Revenue, cost, margin, billed, collected, MRR. Same math the dashboard runs, same shapes. All seven methods return plain TypeScript objects with typed fields. Money fields are number (not strings). If a margin can’t be calculated (because revenue is zero), marginPercent is null, never 0 or NaN. This page covers:
  1. analytics.revenue: revenue, cost, margin, and the breakdown of where revenue came from
  2. analytics.costBreakdown: cost sliced by agent, customer, signal, day, plan, and model
  3. analytics.agentEarned: activity-only revenue, before any fees are added on
  4. analytics.invoiceTotals: billed, collected, outstanding, overdue
  5. analytics.mrr: last complete calendar month’s billed total
  6. analytics.runRateMrr: trajectory if the last 30 days keep going
  7. analytics.committedMrr: contractual floor, regardless of usage
For the shape of every response type, see Types Reference.

Setup

All seven methods are on mf.analytics. No separate import, no special setup.

1. analytics.revenue

What it does in plain English: gives you the whole revenue picture for a time window. How much you earned, how much it cost you, your margin, and where the revenue came from (per subscription, per pricing strategy). This is the number you’d show on an executive dashboard. It includes usage-based revenue plus recurring fees, seat fees, and one-time fees (prorated if the subscription only partly overlapped the window).

Signature

Parameters

Any combination of filters can be mixed. No filter means org-wide.

Response shape

Example

What this returns, in plain English

  • revenue total dollars earned in the window. Usage plus recurring plus seat plus one-time fees.
  • cost total service cost (the bill from OpenAI, Anthropic, Twilio, etc.) for the events in the window.
  • margin revenue minus cost.
  • marginPercent the margin as a percentage. Comes back as null (shown as a dash in dashboards) when revenue is zero, so you never see a 0% or NaN% that would be misleading.
  • usageRevenue / recurringRevenue / seatRevenue / onetimeRevenue the four ways revenue can show up, split out. They add up to revenue.
  • eventCount every event counted in the window.
  • eventCountWithNullCost events that are in the count but whose cost couldn’t be calculated yet (unknown model, no pricing map). A “needs attention” number. See Tracking Events: NEEDS_COST_BACKFILL.
  • bySubscription one row per active subscription in the window, each with its own revenue/cost/margin breakdown.
  • byStrategy one row per pricing strategy that contributed revenue, with the strategy’s charge type, pricing model, and signal id.

2. analytics.costBreakdown

What it does in plain English: shows you where your money is going. Total cost in the window, sliced six different ways: by agent, by customer, by signal, by day, by pricing plan, and by LLM model. Optional period-over-period comparison. This is the number behind a “cost explorer” dashboard. Find the expensive customer. Find the expensive model. Find the day your bill spiked.

Signature

Parameters

Response shape

Each breakdown row has the shape { <idField>: string | null, cost: number, eventCount: number }. See Types Reference for the exact row types.

Example

What this returns, in plain English

  • cost total service cost in the window.
  • eventCount every event in the window.
  • eventCountWithNullCost events whose cost couldn’t be calculated. Counted, not dropped. Shows up as a “needs attention” indicator.
  • byAgent / byCustomer / bySignal / byPlan / byModel cost broken out along each dimension. The id fields can be null when an event isn’t yet attached to that dimension (e.g., an orphan event with no pricing plan).
  • byDay cost per UTC calendar day, one row per day with activity.
  • prior only present when you passed includePriorWindow: true. Same shape as the outer object, but for the same-length window immediately before startDate. Lets you show trend arrows without a second call.

3. analytics.agentEarned

What it does in plain English: tells you how much revenue your agents produced from actual activity, before any fixed fees are added on top. Usage events multiplied by their pricing strategy rates, summed up. This is the earliest signal that something is working. It moves the moment an event fires, without waiting for an invoice to finalize. If you want to answer “are my agents doing billable work this week,” this is the number.

Signature

Parameters

Response shape

Example

What this returns, in plain English

  • revenue activity-only revenue in the window. Usage events × their pricing strategy rate. No recurring fees, no seat fees, no one-time fees.
  • eventCount events that produced revenue (events tied to a usage pricing strategy).
  • bySubscription per-subscription breakdown: how much revenue each sub produced and how many events did it.
  • byStrategy per-pricing-strategy breakdown: which specific rate earned what, and the total quantity that ran through it.

When to use this vs analytics.revenue

Use agentEarned when you care about activity in near-real-time. Use revenue when you want the full picture including fixed fees and prorations. They’ll give you different numbers for the same window, on purpose.

4. analytics.invoiceTotals

What it does in plain English: tells you what you actually invoiced and what your customers actually paid. Billed, collected, draft inventory, outstanding A/R, and a live overdue count. This is the finance-team view. It reads realized amounts off of invoices, not a formula. Non-draft invoices reconcile to the revenue formula, so you can trust these numbers directly.

Signature

Parameters

Response shape

Example

What this returns, in plain English

  • billed total on invoices you issued in the window (status issued or overdue), counted by invoice date. Waiting on payment.
  • collected cash that actually landed in the window: payments that went through with a payment date in the window, net of refunds. Counted by the day the money arrived, not the invoice date.
  • draft total on invoices you generated but haven’t sent yet. Inventory, not revenue.
  • outstanding what’s still open right now: invoices that are issued or overdue and not yet paid. A current-state number with no date window, always zero or more.
  • overdueAmount total on invoices currently past due. Age-based, not window-based. Current state right now.
  • overdueCount how many invoices are currently past due.
  • invoicesSentCount how many non-draft invoices were dated in the window.

5. analytics.mrr

What it does in plain English: tells you how much you actually billed last complete calendar month. Monthly recurring revenue, based on invoices that went out. This is the “book MRR” number. Stable across the month (doesn’t change until the month rolls over), based on realized billing. If you want forward-looking MRR, use runRateMrr or committedMrr below.

Signature

Parameters

All optional. No date parameters. The window is fixed: first of last calendar month to first of this month.

Response shape

Example

What this returns, in plain English

  • mrr total billed across all invoices dated in the previous calendar month.
  • arr annualized: mrr × 12. A convenience so you don’t multiply in the UI.

6. analytics.runRateMrr

What it does in plain English: tells you what your MRR would be if the last 30 days of activity kept going at the same pace. Recurring fees, seat fees, and actual usage rolled forward. This is the “current run rate” number. Useful when usage moves fast and last month’s MRR is already stale.

Signature

Parameters

Same as analytics.mrr: optional customerId and subscriptionId. No date window.

Response shape

Example

What this returns, in plain English

  • mrr projected monthly revenue if the last 30 days keep up this pace.
  • breakdown one row per active subscription with its contribution split into recurring, seat, and usage parts. The three add up to total, and all the totals add up to mrr.

7. analytics.committedMrr

What it does in plain English: the floor. Tells you the monthly revenue your contracts guarantee, regardless of whether customers actually use the product. Recurring fees, seat fees, and usage minimums only. Use this to answer “what’s the least we’ll bill next month?” By definition, committed MRR is always less than or equal to run-rate MRR (because run-rate counts actual usage, committed only counts minimums).

Signature

Parameters

Same as analytics.mrr and analytics.runRateMrr: optional customerId and subscriptionId.

Response shape

Example

What this returns, in plain English

  • mrr the monthly revenue your contracts guarantee. Recurring fees always apply. Seat fees use the booked seat count. Usage uses the minimum commitment on each pricing strategy (zero when there’s no minimum set).
  • breakdown same shape as runRateMrr’s breakdown, but the usage column uses the minimum-commitment floor instead of actual events.

Field types at a glance

All dollar amounts are number, not string. Values come back at full precision. Round at render time, not in storage:
marginPercent is number | null. A null means “no revenue yet, so margin can’t be computed.” Render it as a dash, not as 0%. See Types Reference for the full interface definitions.

When to call which method


Next steps