# AgentMeter SDK for TypeScript

A comprehensive TypeScript SDK for integrating with the AgentMeter usage-based billing API. Track events, manage applications and meters, and retrieve usage analytics with full type safety.

[![npm version](https://badge.fury.io/js/agentmeter.svg)](https://badge.fury.io/js/agentmeter)
[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features

- 🔒 **Type Safe** - Full TypeScript support with comprehensive type definitions
- 🚀 **Easy to Use** - Simple, intuitive API with extensive documentation
- ⚡ **Reliable** - Built-in retry logic, error handling, and timeout management
- 📊 **Comprehensive** - Support for all AgentMeter API endpoints
- 🔄 **Batch Processing** - Efficient batch event tracking
- 🛡️ **Validation** - Input validation with helpful error messages
- 📈 **Analytics Ready** - Built-in methods for usage analytics and billing

## Installation

```bash
npm install agentmeter
# or
yarn add agentmeter
# or
pnpm add agentmeter
```

## Quick Start

```typescript
import { AgentMeterClient } from 'agentmeter';

// Create client instance
const client = new AgentMeterClient({
  apiKey: process.env.AGENTMETER_API_KEY!,
});

// Track an event
await client.trackEvent({
  event_name: 'api_call',
  user_id: 'user-123',
  properties: {
    endpoint: '/api/users',
    method: 'GET',
  },
});

// Get usage data
const usage = await client.getUsage({
  app_id: 'your-app-id',
  period_start: '2023-01-01T00:00:00Z',
  period_end: '2023-01-31T23:59:59Z',
});
```

## Configuration

```typescript
const client = new AgentMeterClient({
  apiKey: 'your-api-key',
  baseUrl: 'https://tcwvgqbyyboxnbrsbchx.functions.supabase.co', // optional
  timeout: 30000, // 30 seconds (optional)
  retryAttempts: 3, // optional
  retryDelay: 1000, // 1 second (optional)
  debug: false, // optional
});
```

## API Reference

### Apps Management

```typescript
// Create an application
const app = await client.createApp({
  name: 'My SaaS App',
  description: 'Application description',
  webhook_url: 'https://myapp.com/webhooks/agentmeter',
});

// Get all applications
const apps = await client.getApps();

// Get specific application
const app = await client.getApp('app-id');

// Update application
const updatedApp = await client.updateApp('app-id', {
  name: 'Updated App Name',
  status: 'active',
});

// Delete application
await client.deleteApp('app-id');
```

### Meters Management

```typescript
// Create a meter
const meter = await client.createMeter({
  app_id: 'your-app-id',
  name: 'API Calls',
  event_name: 'api_call',
  aggregation_method: 'COUNT',
  price_per_unit: 0.01,
  currency: 'USD',
  billing_cycle: 'monthly',
});

// Get meters for an app
const meters = await client.getMeters('app-id');

// Update meter
const updatedMeter = await client.updateMeter('meter-id', {
  price_per_unit: 0.02,
  status: 'active',
});
```

### Event Tracking

```typescript
// Track single event
await client.trackEvent({
  event_name: 'api_call',
  user_id: 'user-123',
  properties: {
    endpoint: '/api/data',
    method: 'GET',
    status_code: 200,
  },
  value: 1,
});

// Track multiple events
await client.trackEvents([
  {
    event_name: 'api_call',
    user_id: 'user-123',
    properties: { endpoint: '/api/users' },
  },
  {
    event_name: 'feature_usage',
    user_id: 'user-456',
    properties: { feature: 'export' },
  },
]);

// Convenience methods
await client.trackApiCall('user-123', '/api/endpoint', 'GET');
await client.trackFeatureUsage('user-123', 'advanced_search', 1);
```

### Usage Analytics

```typescript
// Get usage summary
const usage = await client.getUsage({
  app_id: 'your-app-id',
  period_start: '2023-01-01T00:00:00Z',
  period_end: '2023-01-31T23:59:59Z',
  group_by: 'user_id', // optional
});

// Get time series data
const timeSeries = await client.getUsageTimeSeries({
  meter_id: 'meter-id',
  interval: 'day',
  start_date: '2023-01-01',
  end_date: '2023-01-31',
});

// Get billing summary
const billing = await client.getBillingSummary(
  'app-id',
  '2023-01-01T00:00:00Z',
  '2023-01-31T23:59:59Z',
  true // group by user
);
```

## Error Handling

```typescript
import { AgentMeterError, ValidationError, NetworkError } from 'agentmeter';

try {
  await client.trackEvent({
    event_name: 'test_event',
    // ... other properties
  });
} catch (error) {
  if (error instanceof ValidationError) {
    console.log('Validation error:', error.message);
  } else if (error instanceof AgentMeterError) {
    console.log('API error:', error.message, error.statusCode);
  } else if (error instanceof NetworkError) {
    console.log('Network error:', error.message);
  } else {
    console.log('Unexpected error:', error);
  }
}
```

## Advanced Usage

### Middleware Integration

```typescript
// Express.js middleware example
function trackApiUsage(req, res, next) {
  const startTime = Date.now();
  
  res.on('finish', async () => {
    const duration = Date.now() - startTime;
    
    try {
      await client.trackEvent({
        event_name: 'api_call',
        user_id: req.user?.id || 'anonymous',
        properties: {
          endpoint: req.path,
          method: req.method,
          status_code: res.statusCode,
          response_time_ms: duration,
        },
      });
    } catch (error) {
      console.error('Failed to track API usage:', error);
    }
  });
  
  next();
}

app.use(trackApiUsage);
```

### Batch Processing

```typescript
// Process events in batches
const events = [...]; // Your events array
const batchSize = 50;

for (let i = 0; i < events.length; i += batchSize) {
  const batch = events.slice(i, i + batchSize);
  try {
    await client.trackEvents(batch);
  } catch (error) {
    console.error(`Batch ${i / batchSize + 1} failed:`, error);
  }
}
```

## TypeScript Support

The SDK is built with TypeScript and provides full type definitions:

```typescript
import type {
  App,
  Meter,
  Event,
  Usage,
  UsageSummary,
  CreateEventRequest,
  ApiResponse,
} from 'agentmeter';

// All API responses are properly typed
const response: ApiResponse<App[]> = await client.getApps();
```

## Testing

The SDK includes comprehensive tests. Run them with:

```bash
npm test
```

## Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.

## License

MIT License - see the [LICENSE](LICENSE) file for details.

## Support

- 📖 [Documentation](https://docs.agentmeter.com)
- 🐛 [Issues](https://github.com/agentmeter/agentmeter-sdk-typescript/issues)
- 💬 [Discussions](https://github.com/agentmeter/agentmeter-sdk-typescript/discussions)

## Examples

Check out the [examples](examples/) directory for more comprehensive usage examples:

- [Basic Usage](examples/basic-usage.ts) - Getting started guide
- [Advanced Usage](examples/advanced-usage.ts) - Complex scenarios and best practices