cocodot
← Back to guides
Local card declined for overseas AI? cocodot: one card + one key
视频生成 APIUpdated 2026-10

Video Generation API Errors: Rejected Submissions, Failed Tasks and Moderation, Explained (2026)

A video generation API fails in two places: at submission, or later when the task ends as FAILED. This guide maps each error cocodot's video API returns to its cause and fix, with a polling script that retries only what is worth retrying.

TL;DR: Video generation errors on cocodot come from two places. Either the submission is rejected immediately with an HTTP error (400, 401, 403, 429 or 503) and no task is created, or the submission succeeds and the task later ends with status FAILED and a reason in its error field. The two need different handling. A 400 at submission is usually about the request: a field the model does not accept, a duration or resolution outside the open range, a Hailuo 2.3 Fast first frame sent in content instead of first_frame_image, or Seedance text flags such as --rs in the prompt. Fix the request; resending it unchanged only fails again. A moderation failure means changing the prompt or the input media. Only 429 (too many requests) and 503 (service temporarily unavailable) call for waiting and retrying. A FAILED task with the generic generation-failed message can be retried once or twice later. cocodot pre-deducts a conservative estimate at submission and settles to actual usage once the video is ready; failed jobs are not charged and the hold is refunded in full. A resubmission that succeeds, however, is a new task billed normally, so the retry logic matters.

1. First question: rejected at submission, or failed as a task?

cocodot's video API is asynchronous. You POST to https://cocodot.co/api/ai/video/generations and receive a task ID, then poll GET https://cocodot.co/api/ai/video/generations/{id}. The status is PENDING while the video is being generated, SUCCEEDED with a videoUrl when it is done, or FAILED with an error field. That gives errors two exits. A rejected submission comes back at once as an HTTP status with a message; parameter problems are caught before any task is created. A failed task is one that was accepted and given an ID, then ended as FAILED, with the reason in error. Working out which exit you are looking at is the whole first step of debugging: a 400 at submission is fixed by changing the request, while a FAILED task needs you to read the error text before deciding whether to change the content or simply try again later. Log the task ID, the full request body, the HTTP status and the raw message together. If you need to contact support, the task ID is the first thing to give them. One practical note for teams outside China: the messages are returned in Chinese, so branch your code on the HTTP status and on the field names the messages mention, and show the raw text to a human when in doubt.

2. 400 unsupported fields: each model family has its own schema

The three video model families use different request formats, and cocodot accepts a fixed set of fields per family. Anything extra returns a 400 whose message lists the fields the model does accept. Under the current API, the Seedance models accept model, content, resolution and duration; Kling accepts model, content, prompt, mode, duration and sound; Hailuo accepts model, content, prompt, resolution and duration, and Hailuo 2.3 Fast additionally accepts first_frame_image. The classic mistake is taking a working request for one family, changing only the model, and sending it to another: resolution sent to Kling, or prompt sent to Seedance. The fix is mechanical: remove whatever the message does not list. A wrong model name returns a separate unsupported-video-model error; the valid IDs are the id values returned by GET https://cocodot.co/api/ai/video/models.

Minimal request shape per family (IDs and allowed values: /api/ai/video/models)
// Seedance
{"model": "seedance-2.5", "content": [{"type": "text", "text": "A harbour at dawn, slow push-in"}], "resolution": "720p", "duration": 5}

// Kling
{"model": "kling-v3", "prompt": "Rainy street at night, neon reflections", "mode": "std", "duration": 5, "sound": "off"}

// Hailuo 2.3 Fast (image to video)
{"model": "hailuo-2.3-fast", "prompt": "Slow push-in", "first_frame_image": "https://…/frame.png", "resolution": "768P", "duration": 6}

3. Duration, resolution and mode: only listed combinations are open

cocodot only opens parameter combinations whose pricing has been checked tier by tier. Anything outside that set is rejected at submission, with no task created and nothing charged. The messages fall into a few patterns. One says a model currently only opens certain resolutions, so the one you sent is outside the range. Another says it only opens certain durations in seconds. A third, for Kling, says only the std or pro mode is supported. The last says the combination is not open: each value is individually valid, but together they are not in the open price table. Two more relate to the duration format. Duration must be a positive whole number of seconds; the number 5 and the string "5" both work, while 5.5 or "5s" do not. Kling is billed per second, so leaving duration out returns an error asking you to specify it. The low-effort fix is to call GET https://cocodot.co/api/ai/video/models before you change parameters, read each model's allowed values (resolutions, durations, modes) and validate in your own code, so invalid requests never leave your machine.

