npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@subscribe.dev/client

v0.0.111

Published

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

Downloads

5,132

Readme

@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 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

npm install @subscribe.dev/client
# or
yarn add @subscribe.dev/client
# or
bun add @subscribe.dev/client

3. Quick Start

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

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.

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).

const prediction = await client.createPrediction('model-name', {
  input: { prompt: 'test' }
})

Balance & Billing

getBalance()

Get current project and user credit balances.

const balance = await client.getBalance()
console.log('Project credits:', balance.project.remainingCredits)
console.log('User credits:', balance.user?.remainingCredits)

Returns: Promise<BalanceInfo>

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.

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.

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.

const storage = await client.getStorage({ appVersion: 'v1.0' })
console.log('Session data:', storage.sessionData)

setStorage(sessionData, options?)

Update user session data.

await client.setStorage(
  { preferences: { theme: 'dark' }, gameState: { level: 5 } },
  { appVersion: 'v1.0' }
)

deleteStorage(options?)

Clear user session data.

await client.deleteStorage({ appVersion: 'v1.0' })

File Uploads

uploadFile(file, options?)

Upload user files and get back a public S3 URL.

const imageUrl = await client.uploadFile(file)
// Returns: "https://bucket.s3.amazonaws.com/uploads/..."

// With user context
const imageUrl = await client.uploadFile(file, { userId: 'user-123' })

Browser Convenience Methods

persistSessionData(options?)

Sync session data to localStorage (browser only).

// Automatically saves to localStorage and server
const storage = await client.persistSessionData()

getSessionData(options?)

Get session data with localStorage caching.

// Always fetches from server, updates localStorage cache
const sessionData = await client.getSessionData()

Subscription Management

getSubscriptionStatus()

Get user subscription information (requires userKey).

// 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 dashboard → Project → Overview tab
  • Usage: Required for all requests
const client = new SubscribeDevClient({
  apiKey: 'pub_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
})

User Tokens (Required)

  • Scope: User-specific limits and storage
  • Usage: Per-user rate limiting and session management
const client = new SubscribeDevClient({
  apiKey: 'pub_your_project_key',
  userKey: 'user_specific_token'
})

Error Handling

The client provides specific error types for different scenarios:

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

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

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

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

// 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

// 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

# 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:

import type { 
  SubscribeDevClientConfig,
  Prediction,
  BalanceInfo,
  TransactionHistory,
  UserStorage,
  SubscriptionStatus
} from '@subscribe.dev/client'

Migration from Other Platforms

The Subscribe.dev client offers seamless migration:

// 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:

<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>

Support

License

MIT License - see LICENSE for details.