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
| Plan | Requests/Min | Requests/Hour | Requests/Day | Concurrent Jobs |
|---|---|---|---|---|
| Free | 10 | 100 | 500 | 2 |
| Starter | 30 | 500 | 5,000 | 5 |
| Creator | 60 | 1,500 | 20,000 | 10 |
| Enterprise | Custom | Custom | Custom | Custom |
Enterprise Plans
Rate Limit Headers
Every API response includes headers to help you track your rate limit status:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per minute |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Retry-After | Seconds to wait before retrying (only on 429) |
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: 1706234400Handling Rate Limits
When you exceed your rate limit, you'll receive a 429 Too Many Requests response:
{
"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"{
"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
429 error. Wait for existing jobs to complete before starting new ones.