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
| Parameter | Type | Required | Description |
|---|---|---|---|
customer | string | ✅ | Your internal user ID |
feature | string | ✅ | Feature key to record usage against |
value | number | - | Amount to add (default: 1) |
entity | string | - | Scope to an entity (must exist) |
customerData | object | - | Auto-create customer if missing |
metadata | object | - | 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
- Track after success - Only track after the operation completes successfully
- Non-blocking - Use fire-and-forget for non-critical tracking
- Batch if needed - For high-volume, batch multiple events together
- Include context - Add metadata for debugging and analytics