> ## Documentation Index
> Fetch the complete documentation index at: https://docs.marginfront.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Analytics · Revenue

> Canonical revenue, cost, and margin for any customer, agent, signal, or subscription

# 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](./authentication).

***

## Query parameters

| Param            | Type     | Required | Description                                                                                                             |
| ---------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| `startDate`      | ISO date | yes      | Start of the window (inclusive). Example: `2026-04-01`.                                                                 |
| `endDate`        | ISO date | yes      | End of the window (inclusive).                                                                                          |
| `variant`        | string   | no       | Response shape. `canonical` for the shape documented below. Omit or pass `legacy` to get the older dashboard breakdown. |
| `customerId`     | UUID     | no       | Narrow to one customer. Use MarginFront's internal customer UUID, not your `externalId`.                                |
| `subscriptionId` | UUID     | no       | Narrow to one subscription.                                                                                             |
| `agentId`        | UUID     | no       | Narrow to one agent.                                                                                                    |
| `signalId`       | UUID     | no       | Narrow 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:**

```bash theme={null}
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:**

```bash theme={null}
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:**

```bash theme={null}
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`)

```json theme={null}
{
  "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`](./analytics) when you want raw usage roll-ups (event counts, quantity totals) without pricing math.

Use [`/v1/analytics/cost`](./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`](./analytics-mrr) when you want monthly recurring revenue specifically (last-calendar-month billed, run-rate, or contractual floor).

Use [`/v1/invoices`](./invoices) when you want what was actually billed. Analytics tells you the revenue math; invoices are the documents you sent.

***

## Using the Node SDK

```typescript theme={null}
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](/sdk/analytics) for all seven analytics methods and the [SDK types reference](/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.