4. Hailuo 2.3 Fast first frames, and images in content

On cocodot, Kling and Hailuo only accept text in content. Putting an image or a video there returns a 400 that also tells you where the Hailuo 2.3 Fast first frame belongs: the first_frame_image field. Hailuo 2.3 Fast is image-to-video, so that field is required for it. It takes either a publicly reachable http(s) image URL or a base64 string starting with data:image/, and the value must be 10MB or smaller. A URL containing spaces, a non-http(s) scheme, or base64 without the data:image/ prefix is rejected with the generic message that the submission failed and that you should check resolution, duration and image or video references. Debug it in this order: open the image URL in a private browser window to confirm it loads without a login; check that your code has not appended whitespace or a newline to it; for base64, check the prefix and the size. Integration details for both Hailuo models are in /hub/hailuo-2-3-api.

5. Seedance: --rs and --dur in the prompt are rejected

Some Seedance guides suggest appending text commands such as --rs 1080p --dur 12 to the prompt to set resolution and duration. On cocodot, a Seedance prompt containing these flags is rejected with a 400 telling you to set resolution and duration through the resolution and duration fields, and that other parameters are not open. The specification has to be in fields so the estimated charge can be calculated from them before submission. The fix: move resolution into the resolution field and duration into the duration field, and keep only the scene description in the prompt. The block is not limited to --rs and --dur; flags such as --ratio, --fps, --seed and --watermark are rejected too. If your prompts were exported in bulk from another tool, strip any segment that starts with two hyphens and a letter before submitting. Available specs and billing for the Seedance versions are covered in /hub/seedance-2-5-api.

6. Moderation failures: change the content, do not resend it

The safety-review message can show up in two places: as a 400 at submission, or as the error on a task that was accepted and then ended as FAILED during generation. Neither is charged, and both mean the prompt or the input media (first frame, reference video) did not pass review this time. Sending the same content again does not change what is being reviewed, and it ties up one of your concurrent task slots while it runs. Work through it this way: look for descriptions involving real people, violence or sensitive settings in the prompt and rephrase them more neutrally; then check the first frame and any reference media themselves; if the prompt looks clean but the task was stopped mid-generation, adjust the camera and action description and try again. The review criteria themselves are outside the scope of this guide, and we make no promise about which content will pass.

7. 429, 503, insufficient balance, the concurrency cap, 401 and 403

429 (video requests too frequent, not charged) and 503 (video service temporarily unavailable, not charged) are the errors worth retrying: wait a few seconds, double the wait each time, and set a maximum number of attempts. Insufficient wallet balance comes with the estimated charge for this video in US dollars and means the estimate is more than your available balance; tasks still generating have already had their own estimates held. Video cannot use the $0.5 trial credit, so top up first; top-ups are available via Alipay / WeChat Pay (RMB), USDT / USDC. At most 3 videos generating at the same time means you have hit the per-account limit on tasks in progress; wait for earlier tasks to finish or fail, and queue batch jobs on your side. 401 means the key is missing or invalid (the message reads missing api key or invalid api key); check the Authorization: Bearer cocodot-… header. 403 means an account-level requirement is not met, commonly identity verification (L1); that message includes the link to complete it, in both Chinese and English.

8. A polling and retry pattern that does not waste money

Failed video tasks are not charged, but a resubmission that succeeds is a new task, billed normally. A script that blindly resends a failing request ten times wastes time at best; at worst several attempts succeed while nobody is watching. The pattern below branches on the error. Any 400, 401 or 403 is never retried; the raw message is raised for a person to fix. 429 and 503 back off with a cap. A FAILED task is regenerated at most once, and the error text is printed so a human can tell a moderation failure from a generic one before trying again. Polling every fifteen seconds or so is plenty. Once you see SUCCEEDED, download the video and store it yourself promptly, because the link expires. The useful part here is specific to this API: the retry decision is driven by what the API actually returns for each case, not by a blanket rule on status codes.

