開發者 API 目前仍處於 Beta 階段,介面可能隨時調整,現階段更適合個人測試與體驗,暫不建議用於正式環境。
透過 REST 呼叫目前部署已啟用的 59 項能力,也可直接在支援 MCP 的 AI 工具中使用。存取 API 需要有效訂閱。
Codex MCP、REST、Claude Code、Cursor 與手動 MCP 用戶端統一使用專用 API Key。Codex 將靜態 Authorization Header 儲存在使用者層級設定中;請勿將 Key 傳入聊天或寫入 Shell 歷史。
Codex MCP、REST 與手動用戶端統一使用綁定訂閱的 API Key。
Authorization: Bearer YOUR_API_KEY訂閱失效時請求會回傳 403,續訂後原有 Key 會恢復使用。只有 ACCOUNT_SESSION_REFRESH_REQUIRED 可透過重新登入一次 VidMage 修復;其他 401 請依各自的復原動作處理。
使用短效且綁定檔案大小的 URL,將本機圖片、影片或音訊直接上傳至物件儲存。檔案內容不會經過 VidMage 應用程式伺服器。
curl -X POST "https://vidmage.ai/api/v1/files/upload" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "capability": "video-upscaler", "parameter": "videoURL", "duration": 7.25, "fileName": "input.mp4", "localPath": "./input.mp4", "contentType": "video/mp4", "fileSize": 12345678 }'
# -> { "uploadCommand": "curl ...", "fileUrl": "https://..." }
# Run uploadCommand once, then use fileUrl in the generation request.# ~/.codex/config.toml
# Direct, persistent user-level MCP registration; this is not a plugin install.
# Replace any existing [mcp_servers.vidmage] table; do not append a duplicate.
[mcp_servers.vidmage]
url = "https://vidmage.ai/api/mcp"
http_headers = { Authorization = "Bearer YOUR_API_KEY" }
enabled = true
required = true
startup_timeout_sec = 30
tool_timeout_sec = 120
# Save this file, then confirm persistence with: codex mcp get vidmage
# Restrict the user-level file after saving: chmod 600 ~/.codex/config.toml
# Diagnose this direct server from VidMage startup errors; a remote Plugins catalog 401 is unrelated.
# Fully restart Codex, create a new task, and call list_capabilities.先呼叫 list_capabilities。生成時使用全新且穩定的 idempotencyKey,submit_task 只呼叫一次,之後持續輪詢原 taskId。提交回應遺失時先呼叫 get_recent_tasks;只有同一次傳輸重試才重用原 idempotencyKey。
list_models → estimate_model_creditsMCP 請求需要綁定有效訂閱的 API Key。
list_capabilities(文字生成圖片)
→ describe_capability
→ submit_task + 全新穩定的 idempotencyKey(僅一次)
→ get_task_result(輪詢同一工作)
→ get_recent_tasks(僅在提交回應遺失時)
→ 原生圖片結果所有 AI 工作皆以非同步方式執行。每項能力提供兩個端點:
| 端點 | 說明 |
|---|---|
| GET /api/v1/capabilities | 每個請求都必須使用與訂閱帳戶綁定的 API 金鑰進行驗證。 |
| GET /api/v1/openapi.json | 每個請求都必須使用與訂閱帳戶綁定的 API 金鑰進行驗證。 |
| POST /api/v1/files/upload | 為本機媒體檔案建立受限的臨時直傳 URL。 |
| GET /api/v1/tasks/recent | 在逾時、斷線或回應遺失後復原最近的工作 ID。 |
| POST /api/v1/<capability>/submit | 建立工作並立即回傳工作 ID。 |
| POST /api/v1/<capability>/query | 以工作 ID 查詢狀態;完成後回傳結果 URL。 |
curl -X POST "https://vidmage.ai/api/v1/face-swap/submit" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"targetImageUrl":"https://vidmage.ai/assets/images/samples/blue-eyed-woman-sunlight.webp","referenceFaceImageUrl":"https://vidmage.ai/assets/images/samples/smiling-man-sweater.webp"}'
# -> { "success": true, "taskId": "...", "creditsRequired": ..., "creditsConsumed": 0, "usageDeferred": true }curl -X POST "https://vidmage.ai/api/v1/face-swap/query" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "taskId": "TASK_ID_FROM_SUBMIT" }'
# -> { "success": true, "data": { "status": "...", "imageUrl": "https://..." } }能力目錄和 OpenAPI 3.1 文件與執行階段參數驗證共用相同契約。可將規格匯入 Postman、Insomnia、Bruno 或 API 用戶端產生器。
curl -H "Authorization: Bearer YOUR_API_KEY" "https://vidmage.ai/api/v1/capabilities"curl -H "Authorization: Bearer YOUR_API_KEY" "https://vidmage.ai/api/v1/openapi.json" --output vidmage-openapi.jsoncurl -H "Authorization: Bearer YOUR_API_KEY" "https://vidmage.ai/api/v1/tasks/recent?limit=10"以下範例只提交一次工作,並持續查詢同一工作 ID 直到完成。重試同一次提交時,請維持 idempotency key 不變。
const submitResponse = await fetch('https://vidmage.ai/api/v1/face-swap/submit', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VIDMAGE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"targetImageUrl": "https://vidmage.ai/assets/images/samples/blue-eyed-woman-sunlight.webp",
"referenceFaceImageUrl": "https://vidmage.ai/assets/images/samples/smiling-man-sweater.webp"
}),
})
const submitted = await submitResponse.json()
if (!submitResponse.ok || !submitted.success) {
throw new Error(submitted.message ?? submitted.error ?? 'Task submission failed')
}
const taskId = submitted["taskId"]
if (!taskId) throw new Error('Submit succeeded without a task id')
while (true) {
await new Promise(resolve => setTimeout(resolve, 5000))
const queryResponse = await fetch('https://vidmage.ai/api/v1/face-swap/query', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VIDMAGE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ taskId: taskId }),
})
const queried = await queryResponse.json()
if (!queryResponse.ok || !queried.success) {
throw new Error(queried.message ?? queried.error ?? 'Task query failed')
}
const data = queried.data ?? queried
const status = String(data.status ?? '').toLowerCase()
if (['success', 'succeeded', 'completed'].includes(status)) {
console.log(queried.result ?? queried["imageUrl"] ?? data["imageUrl"])
break
}
if (['failed', 'error'].includes(status)) {
throw new Error(data.errorDetail ?? data.error ?? 'Task failed')
}
}import os
import time
import requests
submit_response = requests.post(
"https://vidmage.ai/api/v1/face-swap/submit",
headers={
"Authorization": f"Bearer {os.environ['VIDMAGE_API_KEY']}",
},
json={
"targetImageUrl": "https://vidmage.ai/assets/images/samples/blue-eyed-woman-sunlight.webp",
"referenceFaceImageUrl": "https://vidmage.ai/assets/images/samples/smiling-man-sweater.webp",
},
timeout=60,
)
submitted = submit_response.json()
if not submit_response.ok or not submitted.get("success"):
raise RuntimeError(submitted.get("message") or submitted.get("error") or "Task submission failed")
task_id = submitted["taskId"]
if not task_id:
raise RuntimeError("Submit succeeded without a task id")
while True:
time.sleep(5)
query_response = requests.post(
"https://vidmage.ai/api/v1/face-swap/query",
headers={"Authorization": f"Bearer {os.environ['VIDMAGE_API_KEY']}"},
json={"taskId": task_id},
timeout=60,
)
queried = query_response.json()
if not query_response.ok or not queried.get("success"):
raise RuntimeError(queried.get("message") or queried.get("error") or "Task query failed")
data = queried.get("data") or queried
status = str(data.get("status") or "").lower()
if status in {"success", "succeeded", "completed"}:
print(queried.get("result") or queried.get("imageUrl") or data.get("imageUrl"))
break
if status in {"failed", "error"}:
raise RuntimeError(data.get("errorDetail") or data.get("error") or "Task failed")使用 HTTP 狀態碼控制程式流程,並依 errorType 執行對應復原操作。每個 REST 回應都包含 X-Request-Id,便於追蹤與支援。
| 狀態碼 | 常見 errorType | 建議處理方式 |
|---|---|---|
| 400 | INVALID_JSON / VALIDATION_ERROR | 依 details 修正欄位;請勿以完全相同的輸入重複請求。 |
| 401 | AUTHENTICATION_REQUIRED | VidMage 未收到憑據。請在 Codex 使用者層級設定或目標用戶端中加入 Authorization;請勿在聊天中索取或貼上 API Key。 |
| 401 | AUTHORIZATION_HEADER_INVALID | 將 Authorization Header 修正為嚴格的 Bearer <API_KEY>;此次沒有提交工作。 |
| 401 | API_KEY_INVALID_OR_REVOKED | 建立新的 API Key,只替換現有設定中的 Authorization;重新啟動 Codex,並在新工作中驗證。 |
| 401 | API_KEY_INVALID_CREDENTIAL | 建立新的 API Key,並替換目標用戶端中的憑證;現有憑證無法解密。 |
| 401 | ACCOUNT_SESSION_REFRESH_REQUIRED | 重新登入一次 VidMage;系統會更新現有 API Key 包裝的後端帳戶憑據,無需修改用戶端設定。 |
| 401 REST | NEED_API_KEY | 僅用於 REST 相容:提供 API Key。 |
| 402 | NEED_PURCHASE_CREDITS | 購買更多點數,或選擇點數消耗較低的操作。 |
| 403 | NEED_SUBSCRIBE | 啟用或續訂帳戶訂閱。 |
| 404 | CAPABILITY_NOT_ENABLED | 重新取得能力目錄。該能力可能已停用,或目前部署未提供。 |
| 409 | UPLOAD_NOT_READY / IDEMPOTENCY_CONFLICT / IDEMPOTENCY_IN_PROGRESS | 若提交仍在處理中,等待提示時間並重用相同 idempotencyKey;只有不同生成請求才建立新 Key。 |
| 410 | UPLOAD_EXPIRED | 請重新建立臨時上傳;先前的檔案 URL 已過期。 |
| 429 | RATE_LIMITED | 等待 Retry-After 指定的時間,再以設有上限的指數退避重試。 |
| 503 | CREDENTIAL_STORAGE_UNAVAILABLE | 遵守 Retry-After,最多重試一次。若仍失敗,請停止、回報 requestId,並請維運人員恢復 Developers MySQL readiness。保留原 Key,不要重新提交。 |
| 503 / MCP | SUBMISSION_OUTCOME_UNKNOWN / BILLING_OUTCOME_UNKNOWN / REFUND_OUTCOME_UNKNOWN | 優先遵循 recovery:GET_RECENT_TASKS 表示呼叫 get_recent_tasks;QUERY_TASK_ID_OR_CONTACT_SUPPORT 表示查詢同一 taskId 或聯絡支援;CONTACT_SUPPORT_WITH_IDEMPOTENCY_KEY_AND_BUSINESS_ID 表示攜帶 idempotencyKey 和 businessId 聯絡支援。絕不要建立新的 idempotencyKey、重新提交或重複退款。 |
| 503 / MCP | TASK_PERSISTENCE_UNCERTAIN | 保留 taskId,不要重新提交;若問題持續,請攜帶 taskId 聯絡支援。 |
| MCP | TASK_QUERY_INTERRUPTED | 繼續輪詢同一 taskId;不要另行提交工作。 |
| MCP | RESULT_MISSING | 繼續輪詢同一 taskId,不要重新提交工作。 |
| 404 / MCP | TASK_NOT_FOUND | 任何重試前先呼叫 get_recent_tasks,不要重新提交付費工作。 |
| 502 / MCP | BILLING_INVARIANT_FAILED | 不要重試、更換 API Key、修改原 Idempotency-Key 或重新提交。請攜帶回應中的 taskId(若有)、capability 和原 Idempotency-Key 聯絡支援;REST 還應提供 X-Request-Id。 |
| 5xx | *_SERVICE_UNAVAILABLE / UPSTREAM_* | 其他 5xx 可使用設有上限的指數退避重試,並保留工作 ID;此規則不適用於 CREDENTIAL_STORAGE_UNAVAILABLE。 |
以下參數組成 submit 的請求本文。輪詢 query 時,請使用相同的工作 ID 欄位。