Claude-skill-registry juicebox-rate-limits
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/juicebox-rate-limits" ~/.claude/skills/majiayu000-claude-skill-registry-juicebox-rate-limits && rm -rf "$T"
manifest:
skills/data/juicebox-rate-limits/SKILL.mdsource content
Juicebox Rate Limits
Overview
Understand and implement proper rate limiting handling for Juicebox API.
Rate Limit Tiers
| Plan | Requests/Min | Requests/Day | Searches/Month |
|---|---|---|---|
| Free | 10 | 100 | 500 |
| Pro | 60 | 5,000 | 25,000 |
| Enterprise | 300 | 50,000 | Unlimited |
Instructions
Step 1: Understand Rate Limit Headers
// Juicebox returns these headers with every response interface RateLimitHeaders { 'x-ratelimit-limit': string; // Max requests per window 'x-ratelimit-remaining': string; // Remaining requests 'x-ratelimit-reset': string; // Unix timestamp when limit resets 'retry-after'?: string; // Seconds to wait (only on 429) } function parseRateLimitHeaders(headers: Headers) { return { limit: parseInt(headers.get('x-ratelimit-limit') || '0'), remaining: parseInt(headers.get('x-ratelimit-remaining') || '0'), reset: new Date(parseInt(headers.get('x-ratelimit-reset') || '0') * 1000), retryAfter: parseInt(headers.get('retry-after') || '0') }; }
Step 2: Implement Rate Limiter
// lib/rate-limiter.ts export class RateLimiter { private queue: Array<() => Promise<void>> = []; private processing = false; private lastRequestTime = 0; private minInterval: number; constructor(requestsPerMinute: number) { this.minInterval = 60000 / requestsPerMinute; } async execute<T>(fn: () => Promise<T>): Promise<T> { return new Promise((resolve, reject) => { this.queue.push(async () => { try { const result = await fn(); resolve(result); } catch (error) { reject(error); } }); this.processQueue(); }); } private async processQueue() { if (this.processing || this.queue.length === 0) return; this.processing = true; while (this.queue.length > 0) { const now = Date.now(); const elapsed = now - this.lastRequestTime; if (elapsed < this.minInterval) { await sleep(this.minInterval - elapsed); } const task = this.queue.shift(); if (task) { this.lastRequestTime = Date.now(); await task(); } } this.processing = false; } }
Step 3: Add Exponential Backoff
// lib/backoff.ts export async function withExponentialBackoff<T>( fn: () => Promise<T>, options: { maxRetries?: number; baseDelay?: number; maxDelay?: number; } = {} ): Promise<T> { const { maxRetries = 5, baseDelay = 1000, maxDelay = 60000 } = options; let lastError: Error; for (let attempt = 0; attempt < maxRetries; attempt++) { try { return await fn(); } catch (error: any) { lastError = error; if (error.code === 'RATE_LIMITED') { const retryAfter = error.retryAfter || 0; const backoffDelay = Math.min( baseDelay * Math.pow(2, attempt), maxDelay ); const delay = Math.max(retryAfter * 1000, backoffDelay); console.log(`Rate limited. Retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`); await sleep(delay); continue; } throw error; } } throw lastError!; }
Step 4: Implement Quota Tracking
// lib/quota-tracker.ts export class QuotaTracker { private dailyRequests = 0; private dailyResetTime: Date; constructor(private dailyLimit: number) { this.dailyResetTime = this.getNextMidnight(); } async checkQuota(): Promise<boolean> { this.maybeResetDaily(); return this.dailyRequests < this.dailyLimit; } recordRequest() { this.dailyRequests++; } getRemainingQuota(): number { this.maybeResetDaily(); return this.dailyLimit - this.dailyRequests; } private maybeResetDaily() { if (new Date() > this.dailyResetTime) { this.dailyRequests = 0; this.dailyResetTime = this.getNextMidnight(); } } }
Output
- Rate limiter with queue
- Exponential backoff handler
- Quota tracking system
- Header parsing utilities
Error Handling
| Scenario | Strategy |
|---|---|
| 429 with Retry-After | Wait exact duration |
| 429 without Retry-After | Exponential backoff |
| Approaching limit | Proactive throttling |
| Daily quota exhausted | Queue for next day |
Resources
Next Steps
After rate limit handling, see
juicebox-security-basics for security best practices.