跳到內容

Wan

Wan(通義萬相)是阿里的影片生成系列,由 DashScope 渠道提供。任務透過與其他影片模型相同的端點提交——見建立任務與查詢任務。本頁完整說明 Wan 3.0 適配器:它讀取哪些請求欄位、如何組裝 DashScope 請求、素材規則、如何讀取任務紀錄,以及按秒計費如何計算。

影片生成是非同步任務:提交、保存 task_id、每 10–15 秒查詢一次,狀態變成 SUCCESS 後下載。

模型 ID解析度時長說明
wan3.0-video480P、720P、1080P2–30 秒,或 -1 智慧時長標準版:文字生成影片、首尾幀圖生影片、多模態參考素材
wan3.0-video-prime480P、720P、1080P2–30 秒,或 -1 智慧時長極速版,能力與標準版一致

請求省略時兩者都預設 1080P 與 5 秒。兩者都支援文字生成影片、首幀與首尾幀圖生影片、參考圖/參考影片/參考音訊、影片編輯與影片延長。模型 ID 以 GET /v1/models 回傳的為準;帳戶能用哪些模型、單價多少,以 RouteAPI 控制台為準。

該渠道還提供較舊的 Wan 2.x 模型(wan2.7-i2v、wan2.7-t2v、wan2.5-i2v-preview、wan2.2-*、wanx2.1-*),規則不同,不在本頁範圍。

外層欄位Wan 3.0 適配器的處理
prompt作為 input.prompt 送出。與所有任務請求一樣,prompt 為空會在提交前被拒絕(400)
image / images設定了 image 就用它作首幀,否則取 images 裡第一張非空圖片;尾幀取 images 裡第二張非空圖片。超過兩張的圖片會被忽略
input_reference單圖簡寫:把 images 替換成一個 URL,但首幀仍由頂層 image 優先
resolution作為 parameters.resolution 送出,轉為大寫並在需要時補 P
ratio作為 parameters.ratio 送出,轉為小寫
size折算成 resolution 與 ratio 後丟棄。1920x1080 與 1920*1080 都接受;* 形式不在支援表內時回傳 400,而 720p 這樣的純檔位會被當作解析度使用
duration作為 parameters.duration 送出。缺失時變成 5
seconds在沒有 duration 時解析為整數時長
generate_audio作為 parameters.audio 送出;明確的 false 也會轉發
metadata合併覆蓋到已建立的請求上,因此 metadata.parameters.* 與 metadata.input.* 優先於映射值

兩者同時送出時,明確的 resolution / ratio 優先於由 size 推導的值;size 一律會從上游請求主體中移除。適配器隨後把 input、parameters 與 model 送到 DashScope 的影片合成端點,你不需要自己呼叫該端點。

由於請求主體採用 DashScope 的結構,同樣的取值也可以放在 metadata 裡:

{
"metadata": {
"input": { "negative_prompt": "blurry, low quality" },
"parameters": { "duration": 10, "resolution": "720p", "ratio": "9:16" }
}
}

metadata 不能換模型:metadata.model 與解析出的上游模型不一致時回傳 400。

以下欄位可以寫在請求主體頂層,模型專屬參數放在 metadata 裡。

欄位類型取值說明
modelstringwan3.0-video、wan3.0-video-prime必填
promptstring—必填且不能為空。參考素材模式裡用「圖 1」「影片 1」「音訊 1」指代素材
resolutionstring480P、720P、1080P大小寫均可,結尾的 P 可省略。預設 1080P
ratiostringadaptive、21:9、16:9、4:3、1:1、3:4、9:16大小寫均可。不傳時由 DashScope 按 adaptive 處理
sizestring1280*720、1280x720 或 720p折算成 resolution 與 ratio 後丟棄。只有適配器表內的像素尺寸才接受
durationinteger2–30輸出時長(秒),預設 5。負數或大於 3600 會被通用任務驗證拒絕;-1 智慧時長只能寫在 metadata.parameters 裡
secondsstring整數字串duration 缺失或為 0 時取代它。不是整數會回傳 400
imagestringURL單張首幀圖片;首幀優先取它,其次才看 images
imagesarrayURL 清單1 張為首幀;2 張依次為首幀與尾幀
input_referencestringURL把 images 替換成一個首幀 URL;首幀仍由頂層 image 優先
generate_audiobooleantrue / false作為 parameters.audio 送出;明確的 false 會按 false 轉發
metadataobjectDashScope 的 input / parameters覆蓋已映射的值,見下節

