Skip to main content
Copy-paste patterns for implementing dynamic and usage-based pricing.

Token-Based Pricing

Charge based on input/output token count (common for LLM APIs):
interface TokenPricing {
  inputTokenPrice: number   // credits per 1K input tokens
  outputTokenPrice: number  // credits per 1K output tokens
  minimumCharge: number     // minimum credits per request
}

const PRICING: TokenPricing = {
  inputTokenPrice: 1,    // 1 credit per 1K input tokens
  outputTokenPrice: 3,   // 3 credits per 1K output tokens
  minimumCharge: 1       // minimum 1 credit
}

function calculateTokenCost(
  inputTokens: number,
  outputTokens: number,
  pricing: TokenPricing = PRICING
): number {
  const inputCost = Math.ceil((inputTokens / 1000) * pricing.inputTokenPrice)
  const outputCost = Math.ceil((outputTokens / 1000) * pricing.outputTokenPrice)
  const totalCost = inputCost + outputCost

  return Math.max(totalCost, pricing.minimumCharge)
}

// Usage
async function processLLMRequest(prompt: string, payment: PaymentInfo) {
  const inputTokens = countTokens(prompt)
  const estimatedOutputTokens = inputTokens * 2  // Rough estimate

  const estimatedCost = calculateTokenCost(inputTokens, estimatedOutputTokens)

  if (payment.balance < estimatedCost) {
    throw new Error(`Insufficient credits. Estimated: ${estimatedCost}, Available: ${payment.balance}`)
  }

  const response = await generateResponse(prompt)
  const outputTokens = countTokens(response)
  const actualCost = calculateTokenCost(inputTokens, outputTokens)

  return {
    response,
    usage: {
      inputTokens,
      outputTokens,
      creditsUsed: actualCost,
      creditsRemaining: payment.balance - actualCost
    }
  }
}

Complexity-Based Pricing

Charge based on operation complexity:
enum OperationType {
  SIMPLE_QUERY = 'simple_query',
  COMPLEX_ANALYSIS = 'complex_analysis',
  IMAGE_GENERATION = 'image_generation',
  BATCH_PROCESSING = 'batch_processing'
}

const OPERATION_COSTS: Record<OperationType, number> = {
  [OperationType.SIMPLE_QUERY]: 1,
  [OperationType.COMPLEX_ANALYSIS]: 5,
  [OperationType.IMAGE_GENERATION]: 10,
  [OperationType.BATCH_PROCESSING]: 20
}

function detectOperationType(request: any): OperationType {
  if (request.type === 'image') {
    return OperationType.IMAGE_GENERATION
  }

  if (request.batch && request.batch.length > 1) {
    return OperationType.BATCH_PROCESSING
  }

  if (request.analysis || request.options?.detailed) {
    return OperationType.COMPLEX_ANALYSIS
  }

  return OperationType.SIMPLE_QUERY
}

function calculateComplexityCost(request: any): {
  operationType: OperationType
  baseCost: number
  multiplier: number
  totalCost: number
} {
  const operationType = detectOperationType(request)
  const baseCost = OPERATION_COSTS[operationType]

  // Apply multipliers based on options
  let multiplier = 1

  if (request.options?.highQuality) {
    multiplier *= 1.5
  }

  if (request.options?.priority) {
    multiplier *= 2
  }

  if (request.batch) {
    multiplier *= request.batch.length
  }

  return {
    operationType,
    baseCost,
    multiplier,
    totalCost: Math.ceil(baseCost * multiplier)
  }
}

Time-Based Dynamic Pricing

Adjust pricing based on demand or time of day:
interface DynamicPricing {
  baseCredits: number
  peakMultiplier: number
  offPeakDiscount: number
}

function getPricingMultiplier(): number {
  const hour = new Date().getUTCHours()

  // Peak hours: 9 AM - 6 PM UTC
  if (hour >= 9 && hour < 18) {
    return 1.5  // 50% premium
  }

  // Off-peak: 10 PM - 6 AM UTC
  if (hour >= 22 || hour < 6) {
    return 0.5  // 50% discount
  }

  // Standard hours
  return 1.0
}

