Quickstart

From zero to your first tracked event in three minutes.

1. Install

pnpm add @vevee/sdk
# or
npm install @vevee/sdk
# or
yarn add @vevee/sdk

The SDK has zero runtime dependencies and ships both ESM and CommonJS builds with full .d.ts types.

2. Create an app and grab a secret key

  1. Sign in at www.vevee.org and create a workspace.
  2. Create an app - this is the metered surface (e.g. VisualNote).
  3. Open API Keys and generate a sk_live_… secret key.
!
Never expose sk_live_ keys in client-side code, mobile binaries, or public repos. Use a pk_live_public key for code that runs on the user's device - it can only read that user's own usage.

3. Initialize the client

import { createClient } from '@vevee/sdk';

export const vevee = createClient({
  apiKey: process.env.VEVEE_KEY!,
  // baseUrl: 'https://www.vevee.org', // optional, this is the default
});

4. Track your first event

// Anywhere in your backend, after the AI call succeeds:
await vevee.track('user_abc123', 'image.render', 1, {
  model: 'flux-pro',
  resolution: '1024x1024',
});

Refresh your dashboard - the event shows up immediately under Usage. If the user has exceeded a limit, track() throws an VeveeError with code limit_reached.

5. Enforce limits the safe way

For anything that costs real money (image gen, video, expensive LLM calls), use the reserve / commitpattern. It atomically holds quota during the AI call so parallel requests can't bypass limits.

async function generateImage(userId: string, prompt: string) {
  const reservation = await vevee.reserve(userId, 'image.render', 1, {
    model: 'flux-pro',
  });

  if (!reservation.allowed) {
    throw new Error(`Limit reached: ${reservation.reasons?.join(', ')}`);
  }

  try {
    const image = await callFluxPro(prompt);          // your AI call
    await vevee.commit(reservation.reservationId!);   // confirm the charge
    return image;
  } catch (err) {
    await vevee.release(reservation.reservationId!);  // refund the quota
    throw err;
  }
}

6. (Optional) Read usage in your own UI

If you want to show users their own remaining quota, use a pk_live_ public key on the client:

'use client';
import { createClient } from '@vevee/sdk';

const vevee = createClient({ apiKey: process.env.NEXT_PUBLIC_VEVEE_KEY! });

const usage = await vevee.usage(currentUserId);
// usage.counters[0] -> { groupId, count, costCents }

You're done

Continue to Core concepts to understand limit groups and periods, or jump straight to the SDK reference.