size 若是 寬*高 像素對,必須命中適配器的表:480P 接受 832*480、480*832、624*624;720P 接受 1280*720、720*1280、960*960、1088*832、832*1088;1080P 接受 1920*1080、1080*1920、1440*1440、1632*1248、1248*1632。比例由像素對約分得出,只有命中支援清單才保留,否則交給 DashScope 的預設比例。

metadata 與 DashScope 的 input / parameters 物件一一對應,下列鍵均為選填。

metadata 鍵類型說明
input.mediaarray由 {"type", "url"} 項目組成的素材清單。提供後頂層圖片欄位不再生效
input.promptstring送到上游時取代頂層 prompt,但通用驗證仍要求頂層 prompt 存在
input.audio_urlstring追加一筆 reference_audio 的簡寫
input.negative_promptstring反向提示詞
input.templatestringDashScope 特效模板,原樣轉發
parameters.resolutionstring同頂層 resolution
parameters.ratiostring同頂層 ratio
parameters.sizestring同頂層 size
parameters.durationinteger-1 為智慧時長,否則 2–30
parameters.audioboolean同 generate_audio
parameters.seedinteger-1 或 0–2147483647。0 會作為明確值保留;相同種子不保證結果完全一致
parameters.watermarkboolean供應商端浮水印,預設關閉
parameters.prompt_extendboolean可以傳,但沒有任何作用——提示詞改寫始終開啟,見下文

metadata.parameters.* 中的值優先於頂層對應欄位。metadata 裡不認得的鍵會被忽略,類型寫錯的鍵會在預扣前回傳 400。

prompt_extend 無法關閉。頂層沒有這個欄位,寫在頂層的 prompt_extend 會被直接忽略;寫在 metadata.parameters 裡時,適配器始終以 true 為起點,而該欄位是不帶指標的 bool 且帶 omitempty,所以 false 在送到 DashScope 時會被丟掉,由上游預設值(開啟)生效。寫上它只是重申預設值,不會改變行為。

Wan 3.0 透過 input.media 接收素材,它是一個由 {"type": "...", "url": "..."} 項目組成的陣列。適配器會從頂層圖片欄位建立它,並合併你明確傳入的內容:

type含義上限(DashScope)
first_frame影片首幀1
last_frame影片尾幀,必須同時有首幀1
reference_image用於主體/風格參考的參考圖10
reference_video用於參考生成、影片編輯或影片延長的參考影片5 段,總時長 ≤15 秒
reference_audio參考音訊。input.audio_url 會以該類型附加5 段,總時長 ≤15 秒

在 metadata.input.media 中明確提供的 media 會原樣保留;未提供時,適配器依 first_frame、last_frame 的順序從頂層圖片欄位建立。這條備援路徑還會讀取舊的 metadata.input.img_url / first_frame_url / last_frame_url,而 metadata.input.audio_url 始終會追加一筆 reference_audio。這四個舊欄位都會被折進 media 後清空——Wan 3.0 只認 media。

上表的數量與時長是 DashScope 的規則,RouteAPI 不做前置驗證;違反時由上游拒絕並退款——可能表現為 fail_to_fetch_task 錯誤,也可能表現為 FAILURE 任務紀錄,而不是本地 400。

素材規則:

  • 素材 URL 必須是免登入即可直接下載的公網 http(s) 位址。圖片還可以用 data:image/png;base64,...。
  • 單一素材限制:圖片 JPEG / JPG / PNG(無透明通道)/ BMP / WEBP,寬高 240–8000 像素,寬高比 ≤8:1,≤20MB;影片 mp4 / mov,每段 1–15 秒,≥16fps,寬高 240–4096 像素,≤100MB;音訊 wav / mp3,每段 1–15 秒,≤15MB。
  • 首幀/尾幀模式與參考素材模式互斥。在同一個 media 裡把首尾幀和 reference_* 混寫會被上游拒絕:任務退款。
  • reference_image、reference_video、reference_audio 可以自由組合。
  • 提示詞裡用「圖 1」「影片 1」「音訊 1」指代素材,序號按同類素材在 media 中的出現順序計算。