function calculateDynamicCost(
  baseCost: number,
  options?: { ignorePeakPricing?: boolean }
): number {
  if (options?.ignorePeakPricing) {
    return baseCost
  }

  const multiplier = getPricingMultiplier()
  return Math.ceil(baseCost * multiplier)
}

// Usage
app.post('/query', requirePayment(1), async (req, res) => {
  const baseCost = 1
  const actualCost = calculateDynamicCost(baseCost)

  if (req.payment!.balance < actualCost) {
    return res.status(402).json({
      error: 'Insufficient credits',
      required: actualCost,
      available: req.payment!.balance,
      note: 'Prices are higher during peak hours (9 AM - 6 PM UTC)'
    })
  }

  // Process request...
})

Usage-Based Tiers

Implement tiered pricing based on monthly usage:
interface UsageTier {
  name: string
  minUsage: number
  maxUsage: number
  pricePerCredit: number  // Discount rate
}

const USAGE_TIERS: UsageTier[] = [
  { name: 'starter', minUsage: 0, maxUsage: 100, pricePerCredit: 1.0 },
  { name: 'growth', minUsage: 101, maxUsage: 1000, pricePerCredit: 0.8 },
  { name: 'scale', minUsage: 1001, maxUsage: 10000, pricePerCredit: 0.6 },
  { name: 'enterprise', minUsage: 10001, maxUsage: Infinity, pricePerCredit: 0.4 }
]

async function getEffectivePrice(
  subscriberAddress: string,
  baseCost: number
): Promise<{ cost: number; tier: string; discount: number }> {
  // Get monthly usage from your tracking system
  const monthlyUsage = await getMonthlyUsage(subscriberAddress)

  const tier = USAGE_TIERS.find(
    t => monthlyUsage >= t.minUsage && monthlyUsage <= t.maxUsage
  ) || USAGE_TIERS[0]

  const effectiveCost = Math.ceil(baseCost * tier.pricePerCredit)
  const discount = Math.round((1 - tier.pricePerCredit) * 100)

  return {
    cost: effectiveCost,
    tier: tier.name,
    discount
  }
}

// Usage
const pricing = await getEffectivePrice(subscriberAddress, 10)
// { cost: 6, tier: 'scale', discount: 40 }

Cost Estimation Endpoint

Provide a cost estimation endpoint:
app.post('/estimate', async (req, res) => {
  const { request, subscriberAddress } = req.body

  // Calculate various cost components
  const tokenCost = calculateTokenCost(
    countTokens(request.prompt),
    estimateOutputTokens(request.prompt)
  )

  const complexityCost = calculateComplexityCost(request)
  const dynamicMultiplier = getPricingMultiplier()

  // Get tier discount if subscriber is known
  let tierDiscount = 0
  if (subscriberAddress) {
    const pricing = await getEffectivePrice(subscriberAddress, 1)
    tierDiscount = pricing.discount
  }

  const baseCost = Math.max(tokenCost, complexityCost.totalCost)
  const adjustedCost = Math.ceil(baseCost * dynamicMultiplier)
  const finalCost = Math.ceil(adjustedCost * (1 - tierDiscount / 100))

  res.json({
    estimate: {
      baseCost,
      adjustments: {
        dynamicPricing: {
          multiplier: dynamicMultiplier,
          reason: dynamicMultiplier > 1 ? 'peak_hours' : dynamicMultiplier < 1 ? 'off_peak' : 'standard'
        },
        tierDiscount: {
          percent: tierDiscount,
          reason: tierDiscount > 0 ? 'volume_discount' : 'none'
        }
      },
      finalCost,
      breakdown: {
        tokenBased: tokenCost,
        complexity: complexityCost.totalCost,
        operationType: complexityCost.operationType
      }
    }
  })
})

Next Steps