Skip to main content

Usage Analytics

The analytics endpoint is how you read usage data back out of MarginFront. It returns rolled-up numbers for any customer, agent, or time window you specify. Use it to:
  • Power “current period usage” widgets in your own product
  • Build cost dashboards that show your customers what they’ve used this month
  • Project a customer’s end-of-month bill before the invoice is generated
  • Feed data into your own BI tools
This is a read-only endpoint — it doesn’t create or modify anything.

The endpoint

Method & URL:
GET /v1/analytics/usage
Same auth as everything else — API key in the x-api-key header.

Query parameters

All optional. If you don’t specify any, you get a roll-up for the whole org over the default time window.
ParamTypeDescription
startDateISO dateStart of the time window (inclusive).
endDateISO dateEnd of the time window (inclusive).
customerIdUUIDFilter to a single customer. Use MarginFront’s internal customer UUID (not your externalId).
agentIdUUIDFilter to a single agent.
signalIdUUIDFilter to a single signal.
groupBystringTime-bucket size for timeSeriesData. One of "daily", "weekly", "monthly". Default: "daily".
breakdownBystringAdd a dimensionBreakdown section broken out by one of "customer", "signal", "agent". When omitted, the response has no dimensionBreakdown field.
If you pass an invalid groupBy or breakdownBy value, the API returns 400 Bad Request with a message listing the accepted values.

Example curl calls

Get everything for April 2026:
curl "https://api.marginfront.com/v1/analytics/usage?startDate=2026-04-01&endDate=2026-04-30" \
  -H "x-api-key: mf_sk_test_..."
Get usage for one customer:
curl "https://api.marginfront.com/v1/analytics/usage?customerId=bc8eceda-50e4-4138-b2a2-47e92d344540&startDate=2026-04-01&endDate=2026-04-30" \
  -H "x-api-key: mf_sk_test_..."
Get weekly totals for one agent:
curl "https://api.marginfront.com/v1/analytics/usage?agentId=3a1948ea-a701-4752-8c3d-df6c2f5833cf&startDate=2026-04-01&endDate=2026-04-30&groupBy=weekly" \
  -H "x-api-key: mf_sk_test_..."
Break down totals by customer:
curl "https://api.marginfront.com/v1/analytics/usage?startDate=2026-04-01&endDate=2026-04-30&breakdownBy=customer" \
  -H "x-api-key: mf_sk_test_..."

What you get back (200 OK)

{
  "dateRange": {
    "start": "2026-04-01",
    "end": "2026-04-30",
    "groupBy": "daily"
  },
  "filters": {},
  "summary": {
    "totalEvents": 1247,
    "totalQuantity": 1247,
    "totalCost": 42.18,
    "avgCostPerEvent": 0.0338
  },
  "timeSeriesData": [
    {
      "date": "2026-04-01",
      "eventCount": 87,
      "totalQuantity": 87,
      "totalCost": 2.94
    },
    {
      "date": "2026-04-02",
      "eventCount": 93,
      "totalQuantity": 93,
      "totalCost": 3.12
    }
  ],
  "metadata": {
    "signals": {
      "69145379-8b26-4050-b54d-e08d6059ca18": "Messages Processed"
    },
    "customers": {
      "19a53f22-3cba-4224-bf1b-7b541ed7d12f": "Acme Inc"
    },
    "agents": {
      "84165d91-1136-4960-97d7-e24136476ce7": "Customer Support Bot"
    }
  }
}
When you pass breakdownBy, an additional dimensionBreakdown field appears at the top level:
{
  "dimensionBreakdown": {
    "dimensionType": "customer",
    "summary": [
      {
        "dimensionId": "19a53f22-3cba-4224-bf1b-7b541ed7d12f",
        "dimensionLabel": "Acme Inc",
        "totalEvents": 412,
        "totalQuantity": 412,
        "totalCost": 18.23
      }
    ],
    "timeline": [
      {
        "date": "2026-04-01",
        "dimensionId": "19a53f22-3cba-4224-bf1b-7b541ed7d12f",
        "dimensionLabel": "Acme Inc",
        "eventCount": 14,
        "totalQuantity": 14,
        "totalCost": 0.62
      }
    ]
  }
}

Understanding the response

  • summary — totals across the entire date range. This is what most dashboards want. Fields: totalEvents, totalQuantity, totalCost, avgCostPerEvent.
  • timeSeriesData — one row per time bucket (daily, weekly, or monthly depending on groupBy). Good for drawing charts. Note the row field is eventCount (not totalEvents).
  • metadata — lookup dictionaries mapping UUIDs to human-readable names for signals, customers, and agents referenced in the results. Use it to render labels without a second round-trip.
  • dimensionBreakdown — present only when you pass breakdownBy=customer|signal|agent. An object with dimensionType, a summary array (one row per dimension with totals across the window), and a timeline array (per-bucket rows tagged with the dimension).
  • dateRange and filters — echo back what you queried so the response is self-describing. filters contains only the keys you actually passed (it’s {} when you passed no filters).
Values in this endpoint are returned as numbers — unlike GET /v1/events, where usageCost and quantity are strings. Analytics values are already rolled up, so sub-cent precision only shows up in averages.

Common errors

  • 400 Bad Request — A query parameter is in the wrong format (e.g., startDate isn’t a valid ISO date).
  • 401 Unauthorized — API key missing or wrong.

Using the Node SDK

// All usage this month for a specific customer
const stats = await mf.analytics.usage({
  customerId: "bc8eceda-50e4-4138-b2a2-47e92d344540",
  startDate: "2026-04-01",
  endDate: "2026-04-30",
});

console.log(`Customer used $${stats.summary.totalCost} worth of usage`);

What this endpoint is for (and what it isn’t)

Use this for:
  • Live dashboards, projections, “usage so far this month” displays
  • Triggering alerts when a customer hits a usage threshold
  • Feeding simple BI reports
Don’t use this for:
  • Actual invoice data — use invoices for that. Analytics tells you “here’s the raw usage roll-up,” but invoices are the finalized billing documents that include discounts, taxes, prorations, etc.
  • High-resolution per-event drill-down — this endpoint returns aggregates. If you need event-level detail, use the signal-events listing endpoint at GET /v1/events.