Guides
Errors
Failed requests return an HTTP status in the 4xx or 5xx range and the same JSON shape: success is false and error explains why in one sentence you can show to a user.
Format
400 Bad Request
{
"success": false,
"error": "Field \"prompt\" is required"
}Some errors add context: rate_limit on 429, current_plan on 403, alternatives on 410.
Status codes
| Status | Meaning | What to do |
|---|---|---|
| 200 | Success. | Read video_url. |
| 400 | A field is missing or invalid. | Fix the request; retrying the same body will fail again. |
| 401 | No key, a malformed header or an unknown key. | Check the Authorization: Bearer header. |
| 403 | Not on the API plan, or the video belongs to someone else. | Upgrade the plan or check the video_id. |
| 404 | No video with this video_id. | Check the id. |
| 405 | Wrong method. | POST for generations, GET for status. |
| 410 | sora2 was retired. | Use an id from alternatives. |
| 429 | Rate limit reached. | Wait Retry-After seconds. |
| 500 | The generation could not be completed. | Read error: see the messages below. |
Messages you can receive
| error | Status | Meaning |
|---|---|---|
Missing or invalid Authorization header. Use: Bearer YOUR_API_KEY | 401 | Header missing or without Bearer. |
Invalid API key | 401 | Regenerated or unknown key. |
API access requires the API plan. Please upgrade your subscription. | 403 | The account is on another plan. |
Field "prompt" is required | 400 | Text to video without a prompt. |
Prompt cannot exceed 7000 characters | 400 | Shorten the prompt. |
Field "image_url" is required · Invalid image_url format | 400 | Image to video without a valid URL. |
video_id parameter is required | 400 | Status call without an id. |
Rate limit exceeded. … | 429 | 15 generations in the last 30 minutes. |
You have reached the generation limit of your plan for this month. … | 500 | No credits left until the monthly reset or an upgrade. |
This prompt or image was blocked by the content filter. … | 500 | Rephrase the prompt or use another image. |
High demand right now. Please try again in a few minutes. | 500 | Temporary capacity limit. Retry later. |
Something went wrong on our side and this generation could not be completed. … | 500 | Model or network failure. Retry once, then contact us with the time of the request. |
Handling errors
Branch on the status, show error to the user, and retry only what can succeed later: 429 and the temporary 500s.
import os, requests
def generate(prompt: str) -> str:
resp = requests.post(
"https://lannevideo.com/api/v1/text-to-video",
headers={"Authorization": f"Bearer {os.environ['NB_API_KEY']}"},
json={"prompt": prompt},
timeout=300,
)
data = resp.json()
if resp.ok:
return data["video_url"]
if resp.status_code in (401, 403):
raise PermissionError(data["error"]) # fix the key or the plan
if resp.status_code == 429:
raise RuntimeError(f"Retry in {resp.headers.get('Retry-After')} s")
raise RuntimeError(data["error"]) # 400: fix the request, 500: show and maybe retryasync function generate(prompt) {
const res = await fetch("https://lannevideo.com/api/v1/text-to-video", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.NB_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ prompt }),
signal: AbortSignal.timeout(300_000),
});
const data = await res.json();
if (res.ok) return data.video_url;
if (res.status === 429) {
throw new Error(`Retry in ${res.headers.get("Retry-After")} s`);
}
// 401/403: key or plan, 400: request, 500: show data.error and maybe retry
throw new Error(`${res.status} ${data.error}`);
}