All pages

SDKs

Seven languages, one behaviour. Each SDK is open source under MIT, carries no package dependencies of its own, and is driven through the same conformance suite before it can be published.

Install

Pick your language. The examples on every other page in these docs switch to it and stay there.

TypeScript and Node

Node 18+, zero dependencies

bash
npm install marginfuse

npm · Source

Python

Python 3.9+, zero dependencies

bash
pip install marginfuse

PyPI · Source

Go

Go 1.21+, zero dependencies

bash
go get github.com/marginfuse/marginfuse-go

Go module proxy · Source

Java

Java 11+, zero dependencies

kotlin
implementation("com.marginfuse:marginfuse-java:0.1.0")

Maven Central · Source

C# and .NET

.NET 8+, zero dependencies

bash
dotnet add package MarginFuse

NuGet · Source

Ruby

Ruby 3.2+, zero dependencies

bash
gem install marginfuse

RubyGems · Source

PHP

PHP 8.2+, zero dependencies

bash
composer require marginfuse/marginfuse

Packagist · Source

The same call, in each of them

This is the whole measurement integration. It sends metadata only: token counts, the model, your customer id. There is no field for the prompt, so nothing else can travel by accident.

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 },
});

Why they behave the same

Nothing about seven independent implementations guarantees they agree. What makes these interchangeable is that none of them owns its own definition of correct. A single shared contract holds the behaviour, and every SDK is driven through it before release.

  • Sixteen behaviour scenarios, run against the packaged artifact rather than the source tree. A block verdict never calls the provider. A timeout fails open to allow. A malformed response degrades instead of crashing.
  • Thirteen gateway vectors, so the cost arithmetic matches across languages down to the string that goes on the wire.
  • Each SDK exports the contract version it was verified against. Two SDKs reporting the same one have passed the same scenarios and the same vectors.

Package version numbers differ per language, because each tracks its own breaking changes: a rename in Python must not tell Node users something broke. The contract version is what makes them comparable, not the package version.

What every one of them promises

  • track never throws into your code and never blocks your response. It returns immediately and retries in the background.
  • decide always returns a verdict. On any timeout or error it fails open to allow with degraded set, because MarginFuse being unreachable must never become your outage.
  • Failures the SDK swallowed reach you through onError and nowhere else. Without it they are silent by design.
NextQuickstartInstall, add one call, and see real margin per customer.