Skip to main content

Customers

The customers resource handles the usual create, read, update, delete, plus one method built for customer detail pages: getWithRevenue. It fetches the customer record AND their revenue numbers for a time window in one round trip. This page covers:
  1. Creating a customer
  2. Listing customers
  3. Getting one customer
  4. Updating a customer
  5. Deleting a customer
  6. Getting a customer with their revenue numbers attached

Setup

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

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

customers.create

Creates a new customer. If you pass agentCode, MarginFront also auto-creates a subscription between the customer and that agent.

Signature

await mf.customers.create(params: CreateCustomerData): Promise<Customer>

Example

const customer = await mf.customers.create({
  name: "Acme Corp",
  externalId: "acme-001",
  email: "[email protected]",
  agentCode: "cs-bot-v2", // optional: auto-creates a subscription
});
See the Customers API reference for the full field list.

customers.list

Returns a paginated list of customers with optional filters.

Signature

await mf.customers.list(params?: CustomerListParams): Promise<CustomerListResponse | Customer[]>

Example

const { data, totalResults, hasMore } = await mf.customers.list({
  limit: 20,
  page: 1,
});

for (const customer of data) {
  console.log(`${customer.name} (${customer.externalId})`);
}

customers.get

Fetches one customer by id, including their subscriptions.

Signature

await mf.customers.get(id: string): Promise<Customer>

Example

const customer = await mf.customers.get("c4e8d1a2-1234-4567-8901-abcdef123456");

console.log(customer.name);
console.log(`Subscriptions: ${customer.subscriptions?.length ?? 0}`);

customers.update

Updates an existing customer. Pass only the fields you want to change.

Signature

await mf.customers.update(id: string, params: UpdateCustomerData): Promise<Customer>

Example

const updated = await mf.customers.update(
  "c4e8d1a2-1234-4567-8901-abcdef123456",
  {
    email: "[email protected]",
    netTerms: 45,
  },
);

customers.delete

Deletes a customer.

Signature

await mf.customers.delete(id: string): Promise<void>

Example

await mf.customers.delete("c4e8d1a2-1234-4567-8901-abcdef123456");

customers.getWithRevenue

What it does in plain English: fetches a customer AND their revenue numbers for a time window, in one call. Lets you render a customer detail page (profile, subscriptions, revenue, cost, margin) without juggling two round trips. Behind the scenes the SDK fires both requests in parallel, so the wall-clock time is roughly the time of one call.

Signature

await mf.customers.getWithRevenue(
  id: string,
  window?: CustomerRevenueWindow,
): Promise<CustomerDetailWithRevenue>

Parameters

NameTypeRequiredDescription
idstringyesThe customer id (MarginFront’s internal UUID).
window.startDatestringnoISO date. Defaults to 30 days ago if omitted.
window.endDatestringnoISO date. Defaults to today if omitted.
Pass both window fields together or neither. Omitting both defaults to the last 30 days UTC.

Response shape

interface CustomerDetailWithRevenue {
  customer: Customer;
  revenue: RevenueMetrics;
}
The customer field is the same shape as customers.get returns. The revenue field is the same canonical shape analytics.revenue returns, scoped to this one customer. See Types Reference for the complete interfaces.

Example

// Default window (last 30 days)
const { customer, revenue } = await mf.customers.getWithRevenue(
  "c4e8d1a2-1234-4567-8901-abcdef123456",
);

console.log(`${customer.name}`);
console.log(`External id: ${customer.externalId ?? "(none)"}`);
console.log(`Status: ${customer.status}`);

console.log(`Revenue: $${revenue.revenue.toFixed(2)}`);
console.log(`Cost: $${revenue.cost.toFixed(2)}`);
console.log(`Margin: $${revenue.margin.toFixed(2)}`);

if (revenue.marginPercent !== null) {
  console.log(`Margin %: ${revenue.marginPercent.toFixed(1)}%`);
} else {
  console.log(`Margin %: not available (no revenue in window)`);
}

console.log(`Events: ${revenue.eventCount}`);

// Which subscriptions contributed the most revenue
const topSubs = revenue.bySubscription
  .sort((a, b) => b.revenue - a.revenue)
  .slice(0, 3);

for (const row of topSubs) {
  console.log(
    `  Sub ${row.subscriptionId}: $${row.revenue.toFixed(2)} revenue`,
  );
}

// Explicit window
const april = await mf.customers.getWithRevenue(
  "c4e8d1a2-1234-4567-8901-abcdef123456",
  {
    startDate: "2026-04-01",
    endDate: "2026-04-30",
  },
);

What this returns, in plain English

  • customer the usual customer record. Profile, contact info, status, subscriptions list (if populated), billing settings.
  • revenue a full canonical revenue block for this one customer, in the window you asked for. Revenue, cost, margin, marginPercent, plus the usage/recurring/seat/onetime breakdown, a per-subscription row list, and a per-pricing-strategy row list.
For the full shape of RevenueMetrics, see Types Reference.

When to use this

Customer detail pages. Account manager dashboards. Churn-risk reviews. Anywhere you need the customer record AND how much they’re contributing in one view. For just the customer record, use customers.get. For revenue across many customers, use analytics.revenue with no filter (and read bySubscription for per-customer rollups).

Next steps