All pages

Quickstart

Measurement first. This gets you real cost and margin per customer without changing how a single request behaves. Nothing here can break production: the call you add cannot throw and cannot block.

  1. 01

    Install

    bash
    npm install marginfuse

    Node 18 or newer, zero dependencies. Works in Next.js route handlers and serverless functions.

  2. 02

    Get a project API key

    Create a project in MarginFuse and copy its key from Settings, then put it in your environment as MARGINFUSE_KEY. Keys start with mf_live_ or mf_test_, and only the hash is stored, so a lost key is rotated rather than recovered.

  3. 03

    Report each AI call

    Add this after the provider call returns. It sends metadata only: token counts, the model, your customer id. There is no field for the prompt.

    TypeScript
    import { MarginFuse } from "marginfuse";
    
    const mf = new MarginFuse({ apiKey: process.env.MARGINFUSE_KEY! });
    
    // After the AI call returns. Metadata only: there is no field for the prompt.
    mf.track({
      customerId: "cus_8x2m91", // your Stripe customer id, or your own
      feature: "ai_chat",
      provider: "openai",
      model: "gpt-4.1",
      usage: { inputTokens: 1204, outputTokens: 388 },
    });

    Pass costUsd instead of, or alongside, token counts when your provider reports the real charge. MarginFuse prefers a figure you observed over one it estimated.

  4. 04

    Connect Stripe, read only

    Cost alone is not margin. Connect Stripe in Settings and MarginFuse reads subscriptions and invoices to put revenue on the other side of the equation. Read only: it cannot change a charge, a plan, or a customer.

  5. 05

    Watch the first numbers arrive

    Events appear within seconds. Margin per customer needs both sides, so it fills in once Stripe has synced and traffic has flowed. Every figure is labeled with how it was arrived at, so you always know whether you are looking at something observed or something estimated.

Configuration

Everything is optional except the key.

TypeScript
import { MarginFuse } from "marginfuse";

const mf = new MarginFuse({
  apiKey: process.env.MARGINFUSE_KEY!,

  // Point at your own deployment in development.
  baseUrl: "https://api.marginfuse.com",

  // How long decide() waits before giving up and allowing the request.
  timeoutMs: 1500,

  // The SDK never throws into your code. Transport failures arrive here.
  onError: (error, context) => {
    logger.warn({ err: error, context }, "marginfuse degraded");
  },
});
  • timeoutMs is the budget for a decision, not for track(). When it expires the request is allowed through.
  • onError is the only place transport failures surface. The SDK swallows them so they cannot become your outage; without this hook they are silent.

Then what

Measuring is the whole free tier and it is worth stopping there for a week. Once you can see which customers lose money, protection is the same SDK with the call moved to before the request.

NextProtectionDecide before the call runs, and act on the verdict.