Cockpitify Help

Track AI cost per user

Wrap your OpenAI, Anthropic or Vercel AI SDK client with @cockpitify/node so every AI call is recorded with its user and cost.

To see what each user costs you in AI, wrap the AI client on your server with the Cockpitify server SDK, @cockpitify/node. Every call is then recorded in your own Supabase project with the user, model, tokens and cost. It works with streaming and doesn’t slow your calls down.

Where to find it in the app

Open the Margin tab and tap Attribute AI cost to users, or use Tie AI cost to users in the setup checklist. The AI cost screen shows the code for your SDK and a live status that turns to Connected when the first call arrives.

Prefer to let an AI coding assistant do it? Switch to Paste into an AI assistant and copy the ready-made prompt.

Supported clients

  • OpenAI SDK, and OpenAI-compatible APIs through baseURL: DeepSeek, Groq, OpenRouter and others
  • Anthropic SDK: messages.create and messages.stream
  • Vercel AI SDK, as middleware
  • Plain fetch calls, with Ops.wrapFetch

Wrap the client

In a Supabase Edge Function, wrap the client where you create it. userId is the Supabase user making the request, and supabase is a service-role client:

// supabase/functions/chat/index.ts
import OpenAI from 'npm:openai'
import { Ops } from 'npm:@cockpitify/node'

const ai = Ops.wrap(new OpenAI({ baseURL, apiKey }), {
  userId: user.id,
  supabase, // service-role client
})

// Use `ai` exactly as before, streaming included.

The Anthropic SDK is wrapped the same way. For the Vercel AI SDK, add the middleware to the model:

import { wrapLanguageModel } from 'ai'

const model = wrapLanguageModel({
  model: openai('gpt-4o-mini'),
  middleware: Ops.middleware({ userId: user.id, supabase }),
})

Running on a regular Node.js server instead of an Edge Function? Call await Ops.flush() before the process exits, so the last records are written.

Calls that aren’t priced per token

For images, audio or anything priced by unit, record the call yourself:

await Ops.record({
  userId: user.id,
  supabase,
  provider: 'fal',
  model: 'flux-schnell',
  units: 1,
  unit: 'image',
  costUsd: 0.003,
})

Without costUsd, the call is recorded but stays unpriced.

How cost is calculated

  • Token prices come from a maintained list of around 200 models. Calls to a model that isn’t on the list are recorded as unpriced; the Margin tab tells you how many there are.
  • With streaming, Cockpitify asks the provider for usage automatically. If a stream is cut short, the tokens are estimated and marked as such.
  • The SDK fails open: if recording fails, your AI call still goes through.

Pass feature to see which feature spends the most:

const ai = Ops.wrap(client, { userId: user.id, supabase, feature: 'quiz' })

The key matches the features you define in Feature usage.

Next