有兩條規則在本地、提交前就攔下,既不存取上游也不扣費:

  • metadata.input.audio_url 與 first_frame 或 last_frame 同時出現會回傳 400,訊息為 wan3 does not support audio_url together with first/last frame images。該檢查只看 input.audio_url;如果直接把 reference_audio 項目寫進 media 與幀混合,則由 DashScope 拒絕(任務 FAILURE,退款)。
  • metadata 合併後,prompt 為空且 media 為空會回傳 400(wan3 requires prompt or input.media)。實際上通用任務驗證已拒絕空 prompt,因此 prompt 始終必填。

只傳 prompt 與影片參數:

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan3.0-video",
"prompt": "An orange cat walking on a rooftop, cinematic lighting",
"resolution": "480P",
"ratio": "16:9",
"duration": 2
}'

用頂層 images 傳圖片:1 張作為首幀,2 張依次作為首幀與尾幀。

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan3.0-video",
"prompt": "The scene shifts naturally from morning to sunset while the camera moves smoothly",
"images": [
"https://cdn.example.com/first.jpg",
"https://cdn.example.com/last.jpg"
],
"resolution": "720P",
"ratio": "adaptive",
"duration": 5
}'

也可以在 metadata.input.media 裡用明確 type 寫出首尾幀;last_frame 必須和 first_frame 一起使用。

需要參考素材時,在 metadata.input.media 裡逐項寫出。一旦給了 media,頂層圖片欄位就不再生效。

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan3.0-video",
"prompt": "The character in image 1 performs the motion from video 1, dancing to the rhythm of audio 1",
"resolution": "720P",
"ratio": "adaptive",
"duration": 8,
"metadata": {
"input": {
"media": [
{ "type": "reference_image", "url": "https://cdn.example.com/character.jpg" },
{ "type": "reference_video", "url": "https://cdn.example.com/motion.mp4" },
{ "type": "reference_audio", "url": "https://cdn.example.com/music.mp3" }
]
}
}
}'

含 reference_video 項目的請求在提交時按 30 秒預扣,與請求的時長無關,因為此時無法確定最終輸出長度——見計費。

兩者都用 reference_video 傳原影片,用提示詞表達意圖。

  • 影片編輯——例如「將影片 1 整體轉換為黏土動畫風格」。建議 ratio 傳 adaptive,輸出保持原影片比例。
  • 影片延長——例如「將影片 1 向後延長,保持人物動作和鏡頭風格一致」。ratio 必須是 adaptive。duration 填「原影片時長 + 延長時間」:5 秒影片延長 2 秒填 7。也可以填 -1 由模型決定。

有影片輸入時,「輸入影片時長 + 輸出時長」不能超過 30 秒。該限制由 DashScope 執行;超出會失敗並退款。

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan3.0-video",
"prompt": "Convert video 1 entirely into a claymation style",
"resolution": "480P",
"ratio": "adaptive",
"duration": 2,
"metadata": {
"input": {
"media": [ { "type": "reference_video", "url": "https://cdn.example.com/input.mp4" } ]
}
}
}'

把同一段 5 秒影片延長 2 秒,只需改提示詞與時長:

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan3.0-video",
"prompt": "Extend video 1 forward by two seconds, keeping the character motion and camera style consistent",
"resolution": "480P",
"ratio": "adaptive",
"duration": 7,
"metadata": {
"input": {
"media": [ { "type": "reference_video", "url": "https://cdn.example.com/input.mp4" } ]
}
}
}'

智慧時長由模型決定輸出長度。在 metadata.parameters.duration 裡傳 -1;頂層 duration 傳負數會被通用任務驗證拒絕,回傳 invalid_seconds。

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan3.0-video",
"prompt": "An orange cat walking on a rooftop, cinematic lighting",
"resolution": "480P",
"ratio": "16:9",
"metadata": { "parameters": { "duration": -1 } }
}'

