Skip to main content

Revenue analytics

GET /v1/analytics/revenue is the single place to read revenue, cost, and margin out of MarginFront. Same math the dashboard runs, same shape. Use it when you need to know:
  • How much you earned in a time window
  • What it cost you to earn that
  • Your margin (dollars and percent)
  • Where the revenue came from (per subscription, per pricing strategy)
This is a read-only endpoint. It never creates or modifies anything.

The endpoint

Method and URL:
GET /v1/analytics/revenue
Auth is the same as every other endpoint: API key in the x-api-key header. See Authentication.

Query parameters

ParamTypeRequiredDescription
startDateISO dateyesStart of the window (inclusive). Example: 2026-04-01.
endDateISO dateyesEnd of the window (inclusive).
variantstringnoResponse shape. canonical for the shape documented below. Omit or pass legacy to get the older dashboard breakdown.
customerIdUUIDnoNarrow to one customer. Use MarginFront’s internal customer UUID, not your externalId.
subscriptionIdUUIDnoNarrow to one subscription.
agentIdUUIDnoNarrow to one agent.
signalIdUUIDnoNarrow to one signal.
About variant: if you pass any of customerId, subscriptionId, or signalId, the response is always the canonical shape shown below. The variant flag only matters when you call the endpoint org-wide with no entity filter. The SDK method client.analytics.revenue() always passes variant=canonical, so SDK users never have to think about this.

Example curl calls

Org-wide revenue for April 2026:
curl "https://api.marginfront.com/v1/analytics/revenue?startDate=2026-04-01&endDate=2026-04-30&variant=canonical" \
  -H "x-api-key: mf_sk_test_..."
One customer’s revenue for the month:
curl "https://api.marginfront.com/v1/analytics/revenue?customerId=bc8eceda-50e4-4138-b2a2-47e92d344540&startDate=2026-04-01&endDate=2026-04-30" \
  -H "x-api-key: mf_sk_test_..."
One subscription’s revenue:
curl "https://api.marginfront.com/v1/analytics/revenue?subscriptionId=9a8b7c6d-...&startDate=2026-04-01&endDate=2026-04-30" \
  -H "x-api-key: mf_sk_test_..."

What you get back (200 OK)

{
  "revenue": 12480.75,
  "cost": 3122.18,
  "margin": 9358.57,
  "marginPercent": 74.98,

  "usageRevenue": 8231.25,
  "recurringRevenue": 3999.0,
  "seatRevenue": 250.5,
  "onetimeRevenue": 0.0,

  "eventCount": 41233,
  "eventCountWithNullCost": 12,

  "bySubscription": [
    {
      "subscriptionId": "9a8b7c6d-...",
      "customerId": "5e7f8a3d-...",
      "agentId": "b47e12fa-...",
      "planId": "a1b2c3d4-...",
      "revenue": 842.0,
      "cost": 184.2,
      "margin": 657.8,
      "usageRevenue": 543.0,
      "recurringRevenue": 299.0,
      "seatRevenue": 0.0,
      "onetimeRevenue": 0.0,
      "eventCount": 2710
    }
  ],

  "byStrategy": [
    {
      "strategyId": "c3d4e5f6-...",
      "chargeType": "usage",
      "pricingModel": "flat",
      "signalId": "69145379-...",
      "revenue": 8231.25,
      "quantity": 823125
    }
  ]
}

Understanding the response

  • revenue is the full revenue total for the window: usage-based charges plus recurring fees plus seat fees plus one-time fees, all prorated if the subscription only partly overlapped the window.
  • cost is what it cost you to deliver the underlying usage: the sum of usageCost across every usage event in the window.
  • margin is revenue minus cost.
  • marginPercent is margin divided by revenue, expressed as a percent (so 74.98 means 74.98%). If revenue is 0 the field is null, never 0 and never NaN. That way “no revenue yet” shows up differently from “zero margin.”
  • usageRevenue / recurringRevenue / seatRevenue / onetimeRevenue split the revenue total by charge type. They always add up to revenue.
  • eventCount counts every usage event that fell inside the window.
  • eventCountWithNullCost is the subset of those events whose cost could not be computed (no matching price in the catalog). They are counted in eventCount but contribute 0 to cost. Treat this as a “needs attention” indicator.
  • bySubscription is one row per subscription that produced revenue in the window. Useful for customer detail pages and per-subscription drill-down.
  • byStrategy is one row per pricing strategy that contributed revenue. Useful for the “revenue by type” donut chart.
All money fields are number, not strings.

When to use this vs. other endpoints

Use this endpoint when you want the revenue answer: Dollars in, cost out, margin. Use /v1/analytics/usage when you want raw usage roll-ups (event counts, quantity totals) without pricing math. Use /v1/analytics/cost when you want cost broken down by agent, customer, signal, day, plan, or model, and you do not need revenue. Use /v1/analytics/mrr when you want monthly recurring revenue specifically (last-calendar-month billed, run-rate, or contractual floor). Use /v1/invoices when you want what was actually billed. Analytics tells you the revenue math; invoices are the documents you sent.

Using the Node SDK

import { MarginFrontClient } from "@marginfront/sdk";

const mf = new MarginFrontClient(process.env.MF_API_SECRET_KEY);

const metrics = await mf.analytics.revenue({
  startDate: "2026-04-01",
  endDate: "2026-04-30",
});

console.log(`Revenue: $${metrics.revenue.toFixed(2)}`);
console.log(`Margin: ${metrics.marginPercent ?? "n/a"}%`);
See the SDK analytics page for all seven analytics methods and the SDK types reference for every response shape.

Common errors

  • 400 Bad Request: startDate or endDate is missing, in the wrong format, or one of the UUID filters is not a valid UUID.
  • 401 Unauthorized: API key missing or wrong.