Rueda Lens

Get Started

Rate Limiting

Understand rate limits, quota management, and overage billing in Rueda Lens.

Rueda Lens implements fair usage policies through subscription-based quotas and overage billing.

Subscription Plans

Plans include different quota levels and features. For current pricing and plan details, visit the billing dashboard.

Plan Features

  • Sandbox: Limited quota for testing and development (no overage support)
  • Starter: Production-ready plan with moderate quota and overage support
  • Pro: High-volume plan with generous quota and competitive overage rates
  • Enterprise: Custom quotas and pricing for large-scale deployments

Upgrade anytime

Upgrade or downgrade your plan anytime in the billing dashboard. Changes take effect immediately.

How Quotas Work

Billing Period Reset

Quotas reset based on your subscription billing period (typically monthly from your subscription start date).

For example, if you subscribed on the 15th, your quota resets on the 15th of each month.

What Counts Toward Your Quota

RequestCounts?
POST /v1/analyze (successful)Yes
POST /v1/analyze (failed)Yes
GET /v1/healthNo

Failed requests count

Both successful and failed analysis requests count toward your quota, as they consume processing resources.

Overage Billing

Plans with overage support (Starter, Pro, Enterprise) allow exceeding your base quota:

  1. You exceed your subscription quota during the billing period
  2. Additional requests are charged at the plan's overage rate
  3. Overage charges appear on your next invoice

Sandbox Plan

Sandbox has no overage support. API requests return a 429 error after your quota is exhausted.

Rate Limit Responses

Quota Exhaustion (Sandbox)

When you exceed your monthly quota (Sandbox plan only, as paid plans have overage support):

{
  "success": false,
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Monthly quota exceeded"
  },
  "timestamp": "2026-02-08T12:00:00.000Z"
}

Burst Rate Limit

When you send too many requests in a short period:

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded"
  },
  "timestamp": "2026-02-08T12:00:00.000Z"
}

Monitoring usage

Track your usage in real-time through the dashboard. The dashboard shows your current period usage, remaining quota, and billing period dates.

Email Notifications

You'll receive automatic email alerts when approaching or exceeding your quota:

ThresholdNotification
80%Warning — approaching your quota limit
90%Urgent warning — nearing quota exhaustion
100%Quota exhausted (Sandbox plan only)

Best Practices

Monitor Usage in Dashboard

Track your usage in real-time through the dashboard analytics page:

  • Current billing period usage
  • Remaining quota
  • Usage trends over time
  • Billing period dates

Implement Error Handling

async function analyzeVehicle(tireImage, carImage, apiKey) {
  try {
    const response = await fetch('https://api.ruedalens.com/v1/analyze', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ tireImage, carImage }),
    });

    const data = await response.json();

    if (response.status === 429) {
      // Quota exceeded - notify user or queue for later
      console.error('Quota exceeded:', data.error.message);
      return null;
    }

    if (!response.ok) {
      throw new Error(data.error?.message || 'Analysis failed');
    }

    return data;
  } catch (error) {
    console.error('API request failed:', error);
    throw error;
  }
}

Cache Results

Avoid redundant requests by caching analysis results. For example, store results keyed by image hash:

import crypto from 'crypto';

function hashImage(imageBuffer) {
  return crypto.createHash('sha256').update(imageBuffer).digest('hex');
}

// Use a cache (Redis, in-memory, etc.) to avoid duplicate analyses
const cache = new Map();

async function cachedAnalyze(tireImage, carImage, apiKey) {
  const cacheKey = `${hashImage(tireImage)}_${hashImage(carImage)}`;

  if (cache.has(cacheKey)) {
    return cache.get(cacheKey);
  }

  const result = await analyzeVehicle(tireImage, carImage, apiKey);
  cache.set(cacheKey, result);

  return result;
}