智慧時長任務提交時按 30 秒預扣,完成後按實際輸出時長結算並退還差額。

Terminal window
curl https://api.routeapi.ai/v1/video/generations/task_FQvcRkHE9wjSWwyISDcrWCKoqCPNdkCx \
-H "Authorization: Bearer $ROUTEAPI_KEY"
{
"code": "success",
"message": "",
"data": {
"id": 4512,
"created_at": 1792412645,
"updated_at": 1792412780,
"task_id": "task_FQvcRkHE9wjSWwyISDcrWCKoqCPNdkCx",
"platform": "17",
"user_id": 1024,
"group": "default",
"channel_id": 18,
"quota": 50000,
"action": "textGenerate",
"status": "SUCCESS",
"progress": "100%",
"fail_reason": "",
"result_url": "https://dashscope-result.oss.example/video.mp4",
"submit_time": 1792412645,
"start_time": 1792412650,
"finish_time": 1792412780,
"properties": {
"input": "",
"origin_model_name": "wan3.0-video",
"upstream_model_name": "wan3.0-video"
},
"data": {
"request_id": "42a9c287-db7b-9edb-b613-xxxxxxxx",
"output": {
"task_id": "dd40fcb4-34f4-4292-a9e0-xxxxxxxx",
"task_status": "SUCCEEDED",
"video_url": "https://dashscope-result.oss.example/video.mp4",
"orig_prompt": "An orange cat walking on a rooftop, cinematic lighting"
},
"usage": {
"video_count": 1,
"duration": 2,
"input_video_duration": 0,
"output_video_duration": 2,
"fps": 30,
"SR": 480,
"ratio": "16:9"
}
}
}
}

外層欄位由 RouteAPI 產生。判斷進度以 data.status 為準;data.progress 對 Wan 只是粗略的階段標記(20% 排隊、30% 生成中、100% 完成),不是上游的真實百分比。data.quota 是目前已扣的額度,任務成功後即為結算後的金額。請求帶了頂層圖片欄位(image、images 或 input_reference)時 data.action 為 generate,否則為 textGenerate。

data.data 是 DashScope 回傳的任務原文,原樣儲存。需要關注這些欄位:

欄位說明
data.data.output.task_idDashScope 任務 ID,與外層 data.task_id 不同
data.data.output.video_url上游影片位址,與外層 data.result_url 相同
data.data.output.orig_promptDashScope 收到的提示詞
data.data.usage.output_video_duration實際輸出秒數——計費就是按它算
data.data.usage.input_video_duration輸入影片秒數,不計費。純文字生成影片為 0
data.data.usage.duration輸入 + 輸出秒數,僅供參考,從不用於結算
data.data.usage.SR實際輸出解析度檔位,數字形式(480、720、1080),用於結算
data.data.usage.fps輸出影格率,這兩個模型為 30
data.data.usage.ratio實際畫面比例。adaptive 時為原素材比例,如 427:240

任務結束前 data.data 可能只有部分欄位,是否結束以 data.status 為準,不要看 usage 是否存在。

狀態含義:NOT_START、QUEUED 繼續輪詢,IN_PROGRESS 生成中,SUCCESS 可以下載,FAILURE 看 fail_reason——預扣額度已經退回。

data.result_url 指向阿里託管的檔案。該位址是暫時的,阿里會依其自身策略使其過期,請儘快下載;也可以改用 RouteAPI 串流取得,不受該位址剩餘有效期影響:

Terminal window
curl -L -o out.mp4 \
https://api.routeapi.ai/v1/videos/task_FQvcRkHE9wjSWwyISDcrWCKoqCPNdkCx/content \
-H "Authorization: Bearer $ROUTEAPI_KEY"

content 端點只對呼叫者自己已完成的任務回傳資料:未完成回傳 400 並在訊息裡帶上目前狀態,未知或他人 task_id 回傳 404,拉取上游失敗回傳 502。完整錯誤表見查詢任務。還沒過期的 result_url 也可以直接作為下一次請求的 reference_video 或 reference_image。

