Rate Limits

Rate Limits

To ensure fair usage and stability for all API consumers, generation requests are rate-limited per user. Limits are applied on a rolling 30-minute window.

30 requests

per 30-minute rolling window, per API key

Applies to

POST /text-to-video

POST /image-to-video

GET /video-status is not rate-limited

Rate Limit Headers

Every generation response includes these headers so you can monitor your quota in real-time:

HeaderTypeDescription
X-RateLimit-Limit integer Maximum requests allowed per window (30).
X-RateLimit-Remaining integer Requests remaining in the current window.
X-RateLimit-Reset unix timestamp Unix timestamp (seconds) when the window resets.
Retry-After integer Only on 429 — seconds to wait before retrying.
Example Response Headers
HTTP/1.1 200 OK
Content-Type:         application/json
X-RateLimit-Limit:    30
X-RateLimit-Remaining:17
X-RateLimit-Reset:    1746463200   ← Unix timestamp

429 — Too Many Requests

When the limit is exceeded, the API returns a 429 with:

429 Response
HTTP/1.1 429 Too Many Requests
Retry-After:          847
X-RateLimit-Limit:    30
X-RateLimit-Remaining:0

{
  "success": false,
  "error":   "Rate limit exceeded. You have generated 30 videos in the last 30 minutes.",
  "rate_limit": {
    "count":            30,
    "limit":            30,
    "remaining":        0,
    "reset_in_seconds": 847,
    "reset_at":         "2026-05-05T18:30:00Z"
  }
}

Best Practices

Monitor X-RateLimit-Remaining

Parse this header after each response. When it drops below 5, slow down your request cadence or queue further calls.

Implement exponential back-off

On a 429, wait for Retry-After seconds before retrying. Increase the delay on subsequent 429s (×2 each time).

Queue requests server-side

Instead of sending bursts, maintain a server-side queue with a rate of ≤1 request every 60 seconds to stay well within limits.

Cache results

Store video URLs from successful generations — you never need to regenerate the same video twice.

Throttled Batch Processing

Batch processing — JavaScript
/**
 * Process a list of prompts respecting rate limits.
 * Waits 2 min between batches of 25 to stay under 30/30min.
 */
async function batchGenerate(prompts, batchSize = 25, delayMs = 120_000) {
  const results = [];

  for (let i = 0; i < prompts.length; i += batchSize) {
    const batch = prompts.slice(i, i + batchSize);

    const batchResults = await Promise.all(
      batch.map(prompt => generateVideo(prompt))
    );
    results.push(...batchResults);

    // Wait between batches to avoid rate limiting
    if (i + batchSize < prompts.length) {
      console.log(`Batch done. Waiting ${delayMs / 1000}s before next batch…`);
      await new Promise(r => setTimeout(r, delayMs));
    }
  }

  return results;
}

// Usage
const prompts = [
  'Sunrise over Tokyo skyline',
  'Tropical beach with turquoise water',
  // ... up to N prompts
];
const videos = await batchGenerate(prompts);