Token Middleware Documentation

Fair and intelligent token management system for AI features

Overview

The Token Middleware (CheckAITokens) is a smart, fair system that ensures users have sufficient tokens before performing AI operations. It validates token requirements dynamically based on the type of operation and user-provided parameters.

Key Features

  • Fair Pricing: Each operation requires tokens proportional to its actual cost
  • Smart Calculation: Dynamic requirements based on parameters (e.g., duration, content size)
  • User-Friendly: Clear error messages showing exactly what's needed
  • Flexible: Works seamlessly with both JSON/AJAX and standard requests
  • Debt Protection: Prevents users from going into negative balances

How It Works

The middleware intercepts requests to AI-powered features and performs the following checks:

  1. Authentication Check: Verifies the user is logged in
  2. Operation Detection: Identifies the type of AI operation from the request path
  3. Token Calculation: Calculates minimum tokens required (may be dynamic)
  4. Balance Check: Compares user's current balance with requirements
  5. Decision: Either allows the request to proceed or returns an error

Middleware Location

app/Http/Middleware/CheckAITokens.php

Operations & Token Costs

The system supports various AI operations, each with specific token requirements:

Operation Minimum Tokens Calculation Type Description
Chat 50 Fixed AI chat messages (~50 messages worth)
AI Generate 250 Fixed Complete study material (6-10 lessons + quizzes)
LearnCast Dynamic Duration-based Podcast generation (250 tokens per minute)
YouTube Import 100 Fixed Import and process YouTube playlists
Content Manipulator 50 Fixed AI-powered content manipulation
Transcription 50 Fixed Video transcription services
Quiz Generation 30 Fixed Generate quiz questions from content
Video Overview 100 Fixed AI-generated video summaries
Default 50 Fixed Any other AI operation

Token Calculation Formulas

Different operations use different calculation methods to ensure fair pricing:

1. LearnCast Generation (Dynamic)

LearnCast tokens are calculated based on the target duration specified by the user:

Formula

Required Tokens = max(250, duration × 250)

Examples

• 1 minute = 250 tokens
• 10 minutes = 2,500 tokens
• 30 minutes = 7,500 tokens
• 45 minutes (max) = 11,250 tokens

if ($operation === 'learncast') { $duration = (int) $request->input('target_duration', 1); $estimated = max(250, ceil($duration * 250)); return $estimated; }

2. AI Material Generation (Fixed)

Generates complete study material with 6-10 lessons, each with a quiz:

Formula

Required Tokens = 250 (fixed)

Breakdown

• 8 lessons (average) × 8 tokens = 64 tokens
• 8 quizzes × 20 tokens (average) = 160 tokens
• Buffer for variations = 26 tokens
Total: 250 tokens

3. Chat Messages (Fixed)

Simple chat interactions with AI:

Formula

Required Tokens = 50 (fixed)

Details

• Actual cost: ~1 token per message
• Minimum balance of 50 tokens ensures ~50 messages
• Prevents frequent "out of tokens" interruptions

4. Other Operations (Fixed)

Fixed minimum requirements based on typical usage:

  • YouTube Import: 100 tokens (minimum for small playlists)
  • Content Manipulator: 50 tokens (per manipulation)
  • Video Transcription: 50 tokens (per video)
  • Quiz Generation: 30 tokens (per quiz)
  • Video Overview: 100 tokens (per overview)

User Types & Token Management

The system supports both teachers and students, with consistent token management:

Students

if ($user->isStudent() && $user->student) { $currentTokens = $user->student->getRemainingTokens(); $tokenPurchaseUrl = route('payment.tokens.packages'); }

Teachers

if ($user->isTeacher() && $user->teacher) { $currentTokens = $user->teacher->getRemainingTokens(); $tokenPurchaseUrl = route('payment.tokens.packages'); }

Negative Balance Protection

If a user's token balance is negative (debt), they are blocked from all AI operations until they purchase more tokens to reach zero or positive balance.

Usage Examples

Example 1: Student Wants to Generate LearnCast

Scenario

• User: Student
• Current Balance: 5,000 tokens
• Action: Generate 20-minute LearnCast
• Required: 20 × 250 = 5,000 tokens

Result

✓ Allowed - User has exactly enough tokens (5,000 ≥ 5,000)

Example 2: Teacher Wants to Chat with AI

Scenario

• User: Teacher
• Current Balance: 25 tokens
• Action: Send chat message
• Required: 50 tokens (minimum)

Result

✗ Blocked - Insufficient tokens
Error: "You have 25 tokens, but you need at least 50 tokens to chat with AI. Please purchase 25 more tokens to continue."

Example 3: Student Wants to Generate Study Material

Scenario

• User: Student
• Current Balance: 300 tokens
• Action: Generate complete study material
• Required: 250 tokens

Result

✓ Allowed - User has enough tokens (300 ≥ 250)

Example 4: User in Debt

Scenario

• User: Student
• Current Balance: -100 tokens (debt)
• Action: Any AI operation

Result

✗ Blocked - Negative balance
Error: "Your token balance is negative (100 tokens). Please purchase more tokens to continue."

Implementation Guide

Applying Middleware to Routes

Add the middleware to any route that requires token checking:

// In routes/student.php or routes/web.php Route::post('/learncast', [LearnCastController::class, 'store']) ->middleware('check.ai.tokens') ->name('learncast.store'); Route::post('/ai-generate', [MaterialController::class, 'generate']) ->middleware('check.ai.tokens') ->name('ai-generate.process');

Middleware Alias Registration

The middleware is registered in app/Http/Kernel.php:

protected $middlewareAliases = [ // ... other middleware 'check.ai.tokens' => \App\Http\Middleware\CheckAITokens::class, ];

Response Formats

JSON/AJAX Requests (403 Response)

{ "success": false, "error": "You have 25 tokens, but you need at least 50 tokens...", "redirect_url": "https://example.com/payment/tokens/packages", "show_subscribe": true, "current_tokens": 25, "required_tokens": 50 }

Standard Web Requests

// Redirects back with error message in session return back()->with('error', $errorMessage);

Frontend Integration

Handle token errors in your JavaScript:

const response = await fetch('/api/generate', { method: 'POST' }); const data = await response.json(); // Check for token errors if (response.status === 403 && data.show_subscribe) { if (typeof window.showTokenModal === 'function') { window.showTokenModal( data.error, data.redirect_url, data.current_tokens, data.required_tokens ); } }

Last Updated: January 2026