DashScope 狀態任務紀錄狀態
PENDINGQUEUED
RUNNINGIN_PROGRESS
SUCCEEDEDSUCCESS
FAILED、CANCELED、UNKNOWNFAILURE

Wan 3.0 按輸出秒數計費,並依解析度縮放。控制台價格是 480P 的每秒單價,其餘檔位按模型的解析度倍率相乘,預設 480P : 720P : 1080P = 1 : 2 : 4。

預扣與結算用同一套公式:

base quota = model price (per 480P second) × group ratio
reserved quota = base quota × reserved seconds × resolution ratio
settled quota = min(base quota × output seconds × effective ratio, reserved quota)

生效倍率 是請求檔位的倍率;若 DashScope 回報的 SR 低於請求檔位,則改用低檔的倍率。它永遠不會高於請求檔位。

預扣與結算:

請求類型提交時預扣任務完成後
指定時長、不含 reference_video請求的秒數實際輸出秒數
含 reference_video 項目30 秒實際輸出秒數,退還差額
metadata.parameters.duration: -1(智慧時長)30 秒實際輸出秒數,退還差額

適配器中可驗證的結算規則:

  • 只對 usage.output_video_duration 計費。輸入影片秒數、參考圖、參考音訊與首尾幀都不收費,是否產生音軌也不影響價格。
  • 單價取提交時的快照。任務執行期間控制台調價不影響已提交的任務,預扣金額保持原樣。
  • 結算只退不補。上游回報秒數超過預扣、SR 更高,或 usage 格式異常時,保持預扣金額而不額外加扣;成功回應缺少 usage 時同樣保持預扣。
  • 任務失敗——審核不通過、上游逾時、取消——退回預扣額度。400 在提交前就被拒絕,不會扣費。
  • 需要按 30 秒預扣的請求,帳戶餘額或 Key 額度必須足以覆蓋該預扣,否則提交時回傳 403 insufficient_user_quota。

提交回應帶有 X-New-Api-Other-Ratios 標頭,列出實際套用的倍率,例如 5 秒 1080P 請求為 {"resolution-1080P":4,"seconds":5}。含參考影片或智慧時長的請求,seconds 為 30。

範例(價格僅作假設,真實價格以控制台為準)。假設該模型 480P 每秒 $0.05,按預設 1 : 2 : 4,720P 為 $0.10、1080P 為 $0.20,分組倍率為 1:

  1. 請求 1080P、duration: 5。預扣 0.20 × 5 = $1.00。
  2. DashScope 回報 usage.SR: 720、output_video_duration: 5,即實際輸出低了一檔。結算 0.10 × 5 = $0.50,退還 $0.50。
  3. 如果回報的是 SR: 1080、5 秒,扣費維持 $1.00——結算永遠不會超過預扣。

第二個範例:480P、輸入 2 秒參考影片、duration: 2。因為有 reference_video,預扣 30 × $0.05 = $1.50;實際輸出 2 秒,結算為 2 × $0.05 = $0.10,退還 $1.40。

參數錯誤在提交前就被攔下:回傳 400,不送到上游,也不扣費。

