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.
15 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:
| Header | Type | Description |
|---|---|---|
X-RateLimit-Limit |
integer | Maximum requests allowed per window (15). |
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. |
HTTP/1.1 200 OK Content-Type: application/json X-RateLimit-Limit: 15 X-RateLimit-Remaining:8 X-RateLimit-Reset: 1746463200 ← Unix timestamp
429, Too Many Requests
When the limit is exceeded, the API returns a 429 with:
HTTP/1.1 429 Too Many Requests Retry-After: 847 X-RateLimit-Limit: 15 X-RateLimit-Remaining:0 { "success": false, "error": "Rate limit exceeded. You have generated 15 videos in the last 30 minutes.", "rate_limit": { "count": 15, "limit": 15, "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
Commercial walkthrough for 100 SKUs, calculator included: batch video generation.
/** * Process a list of prompts respecting rate limits. * Waits 2 min between batches of 12 to stay under 15/30min. */ async function batchGenerate(prompts, batchSize = 12, 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);