Owostack
SDK Reference

track()

Record usage for metered billing

track()

Record usage events for metered billing. Use this to track API calls, storage, messages, or any countable resource.

Signature

await owo.track({
  customer: string,    // Your internal user ID
  feature: string,     // Feature key being used
  value?: number,      // Amount to track (default: 1)
  entity?: string,     // Optional entity scope (seat, workspace, org)
  customerData?: {     // Optional: auto-create customer
    email: string,
    name?: string,
    metadata?: Record<string, unknown>,
  },
  metadata?: object,   // Optional event metadata
}): Promise<TrackResult>

Parameters

ParameterTypeRequiredDescription
customerstringYour internal user ID
featurestringFeature key to record usage against
valuenumber-Amount to add (default: 1)
entitystring-Scope to an entity (must exist)
customerDataobject-Auto-create customer if missing
metadataobject-Additional event data for auditing

When using entity, the entity must be created with addEntity() first. Tracking a non-existent entity returns entity_not_found error.

Response

interface TrackResult {
  success: boolean;
  allowed: boolean; // Whether the usage was accepted
  code: string; // tracked, tracked_overage, limit_exceeded, etc.
  usage: number | null;
  limit: number | null;
  balance: number | null; // Remaining balance when applicable
  resetsAt: string | null; // Period reset time
  resetInterval: string | null;
  details: {
    message: string;
    planName?: string;
    trial?: boolean;
    trialEndsAt?: string | null;
  };
}

Examples

Basic Usage Tracking

import { Owostack } from "@owostack/core";

const owo = new Owostack({ secretKey: process.env.OWOSTACK_API_KEY });

// Track a single API call
await owo.track({
  customer: "user_123",
  feature: "api_calls",
});

Track Custom Amounts

// Track storage usage (e.g., 1.5 MB uploaded)
await owo.track({
  customer: "user_123",
  feature: "storage_mb",
  value: 1.5,
});

// Track multiple items at once
await owo.track({
  customer: "user_123",
  feature: "messages_sent",
  value: 10,
});

With Metadata

await owo.track({
  customer: "user_123",
  feature: "api_calls",
  value: 1,
  metadata: {
    endpoint: "/api/generate",
    responseTime: 234,
    model: "gpt-4",
  },
});

Check Then Track Pattern

// Common pattern: check quota, then track usage
async function processRequest(userId: string) {
  // 1. Check if customer has remaining quota
  const check = await owo.check({
    customer: userId,
    feature: "api_calls",
  });

  if (!check.allowed) {
    throw new Error(`Quota exceeded. Resets at ${check.resetsAt}`);
  }

  // 2. Process the request
  const result = await expensiveOperation();

  // 3. Track usage after successful completion
  await owo.track({
    customer: userId,
    feature: "api_calls",
  });

  return result;
}

Billing Models

Pay-per-use

Track every unit and invoice at the end of the billing period:

// Track each AI token generated
await owo.track({
  customer: "user_123",
  feature: "ai_tokens",
  value: response.usage.total_tokens,
});

Monthly Quotas

Track against a fixed monthly limit:

const result = await owo.track({
  customer: "user_123",
  feature: "exports",
});

console.log(`${result.balance} exports remaining this month`);

Credit-based

Consume from a prepaid credit balance:

await owo.track({
  customer: "user_123",
  feature: "credits",
  value: operationCost, // e.g., 5 credits for this operation
});

Best Practices

  1. Track after success - Only track after the operation completes successfully
  2. Non-blocking - Use fire-and-forget for non-critical tracking
  3. Batch if needed - For high-volume, batch multiple events together
  4. Include context - Add metadata for debugging and analytics

On this page