Skip to content
OpenSmartRoute
Skillv1.0.0

juicebox-rate-limits

Implement Juicebox rate limiting. Trigger: "juicebox rate limit", "juicebox 429", "juicebox throttle".

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (skills/.curated/juicebox-rate-limits/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill juicebox-rate-limits. Copyright stays with the author (MIT).

Juicebox Rate Limits

Overview

Juicebox's AI-powered data analysis API enforces plan-tiered rate limits across dataset uploads, analysis triggers, and result retrieval. Heavy analytical workloads like running comparative analyses across multiple datasets or batch-processing survey results hit the analysis trigger limit first. The enrichment endpoints for augmenting datasets with external data sources have separate, lower caps, making it essential to prioritize enrichment calls and batch analysis runs during off-peak windows.

Rate Limit Reference

Endpoint Limit Window Scope
Dataset upload 20 req 1 minute Per API key
Analysis trigger 30 req 1 minute Per API key
Result retrieval 120 req 1 minute Per API key
Data enrichment 15 req 1 minute Per API key
Export download 10 req 1 minute Per API key

Rate Limiter Implementation

class JuiceboxRateLimiter {
  private tokens: number;
  private lastRefill: number;
  private readonly max: number;
  private readonly refillRate: number;
  private queue: Array<{ resolve: () => void }> = [];

  constructor(maxPerMinute: number) {
    this.max = maxPerMinute;
    this.tokens = maxPerMinute;
    this.lastRefill = Date.now();
    this.refillRate = maxPerMinute / 60_000;
  }

  async acquire(): Promise<void> {
    this.refill();
    if (this.tokens >= 1) { this.tokens -= 1; return; }
    return new Promise(resolve => this.queue.push({ resolve }));
  }

  private refill() {
    const now = Date.now();
    this.tokens = Math.min(this.max, this.tokens + (now - this.lastRefill) * this.refillRate);
    this.lastRefill = now;
    while (this.tokens >= 1 && this.queue.length) {
      this.tokens -= 1;
      this.queue.shift()!.resolve();
    }
  }
}

const analysisLimiter = new JuiceboxRateLimiter(25);
const enrichLimiter = new JuiceboxRateLimiter(12);

Retry Strategy

async function juiceboxRetry<T>(
  limiter: JuiceboxRateLimiter, fn: () => Promise<Response>, maxRetries = 3
): Promise<T> {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    await limiter.acquire();
    const res = await fn();
    if (res.ok) return res.json();
    if (res.status === 429) {
      const retryAfter = parseInt(res.headers.get("Retry-After") || "15", 10);
      const jitter = Math.random() * 3000;
      await new Promise(r => setTimeout(r, retryAfter * 1000 + jitter));
      continue;
    }
    if (res.status >= 500 && attempt < maxRetries) {
      await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 2000));
      continue;
    }
    throw new Error(`Juicebox API ${res.status}: ${await res.text()}`);
  }
  throw new Error("Max retries exceeded");
}

Batch Processing

async function batchAnalyzeDatasets(datasetIds: string[], query: string, batchSize = 5) {
  const results: any[] = [];
  for (let i = 0; i < datasetIds.length; i += batchSize) {
    const batch = datasetIds.slice(i, i + batchSize);
    const batchResults = await Promise.all(
      batch.map(id => juiceboxRetry(analysisLimiter, () =>
        fetch(`${BASE}/api/v1/datasets/${id}/analyze`, {
          method: "POST", headers,
          body: JSON.stringify({ query }),
        })
      ))
    );
    results.push(...batchResults);
    if (i + batchSize < datasetIds.length) await new Promise(r => setTimeout(r, 8000));
  }
  return results;
}

Error Handling

Issue Cause Fix
429 on analysis trigger Exceeded 30 req/min analysis cap Queue analyses, space 3s apart
429 on enrichment Enrichment limit (15/min) is lowest Batch enrichments separately with wider spacing
Upload timeout Dataset exceeds 50MB Compress CSV, use chunked upload endpoint
Analysis still processing Complex query on large dataset Poll status every 10s, timeout at 10 min
403 on export Plan does not include export feature Verify plan tier supports data export

Prerequisites

  • An approved sandbox workload, synthetic records, current quota limits, source/destination allowlists, suppression controls, and a named operator for pause and rollback.

Instructions

  1. Exercise rate-limit behavior only with synthetic fixtures and bounded request budgets; reject real-record export or unapproved destinations.
  2. Apply idempotency keys, exponential backoff, and aggregate-only telemetry; verify suppression and contacts_exported=0 at each probe.
  3. Stop the canary on unexpected quota, scope, policy, or retention drift, then cancel queued work and revoke temporary access.
  4. Retain only redacted aggregate evidence and delete sandbox artifacts after the approved test window.

Output

Produce a rate-limit receipt with environment, request budget, aggregate response/error counts, suppression and no-export assertions, pause/rollback action, owner approval, and retention/deletion proof. Exclude queries, contacts, and credentials.

Examples

env=ci-synthetic; budget=30rpm; retries=backoff; suppression=pass; contacts_exported=0; queued_jobs=cancelled; cleanup=verified is an acceptable receipt.

Resources

  • Juicebox API Documentation

Next Steps

See juicebox-performance-tuning.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-juicebox-rate-limits/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-juicebox-rate-limits.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-juicebox-rate-limits",
  "kind": "skill",
  "name": "juicebox-rate-limits",
  "description": "Implement Juicebox rate limiting. Trigger: \"juicebox rate limit\", \"juicebox 429\", \"juicebox throttle\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "general"
    ],
    "tags": [
      "skill-md",
      "saas",
      "recruiting",
      "juicebox",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Implement Juicebox rate limiting. Trigger: \"juicebox rate limit\", \"juicebox 429\", \"juicebox throttle\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "skills/.curated/juicebox-rate-limits/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/skills/.curated/juicebox-rate-limits/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/skills/.curated/juicebox-rate-limits/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Write,",
      "Edit"
    ],
    "license": "MIT"
  },
  "instructions": "# Juicebox Rate Limits\n\n## Overview\n\nJuicebox's AI-powered data analysis API enforces plan-tiered rate limits across dataset uploads, analysis triggers, and result retrieval. Heavy analytical workloads like running comparative analyses across multiple datasets or batch-processing survey results hit the analysis trigger limit first. The enrichment endpoints for augmenting datasets with external data sources have separate, lower caps, making it essential to prioritize enrichment calls and batch analysis runs during off-peak windows.\n\n## Rate Limit Reference\n\n| Endpoint | Limit | Window | Scope |",
  "cost": {
    "context_tokens": 1315
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-juicebox-rate-limits/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.