狀態碼錯誤碼含義
400invalid_requestprompt 缺失或為空(prompt is required);audio_url 與首/尾幀同時出現(wan3 does not support audio_url together with first/last frame images);prompt 與 media 都為空;metadata 欄位類型錯誤;metadata.model 與解析出的模型不一致(can't change model with metadata)
400invalid_request參數驗證失敗——見下面的訊息表
400invalid_json請求主體無法解析
400invalid_seconds頂層 duration / seconds 為負或大於 3600(seconds must be between 1 and 3600)
400missing_model請求主體沒有 model(model field is required)
400task_not_existtask_id 未知或屬於其他帳戶
403insufficient_user_quota餘額或 Key 額度不足以覆蓋預扣;不會提交
429—上游容量耗盡;訊息會被替換為 Upstream load is saturated, please try again later
500build_request_failed、do_request_failed、invalid_response轉換失敗、上游不可達,或 DashScope 沒有回傳任務 ID
上游狀態碼ali_api_errorDashScope 在回應主體中回傳了錯誤碼與訊息
上游狀態碼fail_to_fetch_taskDashScope 拒絕了提交;HTTP 狀態碼即 DashScope 的狀態碼

Wan 3.0 驗證回傳的常見 400 訊息(原文):

message原因
invalid duration: 40, wan3 supports -1 or 2-30時長超出 2–30 且不是 -1
invalid resolution: 4KP, wan3 supports 480P, 720P, 1080P解析度不在支援檔位內(顯示的是轉大寫並補 P 之後的值)
invalid ratio: 1:2, wan3 supports adaptive, 21:9, 16:9, 4:3, 1:1, 3:4, 9:16比例不在支援清單內
invalid seed: 3000000000, wan3 supports -1 or 0-2147483647種子超出 -1 或 0–2147483647
invalid size: 1000*1000寬*高 像素尺寸不在表內
wan3 does not support audio_url together with first/last frame images首尾幀與透過 input.audio_url 傳入的參考音訊混用
wan3 requires prompt or input.mediametadata 合併後既沒有 prompt 也沒有 media
can't change model with metadatametadata.model 與解析出的上游模型不一致
convert seconds to int failed: ...seconds 不是整數字串
seconds must be between 1 and 3600頂層時長過小或過大;-1 請用 metadata.parameters.duration

提交成功之後出現的失敗——審核不通過、素材無法下載、素材組合不合法、輸入 + 輸出超過 30 秒——不會以 HTTP 錯誤回傳,而是體現在任務紀錄的 FAILURE 狀態與 fail_reason 裡,預扣額度會退回。

  • 介面位址不同。RouteAPI 不提供 /api/v1/services/aigc/video-generation/video-synthesis,把 DashScope SDK 的 Base URL 改成我們的位址是不能直接用的。
  • 阿里原生的 input / parameters 物件要放在 metadata.input / metadata.parameters 裡;常用參數(prompt、resolution、ratio、size、duration、images、generate_audio)也可以寫在頂層,我們會自動映射。
  • 回傳的 task_id 是 RouteAPI 的 ID,不是阿里的任務 ID。阿里的任務 ID 在 data.data.output.task_id。
  • 提示詞智慧改寫(prompt_extend)始終開啟,無法關閉。
  • 舊的按模型圖片欄位(img_url、first_frame_url、last_frame_url、audio_url)會被丟棄,只有 input.media 會送到上游。
  • 不支援回呼通知,請用輪詢查詢結果。
  • 計費按輸出秒數乘解析度倍率,不適用上游的按次或分檔計價。

需要 bash、curl 與 jq。

#!/usr/bin/env bash
set -euo pipefail
: "${ROUTEAPI_KEY:?set ROUTEAPI_KEY first}"
BASE="${ROUTEAPI_BASE:-https://api.routeapi.ai}"
AUTH="Authorization: Bearer $ROUTEAPI_KEY"
TASK_ID=$(curl -sS -X POST "$BASE/v1/video/generations" \
-H "$AUTH" -H "Content-Type: application/json" \
-d '{"model":"wan3.0-video","prompt":"An orange cat walking on a rooftop, cinematic lighting","resolution":"480P","ratio":"16:9","duration":2}' \
| jq -er .task_id)
echo "task: $TASK_ID"
for _ in $(seq 1 60); do
RESP=$(curl -sS "$BASE/v1/video/generations/$TASK_ID" -H "$AUTH")
STATUS=$(printf '%s' "$RESP" | jq -r .data.status)
echo "status: $STATUS $(printf '%s' "$RESP" | jq -r .data.progress)"
case "$STATUS" in
SUCCESS)
echo "billed seconds: $(printf '%s' "$RESP" | jq -r .data.data.usage.output_video_duration)"
curl -sSL -o "$TASK_ID.mp4" "$BASE/v1/videos/$TASK_ID/content" -H "$AUTH"
echo "saved $TASK_ID.mp4"
exit 0
;;
FAILURE)
echo "failed: $(printf '%s' "$RESP" | jq -r .data.fail_reason)"
exit 1
;;
esac
sleep 15
done
echo "timed out waiting for the task"
exit 1