npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@margovia/sdk

v0.1.4

Published

Track AI cost, customer attribution, and outcome economics from Node/JavaScript apps.

Readme

Margovia JavaScript SDK

Track AI cost, customer attribution, and outcome economics from Node/JavaScript apps.

Install

pnpm add @margovia/sdk
npm install @margovia/sdk

Environment

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 at https://api.margovia.com by default.

Set MARGOVIA_BASE_URL only if you self-host Margovia, run a compatible receiver, or test against a local API.

Why open source?

Margovia is a commercial product for AI gross margin reporting, budgets, customer profitability, and plan margin analysis.

This SDK is open source because instrumentation should be inspectable, portable, and easy to remove or replace. The SDK captures usage and attribution events; Margovia's hosted product turns those events into reporting and operational controls.

Where to use it

Use the SDK in server-side code that already calls OpenAI, Anthropic, or another model provider. Do not expose MARGOVIA_API_KEY in browser code.

Works with Node/JS backends such as Express, Fastify, Hono, Next.js route handlers/server actions, Remix actions, workers, and background jobs.

Plan pricing

Define your customer plan catalog once in your app, then attach the current account or workspace plan when making a model call.

const plans = {
  free: { name: "free", monthlyUsd: 0 },
  starter: { name: "starter", monthlyUsd: 29 },
  pro: { name: "pro", monthlyUsd: 99 },
  enterprise: { name: "enterprise", monthlyUsd: 499 },
} as const;

Margovia calculates AI cost from provider usage and model pricing. Your app supplies customer identity and what that customer pays you.

Customer attribution

Send the stable customer/account key from your app. Margovia preserves this value exactly and uses it for grouping, joins, aliases, and margin reporting.

Recommended IDs:

customerId: `workspace_${workspace.id}`
customerId: `org_${organization.id}`
customerId: `stripe_${stripeCustomer.id}`
customerId: `tenant_${tenant.id}`

Avoid raw values like "1" or "42" when possible. If your internal ID is numeric, prefix it before sending, such as workspace_42. Use customerName for display and aliases; do not change customerId just to make the dashboard prettier.

Recommended paths

Use the SDK based on what you are tracking:

| Situation | Use | | --- | --- | | One OpenAI or Anthropic call should become one tracked run | margovia.openai(client) or margovia.anthropic(client) | | You want to patch an existing provider client | wrapOpenAI(..., { autoTrack: true }) or wrapAnthropic(..., { autoTrack: true }) | | You already have your own provider helper function | trackOpenAI(...) or trackAnthropic(...) | | One product workflow has several provider/tool calls | margovia.track(...) around wrapped clients or manual cost calls | | You use another paid API or custom provider | startRun(...), run.trackCost(...), run.complete(...) |

margovia.track(...) is a workflow wrapper. It does not read provider token usage by itself. For AI cost tracking, use provider wrappers/helpers or manually report cost.

Easiest: tracked provider adapter

Create a tracked provider adapter once, then call it with Margovia run fields and the real provider request.

import OpenAI from "openai";
import { Margovia } from "@margovia/sdk";

const margovia = new Margovia({ apiKey: process.env.MARGOVIA_API_KEY });
const openai = margovia.openai(new OpenAI());

await openai.chat.completions.create({
  name: "support_reply",
  customerId: `workspace_${workspace.id}`,
  customerName: workspace.name,
  customerPlan: "pro",
  outcome: "reply_generated",
  request: {
    model: "gpt-5-mini",
    messages: buildSupportMessages(ticket)
  }
});

The adapter starts the run, calls OpenAI, reads response.usage, records cost, and completes or fails the run.

Explicit: provider helper

const response = await margovia.trackAnthropic({
  name: "score_tweet",
  customerId: `workspace_${workspace.id}`,
  customerName: workspace.name,
  outcome: "tweet_scored",
  request: params,
  fn: () => anthropic.messages.create(params)
});

This is the best replacement for custom helper code that manually calls startRun, run.trackCost, and run.complete.

Use a raw provider client inside trackOpenAI(...) or trackAnthropic(...). Do not pass an already-wrapped client into these helpers or you may double-report the same call.

Workflow grouping: .track(...)

Use .track(...) when one business workflow contains multiple tracked calls.

import OpenAI from "openai";
import { Margovia, customer, user } from "@margovia/sdk";

const workspace = await db.workspace.findById(req.user.workspaceId);
const customerPlan = plans[workspace.plan];
const openai = margovia.wrapOpenAI(new OpenAI());

await margovia.track({
  name: "weekly_report",
  outcome: "report_generated",
  ...customer({
    id: workspace.id,
    prefix: "workspace",
    name: workspace.name,
    plan: customerPlan
  }),
  ...user({ id: req.user.id }),
  fn: async () => {
    await openai.chat.completions.create({
      model: "gpt-5-mini",
      messages: buildSummaryMessages()
    });

    await openai.chat.completions.create({
      model: "gpt-5-mini",
      messages: buildRecommendationMessages()
    });
  }
});

Bad .track(...) use:

await margovia.track({
  name: "score_tweet",
  fn: () => anthropic.messages.create(params)
});

If anthropic is raw and not wrapped, Margovia sees a run but no token usage or cost.

Use stable, namespaced customer 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, billing system, logs, or warehouse.

Guardrail preflight

Use canRun(...) before expensive work when you want to check active budgets. For now this is advisory: hard and soft stops are reported, not enforced by the SDK.

const guardrail = await margovia.canRun({
  name: "support_reply",
  customerId: `workspace_${workspace.id}`,
  estimatedCostUsd: 0.05
});

if (!guardrail.allowed) {
  throw new Error("Margovia hard-stop budget would block this workflow");
}

Manual runs

Use manual runs only when you need explicit lifecycle control. For normal OpenAI or Anthropic calls, prefer wrappers or provider helpers. For multi-step workflows, prefer margovia.track(...) around wrapped clients or manual cost calls.

const run = await margovia.startRun({
  name: "generate_report",
  customerId: "workspace_123",
  customerName: "Acme Inc.",
  customerPlan: { name: "enterprise", monthlyUsd: 499 },
});

await run.trackCost({
  provider: "serpapi",
  label: "search_tool",
  costUsd: 0.01,
});

await run.complete({ outcome: "report_generated" });

Manual runs remain running until you call run.complete(...) or run.fail(...). Use margovia.track(...) if you want the SDK to handle completion and failure around a function.

When you want wrapped provider calls inside a manual run, execute them inside run.step(...) so the SDK can attach the cost event to the correct run:

const run = await margovia.startRun({
  name: "support_reply",
  customerId: "workspace_123",
  customerPlan: { name: "pro", monthlyUsd: 99 },
});

const response = await run.step("openai_reply", () =>
  openai.chat.completions.create({
    model: "gpt-5-mini",
    messages,
  })
);

await run.complete({ outcome: "reply_generated" });

Advanced examples

See examples/ for:

  • Express + Anthropic
  • Next.js route handler + OpenAI
  • Custom helper wrapper with lazy ESM import