Branch on the error: no retry for 400/401/403, back off on 429/503, regenerate a FAILED task at most once
import time, requests

BASE = "https://cocodot.co/api/ai/video/generations"
H = {"Authorization": "Bearer cocodot-..."}

def submit(body, tries=4):
    for i in range(tries):
        r = requests.post(BASE, json=body, headers=H, timeout=90)
        if r.ok:
            return r.json()["id"]
        if r.status_code in (429, 503):
            time.sleep(5 * 2 ** i)
            continue
        raise RuntimeError(f"{r.status_code} {r.text}")  # fix the request; do not retry
    raise RuntimeError("repeated 429/503; try again later")

def run(body, max_regen=1):
    for attempt in range(max_regen + 1):
        tid = submit(body)
        while True:
            time.sleep(15)
            t = requests.get(f"{BASE}/{tid}", headers=H, timeout=30).json()
            if t["status"] == "SUCCEEDED":
                return t["videoUrl"]  # download and store it promptly
            if t["status"] == "FAILED":
                break
        err = t.get("error") or ""
        print("task", tid, "failed:", err)
        if err != "视频生成失败,本次未扣费,请稍后重试。":
            raise RuntimeError(err)  # review unknown or moderation errors
    raise RuntimeError("generation keeps failing: review parameters and content")

Common errors from cocodot's video API (messages are returned in Chinese; the English below is a summary)

Error (summary)Where it appearsCauseWhat to do
Request contains unsupported fields; allowed fields: …Submit, 400A field this model family does not acceptTrim the body to the fields the message lists
Only … is open / this parameter combination is not openSubmit, 400Resolution, duration or mode outside the open rangeRead allowed from GET /api/ai/video/models and adjust
This model does not accept images or video in contentSubmit, 400Kling and Hailuo content is text onlySend the Hailuo 2.3 Fast first frame in first_frame_image
Prompt text flags are not supportedSubmit, 400Seedance prompt contains --rs, --dur and similarRemove them; use the resolution and duration fields
Video task submission failed, not chargedSubmit, 400A parameter or image/video reference was not acceptedCheck resolution, duration and the image URL or base64
Content did not pass the safety review, not chargedSubmit 400, or task FAILEDPrompt or input media did not pass reviewChange the content; do not resend it unchanged
Too many requests / service temporarily unavailableSubmit, 429 / 503Requests too dense, or the service is temporarily unavailableBack off and retry with a cap
Video generation failed, not charged, try again laterTask FAILEDGeneration failed; no finer reason givenRetry once or twice later; if it keeps failing, review parameters and content

FAQ

Video generation failed, please try again later: what should I do?

That is the generic message on a FAILED task, with no finer reason. Retry once or twice later; if it keeps failing, review the parameters (resolution, duration, first frame) and the prompt. A retry that succeeds is a new task and is billed normally.

Am I charged when a video fails content moderation?

No. The message itself says the request was not charged. Resending the same content will not change the review, so adjust the prompt or input media first.

How do I send the first frame for Hailuo 2.3 Fast?

Use the first_frame_image field with a public http(s) image URL or a base64 string starting with data:image/, up to 10MB. Do not put it in content.

Can I put --rs 1080p --dur 10 in a Seedance prompt?

No. cocodot rejects text flags in the prompt. Set resolution and duration through the resolution and duration fields.

Why do I get an error saying at most 3 videos can be generating?

Your account already has the maximum number of tasks in progress. Wait for one to finish or fail, and queue batch jobs in your own code.

Can I test the video API with the free trial credit?

No. Video cannot use the $0.5 trial credit, so a top-up is needed first, and identity verification (L1) must be completed before calling the API.

About cocodot

cocodot is a payment and AI access service for developers and cross-border teams in mainland China. It provides US-BIN virtual cards issued by a licensed institution — used to pay for overseas subscriptions and ad accounts — and an OpenAI-compatible AI API gateway for calling Claude, GPT and Gemini from within mainland China. Both share one wallet, funded by Alipay / WeChat Pay (RMB), USDT / USDC and accounted in USD. Card: $9.9 to open, 3% to load, $1 per active card per month; spending: $0.60 settlement fee on purchases under $20; a corresponding fee applies when the issuer charges one.

Service scope, pricing and limits →