Skip to main content

The Check-Record Pattern

Always check limits before, record events after:
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:
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
// 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:
// 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:
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:
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:
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:
// 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

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!;
}