Quickstart
Marginal tracks where your AI spend goes — per customer, feature, model, or any other field you define. This page takes you from zero to seeing spend in the dashboard in about five minutes.
1. Create a project
Sign up and create a project. A project represents one application; events, API keys, and dashboards are all scoped to it. Pick the project's timezone while you're at it — every day-based number (the overview's daily chart, the explorer's date ranges) is computed in it.
2. Register your fields
On the project's Fields page, declare the keys your events may carry — this is your project's vocabulary, and it's what keeps dashboards free of typo'd keys. The suggested conventions are one click away:
customer— who this cost is attributable tofeature— which part of your product made the callenvironment—production,staging,development, …
(Don't register model — it's part of the event itself, not a field.)
You can register anything you like (up to 20 keys). Events may only carry registered keys — anything else is stripped on arrival and reported back, so nothing lands silently. See Field conventions for how to pick good ones.
3. Create an API key
On the API keys page, create a key. It looks like mgl_… and is how the
SDK authenticates and routes events to your project. Treat it like a secret —
use it server-side only.
4. Install the SDK
npm install marginal-sdk # TypeScript / JavaScript (Node 18+)
pip install marginal-sdk # Python (3.9+)5. Send your first event
One call per LLM request: name the provider, paste the response's model and
usage — Marginal detects the provider's usage shape and computes the cost
server-side against its model price catalog. track never throws and never
blocks: events are buffered and sent in batches in the background.
import { Marginal } from "marginal-sdk";
const marginal = new Marginal({ apiKey: process.env.MARGINAL_API_KEY });
const response = await openai.chat.completions.create({ /* … */ });
marginal.track({
provider: "openai",
model: response.model, // the response-reported model
usage: response.usage, // pasted as-is; Marginal does the math
fields: {
customer: "acme",
feature: "chat",
environment: "production",
},
});
// On shutdown, flush anything still buffered:
await marginal.shutdown();import os
from marginal import Marginal
marginal = Marginal(api_key=os.environ["MARGINAL_API_KEY"])
response = client.chat.completions.create(...)
marginal.track(
provider="openai",
model=response.model,
usage=response.usage.model_dump(),
fields={
"customer": "acme",
"feature": "chat",
"environment": "production",
},
)
# Buffered events are flushed automatically at exit;
# call marginal.shutdown() to flush explicitly.For anything Marginal can't price — voice minutes, image generation, or a
cost you've already computed — send an explicit cost in dollars instead:
marginal.track({ cost: 0.05, fields: { customer: "acme", feature: "voice" } });Timestamps are assigned by the server when events arrive — the SDK doesn't send them and the API doesn't accept them.
6. Watch it land
Open the project's Ingest log page — every API request shows up there as
it arrives, tagged success, warn, or error, with any problems
(rejected events, stripped field keys, unpriced models) spelled out. Then
open the Explorer — your event appears in the list with one column per
registered field, so you can confirm everything is tagged as intended. Then pick a Group by dimension to slice spend —
Model and Provider are built in (no registration needed), and every
registered field joins them (top customers by cost, production only, …).
Head to Overview for totals and the daily spend chart.
That's the whole integration. For copy-paste recipes per stack — OpenAI, Anthropic, Vercel AI SDK, Gemini, Bedrock, streaming included — see Integrations; for the full wire contract and SDK options, see Event shape & API.