Skip to main content

Install

npm install @margovia/sdk

Configure

You need two kinds of keys:
  • A Margovia API key from your Margovia project settings. This lets the SDK send usage to Margovia.
  • Your model provider key, such as OPENAI_API_KEY or ANTHROPIC_API_KEY. Margovia does not call OpenAI or Anthropic for you.
Add the Margovia key to the backend app where you call the model provider:
MARGOVIA_API_KEY=mg_live_xxx
Installing the SDK alone sends nothing. When MARGOVIA_API_KEY is configured, the SDK sends events to Margovia Cloud by default. If you self-host Margovia, run a compatible receiver, or test against a local API, set MARGOVIA_BASE_URL:
MARGOVIA_BASE_URL=http://localhost:4010

Track your first OpenAI call

The easiest OpenAI setup is margovia.openai(client). Think of it as a tracked OpenAI client. You still call OpenAI, but Margovia records the workflow name, customer, token usage, and cost.
import OpenAI from "openai";
import { Margovia } from "@margovia/sdk";

const margovia = new Margovia();
const openai = margovia.openai(new OpenAI());

await openai.chat.completions.create({
  name: "support_reply",
  outcome: "reply_generated",
  customerId: "workspace_123",
  customerName: "Northstar Agency",
  customerPlan: { name: "pro", monthlyUsd: 99 },
  request: {
    model: "gpt-5-mini",
    messages: [
      { role: "system", content: "Write concise customer support replies." },
      { role: "user", content: "Help me respond to this ticket." }
    ]
  }
});
The tracked client starts a Margovia run, calls OpenAI, records the cost event from provider usage, and completes the run after the provider call succeeds.

Track your first Anthropic call

The Anthropic setup is the same idea. Wrap the Anthropic client once, then call anthropic.messages.create(...) with your Margovia fields plus the real Anthropic request.
import Anthropic from "@anthropic-ai/sdk";
import { Margovia } from "@margovia/sdk";

const margovia = new Margovia();
const anthropic = margovia.anthropic(new Anthropic());

await anthropic.messages.create({
  name: "score_tweet",
  outcome: "tweet_scored",
  customerId: "workspace_123",
  customerName: "Northstar Agency",
  customerPlan: { name: "pro", monthlyUsd: 99 },
  request: {
    model: "claude-sonnet-4-20250514",
    max_tokens: 800,
    messages: [
      { role: "user", content: "Score this tweet for likely engagement." }
    ]
  }
});

If you already have a helper

Use trackAnthropic(...) or trackOpenAI(...) only when you already have your own provider helper function and want to keep that shape.
const response = await margovia.trackAnthropic({
  name: "score_tweet",
  customerId: "workspace_123",
  customerName: "Northstar Agency",
  outcome: "tweet_scored",
  request: params,
  fn: () => anthropic.messages.create(params)
});
This replaces manual code that calls startRun, run.trackCost, and run.complete. Use a raw provider client inside trackAnthropic(...) or trackOpenAI(...). Do not pass an already-wrapped client into these helpers or you may double-report cost.

What .track(...) is for

margovia.track(...) tracks a workflow boundary. It does not read OpenAI or Anthropic token usage by itself. Good use:
const openai = margovia.wrapOpenAI(new OpenAI());

await margovia.track({
  name: "generate_weekly_report",
  customerId: "workspace_123",
  outcome: "report_created",
  fn: async () => {
    await openai.chat.completions.create({ model: "gpt-5-mini", messages });
    await openai.chat.completions.create({ model: "gpt-5-mini", messages: followupMessages });
  }
});
Bad use:
await margovia.track({
  name: "score_tweet",
  fn: () => anthropic.messages.create(params)
});
That bad example creates a run, but if anthropic is not wrapped then Margovia receives no token usage and no cost.

If you use another provider

OpenAI and Anthropic have first-class helpers because the SDK knows how to read their usage fields. For Gemini, Cohere, custom models, search APIs, or internal tools, use manual tracking and send either tokens or costUsd.
const run = await margovia.startRun({
  name: "generate_answer",
  customerId: "workspace_123"
});

const response = await gemini.models.generateContent(...);

await run.trackCost({
  provider: "gemini",
  model: "gemini-2.5-pro",
  inputTokens: response.usageMetadata?.promptTokenCount,
  outputTokens: response.usageMetadata?.candidatesTokenCount
});

await run.complete({ outcome: "answer_generated" });
See Integration patterns for unsupported provider examples.

Verify

Run the code once, then open Margovia and look for a run named:
support_reply
If no API key is configured, the SDK skips Margovia tracking and does not send events. If you do not see a run, check:
  • The code ran on your backend, not in the browser
  • MARGOVIA_API_KEY is set in the same process that calls OpenAI or Anthropic
  • The API key belongs to the Margovia project you are viewing
  • MARGOVIA_BASE_URL is not pointing at a local API by accident

Attribution checklist

Send attribution from your app’s source of truth:
  • customerId: stable account, workspace, org, tenant, or billing customer ID
  • customerName: readable display name
  • customerPlan: current plan name and monthly revenue
  • userId: optional actor inside that customer account
Prefer namespaced IDs such as workspace_123, org_abc, or stripe_cus_123. Margovia stores the ID exactly as sent so it can join back to your app and billing data.