UNPKG

@subscribe.dev/client

Version:

JavaScript/TypeScript client for SubscribeDev API - A drop-in for AI generation across 100+ models with built-in billing and rate limiting

533 lines (408 loc) 14.4 kB
# @subscribe.dev/client A JavaScript SDK for AI model inference with integrated billing, rate limiting, and user management. Subscribe.dev provides access to curated AI models with built-in cost tracking and analytics through a unified API. ## Features - 🚀 **100+ AI Models** - Curated collection of state-of-the-art models for various use cases - 💰 **Integrated Billing** - Transparent pricing with automatic cost tracking and detailed usage analytics - 🔒 **Secure Authentication** - Dual-layer authentication with project and user-level access control -**Rate Limiting** - Built-in request queuing with configurable limits and retry logic - 📊 **Usage Analytics** - Real-time tracking of requests, costs, and performance metrics - 🔐 **User Storage** - Session data persistence and user preferences management - 📱 **JavaScript Support** - Works in Node.js, browser, and JavaScript runtime environments - 🛡️ **Error Handling** - Comprehensive error types with detailed context and retry mechanisms - 🎯 **Easy Integration** - Compatible with existing JavaScript AI workflows ## Getting Started ### 1. Create a Subscribe.dev Account 1. Visit [Subscribe.dev](https://subscribe.dev) and create an account 2. Create a new project in your dashboard 3. Copy your project API key (starts with `pub_`) from the project overview 4. Leave defaults-- or configure your users' plans, features and limits ### 2. Installation ```bash npm install @subscribe.dev/client # or yarn add @subscribe.dev/client # or bun add @subscribe.dev/client ``` ### 3. Quick Start ```typescript import { SubscribeDevClient } from '@subscribe.dev/client' // Initialize the client with your [Subscribe.dev](https://subscribe.dev) credentials const client = new SubscribeDevClient({ apiKey: 'pub_your_project_api_key', // From your [Subscribe.dev](https://subscribe.dev) project dashboard userKey: 'your_user_token' // From your [Subscribe.dev](https://subscribe.dev) account }) // Run any AI model with a single API call const result = await client.run('black-forest-labs/flux-schnell', { input: { prompt: 'A majestic mountain landscape at sunset', num_inference_steps: 4, guidance_scale: 3.5 } }) console.log('Generated image:', result.output) ``` ## Configuration ### SubscribeDevClientConfig ```typescript interface SubscribeDevClientConfig { /** Public API key (project bearer token) - required */ apiKey: string /** User token for user-specific limits and features */ userKey: string /** Request timeout in milliseconds (default: 300000 = 5 minutes) */ timeout?: number /** Maximum retry attempts (default: 2) */ maxRetries?: number /** Enable debug logging (default: false) */ debug?: boolean } ``` ## API Reference ### Core Methods #### `run(model, options)` The main method for running predictions. Returns completed results. ```typescript await client.run( 'black-forest-labs/flux-schnell', { input: { prompt: 'A beautiful landscape', width: 1024, height: 1024 }, webhook?: 'https://your-site.com/webhook', webhook_events_filter?: ['completed', 'failed'] } ) ``` **Returns:** `Promise<Prediction>` - Completed prediction with output #### `createPrediction(model, options)` Create a prediction and return immediately (legacy method). ```typescript const prediction = await client.createPrediction('model-name', { input: { prompt: 'test' } }) ``` ### Balance & Billing #### `getBalance()` Get current project and user credit balances. ```typescript const balance = await client.getBalance() console.log('Project credits:', balance.project.remainingCredits) console.log('User credits:', balance.user?.remainingCredits) ``` **Returns:** `Promise<BalanceInfo>` ```typescript interface BalanceInfo { project: ProjectBalance user?: UserBalance } interface ProjectBalance { projectId: string totalCredits: number usedCredits: number remainingCredits: number lastUpdated: Date } ``` #### `getTransactions(options?)` Retrieve transaction history with filtering. ```typescript const history = await client.getTransactions({ limit: 50, offset: 0, status: 'completed', model: 'black-forest-labs/flux-schnell', startDate: '2024-01-01', endDate: '2024-12-31' }) ``` **Returns:** `Promise<TransactionHistory>` ### Rate Limiting #### `getRateLimits()` Get current rate limit status. ```typescript const limits = await client.getRateLimits() console.log('Concurrent requests:', limits.concurrent.currentRequests) console.log('Hourly limit reached:', !limits.hour?.allowed) ``` ### User Storage #### `getStorage(options?)` Retrieve user session data. ```typescript const storage = await client.getStorage({ appVersion: 'v1.0' }) console.log('Session data:', storage.sessionData) ``` #### `setStorage(sessionData, options?)` Update user session data. ```typescript await client.setStorage( { preferences: { theme: 'dark' }, gameState: { level: 5 } }, { appVersion: 'v1.0' } ) ``` #### `deleteStorage(options?)` Clear user session data. ```typescript await client.deleteStorage({ appVersion: 'v1.0' }) ``` ### Browser Convenience Methods #### `persistSessionData(options?)` Sync session data to localStorage (browser only). ```typescript // Automatically saves to localStorage and server const storage = await client.persistSessionData() ``` #### `getSessionData(options?)` Get session data with localStorage caching. ```typescript // Always fetches from server, updates localStorage cache const sessionData = await client.getSessionData() ``` ### Subscription Management #### `getSubscriptionStatus()` Get user subscription information (requires userKey). ```typescript // Requires userKey in client configuration const subscription = await client.getSubscriptionStatus() if (subscription.hasActiveSubscription) { console.log('Plan:', subscription.plan?.name) console.log('Credits:', subscription.plan?.tokenLimit) } ``` ## Authentication Subscribe.dev uses a dual authentication system: ### Project API Keys - **Format:** `pub_[base64_jwt_token]` - **Scope:** Project-level access and billing - **Location:** Get from [Subscribe.dev](https://subscribe.dev) dashboard → Project → Overview tab - **Usage:** Required for all requests ```typescript const client = new SubscribeDevClient({ apiKey: 'pub_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' }) ``` ### User Tokens (Required) - **Scope:** User-specific limits and storage - **Usage:** Per-user rate limiting and session management ```typescript const client = new SubscribeDevClient({ apiKey: 'pub_your_project_key', userKey: 'user_specific_token' }) ``` ## Error Handling The client provides specific error types for different scenarios: ```typescript import { SubscribeDevClient, InsufficientBalanceError, RateLimitError, AuthenticationError, ValidationError } from '@subscribe.dev/client' try { const result = await client.run('model-name', { input: {} }) } catch (error) { if (error instanceof InsufficientBalanceError) { console.log('Remaining credits:', error.details?.remainingCredits) console.log('Required credits:', error.details?.requiredCredits) console.log('Pricing page:', client.pricingUrl) } else if (error instanceof RateLimitError) { console.log('Rate limited until:', error.resetTime) console.log('Retry after seconds:', error.retryAfter) } else if (error instanceof AuthenticationError) { console.log('Invalid API key or user token') } else if (error instanceof ValidationError) { console.log('Invalid request:', error.details) } } ``` ### Error Types - **`SubscribeDevError`** - Base error class - **`InsufficientBalanceError`** - Not enough credits (402) - **`RateLimitError`** - Rate limit exceeded (429) - **`AuthenticationError`** - Invalid credentials (401) - **`AccessDeniedError`** - Permission denied (403) - **`NotFoundError`** - Resource not found (404) - **`ValidationError`** - Invalid request data (400) ## Usage Examples ### Basic Image Generation ```typescript import { SubscribeDevClient } from '@subscribe.dev/client' const client = new SubscribeDevClient({ apiKey: process.env.SUBSCRIBE_DEV_API_KEY! }) const result = await client.run('black-forest-labs/flux-schnell', { input: { prompt: 'A cyberpunk cityscape at night, neon lights, 4k', num_inference_steps: 4, guidance_scale: 3.5, width: 1024, height: 1024 } }) console.log('Generated images:', result.output) // Array of image URLs ``` ### With User Token and Error Handling ```typescript import { SubscribeDevClient, InsufficientBalanceError } from '@subscribe.dev/client' const client = new SubscribeDevClient({ apiKey: process.env.SUBSCRIBE_DEV_API_KEY!, userKey: process.env.USER_TOKEN!, // User-specific limits debug: true }) try { // Check balance first const balance = await client.getBalance() console.log('Available credits:', balance.project.remainingCredits) if (balance.project.remainingCredits < 10) { console.log('Low credits! Consider upgrading:', client.pricingUrl) } // Run prediction const result = await client.run('stability-ai/sdxl', { input: { prompt: 'A majestic dragon in a fantasy landscape' } }) console.log('Success!', result.output) // Check updated balance const newBalance = await client.getBalance() const used = balance.project.remainingCredits - newBalance.project.remainingCredits console.log('Credits used:', used) } catch (error) { if (error instanceof InsufficientBalanceError) { console.error('Need more credits:', error.details) } else { console.error('Error:', error.message) } } ``` ### Session Storage Example ```typescript const client = new SubscribeDevClient({ apiKey: process.env.SUBSCRIBE_DEV_API_KEY!, userKey: process.env.USER_TOKEN! // Required for storage }) // Load existing session data const existingData = await client.getSessionData() console.log('Previous session:', existingData) // Update session with new data await client.setStorage({ ...existingData, lastModel: 'black-forest-labs/flux-schnell', generationCount: (existingData.generationCount || 0) + 1, preferences: { defaultSteps: 4, favoriteStyles: ['photorealistic', 'cinematic'] } }) // In browser environments, also sync to localStorage if (typeof window !== 'undefined') { await client.persistSessionData() } ``` ### Transaction History and Analytics ```typescript // Get recent completed transactions const history = await client.getTransactions({ limit: 20, status: 'completed' }) console.log(`Found ${history.transactions.length} transactions`) // Calculate total spending const totalCost = history.transactions.reduce( (sum, tx) => sum + (tx.actualCost || tx.estimatedCost), 0 ) console.log('Total spent:', totalCost, 'credits') // Find most used models const modelUsage = history.transactions.reduce((acc, tx) => { acc[tx.modelName] = (acc[tx.modelName] || 0) + 1 return acc }, {} as Record<string, number>) console.log('Model usage:', modelUsage) ``` ### Rate Limit Monitoring ```typescript // Check current rate limits const limits = await client.getRateLimits() console.log('Rate limit status:') console.log(`Concurrent: ${limits.concurrent.currentRequests}/${limits.concurrent.maxRequests}`) if (limits.minute) { console.log(`Per minute: ${limits.minute.currentRequests}/${limits.minute.maxRequests}`) console.log(`Resets at: ${limits.minute.resetTime}`) } if (limits.hour) { console.log(`Per hour: ${limits.hour.currentRequests}/${limits.hour.maxRequests}`) } // Check if we're approaching limits if (limits.concurrent.currentRequests > limits.concurrent.maxRequests * 0.8) { console.warn('Approaching concurrent request limit') } ``` ## Environment Variables ```bash # Required - Your Subscribe.dev project API key SUBSCRIBE_DEV_API_KEY=pub_your_api_key_here # Required - User token for user-specific features SUBSCRIBE_DEV_USER_KEY=your_user_token_here ``` ## TypeScript Support The client is written in TypeScript and provides full type definitions: ```typescript import type { SubscribeDevClientConfig, Prediction, BalanceInfo, TransactionHistory, UserStorage, SubscriptionStatus } from '@subscribe.dev/client' ``` ## Migration from Other Platforms The Subscribe.dev client offers seamless migration: ```typescript // Before (Other platforms) import OtherClient from 'other-ai-platform' const client = new OtherClient({ auth: 'your-token' }) // After (Subscribe.dev - More models, better features) import { SubscribeDevClient } from '@subscribe.dev/client' const client = new SubscribeDevClient({ apiKey: 'pub_your-token' }) // Same API const result = await client.run('model-name', { input: {} }) ``` ### Key Advantages 1. **Unified Access**: Single SDK for 100+ curated models across multiple AI providers 2. **Built-in Management**: Native billing, analytics, and user management for production applications 3. **Optimized Requests**: Intelligent routing with automatic retries and completion handling 4. **Extended Features**: User storage, subscription management, and detailed analytics 5. **Transparent Pricing**: Clear cost tracking with automatic optimization 6. **Reliable Operation**: Comprehensive error handling and monitoring capabilities ## Browser Usage The client works in browser environments with CORS support: ```html <script type="module"> import { SubscribeDevClient } from 'https://unpkg.com/@subscribe.dev/client@latest/dist/index.js' const client = new SubscribeDevClient({ apiKey: 'pub_your_public_api_key', // Safe to embed in frontend userKey: localStorage.getItem('user_token')! // User context }) // Use normally const result = await client.run('model', { input: {} }) </script> ``` ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests 5. Submit a pull request ## Support - 📖 **Documentation**: [docs.subscribe.dev](https://docs.subscribe.dev) - 🐛 **Issues**: [GitHub Issues](https://github.com/subscribe-dev/subscribe-dev/issues) - 💬 **Discord**: [Join our community](https://discord.gg/subscribe-dev) - 📧 **Email**: [support@subscribe.dev](mailto:support@subscribe.dev) ## License MIT License - see [LICENSE](../../LICENSE) for details.