Rate Limits

Understand how rate limiting works and how to handle rate limit errors.

Overview

Vydra uses a sliding window rate limiting algorithm to ensure fair usage across all users. Rate limits are applied at the organization level and vary by subscription plan.

Limits by Plan

PlanRequests/MinRequests/HourRequests/DayConcurrent Jobs
Free101005002
Starter305005,0005
Creator601,50020,00010
EnterpriseCustomCustomCustomCustom

Enterprise Plans

Need higher limits? Contact us for custom enterprise plans with dedicated resources and priority support.

Rate Limit Headers

Every API response includes headers to help you track your rate limit status:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the window resets
Retry-AfterSeconds to wait before retrying (only on 429)
Example Response Headersbash
HTTP/1.1 200 OK
X"text-blue-600">-RateLimit"text-blue-600">-Limit: 30
X"text-blue-600">-RateLimit"text-blue-600">-Remaining: 25
X"text-blue-600">-RateLimit"text-blue-600">-Reset: 1706234400

Handling Rate Limits

When you exceed your rate limit, you'll receive a 429 Too Many Requests response:

Rate Limit Error Responsejson
{
  "error": "Rate limit exceeded",
  "code": "RATE_LIMIT_EXCEEDED",
  "retryAfter": 30,
  "limits": {
    "type": "minute",
    "limit": 30,
    "used": 31
  }
}

Best Practices

Implement Exponential Backoff

When you receive a 429 error, wait for the time specified in Retry-After, then retry with exponential backoff for subsequent failures.

"text-purple-600">async "text-purple-600">function requestWithRetry(url, options, maxRetries = 3) {
  for ("text-purple-600">let i = 0; i < maxRetries; i++) {
    "text-purple-600">const response = "text-purple-600">await fetch(url, options);
    
    "text-purple-600">if (response.status === 429) {
      "text-purple-600">const retryAfter = response.headers.get("text-green-600">'Retry-After') || 60;
      "text-purple-600">const delay = Math.pow(2, i) * parseInt(retryAfter) * 1000;
      "text-purple-600">await "text-purple-600">new Promise(resolve => setTimeout(resolve, delay));
      continue;
    }
    
    "text-purple-600">return response;
  }
  throw "text-purple-600">new Error("text-green-600">'Max retries exceeded');
}

Monitor Rate Limit Headers

Check X-RateLimit-Remaining before making requests. If you're low on remaining requests, slow down or queue your requests.

Use Webhooks for Long Jobs

Instead of polling for job status, use webhooks to receive notifications when jobs complete. This significantly reduces your API usage.

Check Your Usage

Use the rate limits endpoint to check your current usage:

"text">-purple-600">curl https://vydra.app/api/v1/account/rate"text-blue-600">-limits \
  "text-blue-600">-H "Authorization: Bearer YOUR_API_KEY"
Responsejson
{
  "plan": "starter",
  "limits": {
    "rpm": 30,
    "rph": 500,
    "rpd": 5000,
    "concurrent": 5
  },
  "usage": {
    "minute": { "used": 12, "limit": 30 },
    "hour": { "used": 87, "limit": 500 },
    "day": { "used": 342, "limit": 5000 }
  },
  "timestamp": "2026-01-26T12:00:00.000Z"
}

Concurrent Job Limits

In addition to request rate limits, there's a limit on how many jobs can run simultaneously. This applies to workflow jobs (house timelapse, renovation timelapse, etc.).

Job Queue

If you hit the concurrent job limit, new job requests will be rejected with a429 error. Wait for existing jobs to complete before starting new ones.