Error codes
The VideoGenAPI REST API uses standard HTTP status codes. Every error response is JSON with an error field, and some include a message and a details object:
{
"error": "Rate limit exceeded",
"message": "High demand right now. Please try again in a few minutes.",
"details": {
"seconds_until_reset": 412,
"reset_time": "2026-10-06 14:32:10"
}
}
Status codes at a glance
| HTTP | Meaning | Retry? |
|---|---|---|
| 400 | Invalid parameters or missing prompt | No, fix the request |
| 401 | Missing or invalid API key | No, fix the key |
| 403 | Model not included in your plan | No |
| 404 | Unknown generation id | No |
| 429 | Rate limit or fair-use ceiling reached | Yes, after seconds_until_reset |
| 500 | Provider or platform error | Yes, with backoff |
Error messages and fixes
| HTTP | error | Cause | Fix |
|---|---|---|---|
| 400 | Invalid JSON input | The request body is not valid JSON. | Send a JSON object with Content-Type: application/json. |
| 400 | Invalid or inactive model specified | The "model" value is not in the catalogue or is disabled. | Use a model key from the model catalog, e.g. kling-3. |
| 400 | Duration must be between X and Y seconds for this model | The requested duration is outside the model range. | Check the duration range on the model page. |
| 400 | This model does not support image-to-video generation | An image_url was sent to a text-to-video-only model. | Remove image_url or pick a model that supports image-to-video. |
| 400 | Invalid image URL. Please provide a valid URL pointing to an image file | image_url is not a reachable jpg, png, gif or webp. | Use a public HTTPS URL to the image file itself. |
| 400 | Aspect ratio must be one of: 1:1, 4:3, 3:4, 16:9, 9:16, 21:9, adaptive | Unsupported aspect_ratio value. | Use one of the listed ratios. |
| 401 | Missing or invalid Authorization header | No Bearer token was sent. | Add Authorization: Bearer YOUR_API_KEY. |
| 401 | Invalid API key | The key is wrong, revoked or was rotated. | Copy the current key from the dashboard. See authentication. |
| 403 | Access denied to this model. Please upgrade your plan. | Your plan does not include this model. | Upgrade your plan or choose an included model. |
| 404 | Generation not found | Unknown generation_id, or it belongs to another key. | Use the generation_id returned by POST /generate with the same key. |
| 405 | Method not allowed | Wrong HTTP method for the endpoint. | POST for /generate, GET for /status/{id}. |
| 429 | Rate limit exceeded / Temporarily unavailable | Too many generations in a short window, or the daily fair-use ceiling. | Wait for details.seconds_until_reset before retrying. See rate limits. |
| 500 | Failed to submit request to video generation service | The model provider rejected or timed out the job. | Retry with exponential backoff. |
Retrying 429 and 500 responses
Do not retry immediately: back-to-back retries keep hitting the same limit. Wait for details.seconds_until_reset on a 429, and use exponential backoff on a 500:
import time, requests
def generate_with_retry(payload, api_key, attempts=5):
for attempt in range(attempts):
r = requests.post("https://videogenapi.com/api/v1/generate",
headers={"Authorization": f"Bearer {api_key}"},
json=payload, timeout=60)
if r.status_code == 429:
wait = r.json().get("details", {}).get("seconds_until_reset", 60)
time.sleep(min(wait, 900))
continue
if r.status_code >= 500:
time.sleep(2 ** attempt * 5)
continue
r.raise_for_status()
return r.json()["generation_id"]
raise RuntimeError("Generation could not be submitted")
Failed jobs
A request can be accepted (HTTP 200) and the job can still fail later, for example when a prompt is rejected by the model's content policy. Those failures appear as "status": "failed" when you poll GET /api/v1/status/{id}, not as an HTTP error. See the content guidelines for what models refuse.