The Check-Record Pattern
Always check limits before, record events after:Copy
import Limitry from '@limitry/sdk';
import OpenAI from 'openai';
const limitry = new Limitry();
const openai = new OpenAI();
async function chat(customerId: string, message: string): Promise<string> {
// 1. Check limits
const check = await limitry.limits.check({ customerId });
if (!check.allowed) {
throw new Error(`Limit exceeded: ${check.limits[0].name}`);
}
// 2. Make request
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [{ role: 'user', content: message }]
});
// 3. Record event
await limitry.events.record({
customerId,
eventType: 'llm.completion',
values: { tokens: response.usage!.total_tokens },
dimensions: { model: 'gpt-4' }
});
return response.choices[0].message.content!;
}
Record Events
Log usage after each operation:Copy
const result = await limitry.events.record({
customerId: 'cust_123',
eventType: 'llm.completion',
// Numeric values (for metering)
values: {
tokens: 500,
cost_cents: 25,
latency_ms: 1200
},
// Categorical dimensions (for filtering)
dimensions: {
model: 'gpt-4',
provider: 'openai',
feature: 'chat'
}
});
console.log(`Recorded event: ${result.id}`);
Values vs Dimensions
- Values: Numbers that can be summed, averaged, or maxed by meters
- Dimensions: Strings for filtering and grouping
Copy
// Values are numeric
values: {
tokens: 500,
cost_cents: 25,
images: 4
}
// Dimensions are strings
dimensions: {
model: 'gpt-4',
team: 'engineering',
environment: 'production'
}
List Events
Retrieve recorded events with filtering:Copy
// List all events
const events = await limitry.events.list();
for (const event of events.data) {
console.log(`${event.id}: ${event.customerId} - ${event.eventType}`);
console.log(` Values: ${JSON.stringify(event.values)}`);
console.log(` Dimensions: ${JSON.stringify(event.dimensions)}`);
}
// Filter by customer
const events = await limitry.events.list({ customerId: 'cust_123' });
// Filter by event type
const events = await limitry.events.list({ eventType: 'llm.completion' });
// Filter by date range
const events = await limitry.events.list({
startDate: '2024-01-01T00:00:00Z',
endDate: '2024-01-31T23:59:59Z'
});
// Pagination
const events = await limitry.events.list({ limit: 50 });
if (events.hasMore) {
const nextPage = await limitry.events.list({ cursor: events.nextCursor });
}
Get Usage Summary
Aggregate usage over a time range:Copy
const summary = await limitry.events.getSummary({
startDate: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),
endDate: new Date().toISOString(),
customerId: 'cust_123' // Optional filter
});
console.log(`Total events: ${summary.totalEvents}`);
console.log(`Values: ${JSON.stringify(summary.values)}`);
Get Usage Breakdown
Group usage by dimension:Copy
const breakdown = await limitry.events.getBreakdown({
groupBy: 'model',
startDate: '2024-01-01T00:00:00Z',
endDate: '2024-01-31T23:59:59Z'
});
for (const item of breakdown.data) {
console.log(`${item.dimension}: ${item.totalEvents} events`);
console.log(` Values: ${JSON.stringify(item.values)}`);
}
Batch Recording
Record multiple events efficiently:Copy
const result = await limitry.events.batchIngest({
events: [
{
customerId: 'cust_123',
eventType: 'llm.completion',
values: { tokens: 500 },
dimensions: { model: 'gpt-4' }
},
{
customerId: 'cust_456',
eventType: 'llm.embedding',
values: { tokens: 1000 },
dimensions: { model: 'text-embedding-3-small' }
}
]
});
console.log(`Recorded ${result.count} events`);
Event Types
Use descriptive event types:Copy
// LLM operations
eventType: 'llm.completion'
eventType: 'llm.embedding'
// Image operations
eventType: 'image.generation'
// Agent operations
eventType: 'agent.run'
// Resource tracking
eventType: 'agent.count'
// Custom operations
eventType: 'feature.usage'
Example: Full Integration
Copy
import Limitry from '@limitry/sdk';
import OpenAI from 'openai';
const limitry = new Limitry();
const openai = new OpenAI();
async function processRequest(customerId: string, prompt: string): Promise<string> {
// 1. Check limits
const check = await limitry.limits.check({ customerId });
if (!check.allowed) {
const exceeded = check.limits.find(l => l.exceeded);
throw new Error(`Limit exceeded: ${exceeded?.name}`);
}
// 2. Make the LLM call
const startTime = Date.now();
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [{ role: 'user', content: prompt }]
});
const latencyMs = Date.now() - startTime;
// 3. Record comprehensive event
await limitry.events.record({
customerId,
eventType: 'llm.completion',
values: {
input_tokens: response.usage!.prompt_tokens,
output_tokens: response.usage!.completion_tokens,
total_tokens: response.usage!.total_tokens,
latency_ms: latencyMs
},
dimensions: {
model: 'gpt-4',
provider: 'openai',
feature: 'chat'
}
});
return response.choices[0].message.content!;
}