API Developer masih dalam tahap beta dan dapat berubah kapan saja. Saat ini, API ini lebih cocok untuk pengujian dan eksperimen pribadi dan belum direkomendasikan untuk penggunaan produksi.
Panggil 59 kemampuan yang diaktifkan untuk deployment ini melalui REST, atau gunakan langsung melalui alat AI yang kompatibel dengan MCP. Langganan aktif diperlukan.
Codex MCP, REST, Claude Code, Cursor, dan klien MCP manual memakai kunci API khusus. Codex menyimpan header Authorization statis di konfigurasi pengguna; jangan pernah mengirim kunci lewat chat atau riwayat shell.
Setiap permintaan diautentikasi dengan kunci API yang ditautkan ke langganan Anda.
Authorization: Bearer YOUR_API_KEYLangganan kedaluwarsa menghasilkan 403 dan Key lama berfungsi kembali setelah diperpanjang. Hanya ACCOUNT_SESSION_REFRESH_REQUIRED yang diperbaiki dengan masuk sekali ke VidMage; ikuti tindakan pemulihan khusus untuk 401 lainnya.
Gunakan URL berumur pendek dan terikat ukuran untuk mengunggah gambar, video, atau audio lokal langsung ke penyimpanan. Byte file tidak melewati server aplikasi 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.Panggil list_capabilities terlebih dahulu. Untuk membuat media, gunakan idempotencyKey baru yang stabil, panggil submit_task tepat satu kali, lalu polling taskId yang sama. Jika respons hilang, panggil get_recent_tasks terlebih dahulu; gunakan kembali kunci awal hanya untuk percobaan ulang transport pada pengiriman yang sama.
list_models → estimate_model_creditsSetiap permintaan diautentikasi dengan kunci API yang ditautkan ke langganan Anda.
list_capabilities (teks ke gambar)
→ describe_capability
→ submit_task + idempotencyKey baru yang stabil (tepat satu kali)
→ get_task_result (polling tugas yang sama)
→ get_recent_tasks (hanya jika respons hilang)
→ hasil gambar nativeSemua tugas AI bersifat asinkron. Setiap kemampuan menyediakan dua endpoint:
| Endpoint | Deskripsi |
|---|---|
| GET /api/v1/capabilities | Setiap permintaan diautentikasi dengan kunci API yang ditautkan ke langganan Anda. |
| GET /api/v1/openapi.json | Setiap permintaan diautentikasi dengan kunci API yang ditautkan ke langganan Anda. |
| POST /api/v1/files/upload | Membuat URL unggah langsung sementara yang dibatasi untuk file media lokal. |
| GET /api/v1/tasks/recent | Memulihkan ID tugas terbaru setelah waktu habis, koneksi terputus, atau respons hilang. |
| POST /api/v1/<capability>/submit | Memulai tugas dan langsung mengembalikan ID tugas. |
| POST /api/v1/<capability>/query | Memeriksa tugas berdasarkan ID dan mengembalikan status serta URL hasil setelah selesai. |
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://..." } }Katalog kemampuan dan dokumen OpenAPI 3.1 dibuat dari kontrak yang sama dengan yang digunakan untuk memvalidasi permintaan. Impor spesifikasi ke Postman, Insomnia, Bruno, atau generator klien 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"Contoh ini mengirim tugas satu kali lalu memeriksa ID tugas yang sama hingga selesai. Pertahankan idempotency key yang sama saat mencoba kembali pengiriman yang sama.
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")Gunakan status HTTP untuk alur kontrol dan errorType untuk menentukan langkah pemulihan. Setiap respons REST menyertakan header X-Request-Id untuk pelacakan dan dukungan.
| Status | errorType umum | Tindakan yang disarankan |
|---|---|---|
| 400 | INVALID_JSON / VALIDATION_ERROR | Perbaiki kolom yang tercantum di details; jangan coba lagi dengan input yang sama tanpa perubahan. |
| 401 | AUTHENTICATION_REQUIRED | VidMage tidak menerima kredensial. Tambahkan Authorization ke konfigurasi pengguna Codex atau klien tujuan; jangan meminta atau menempelkan Key di chat. |
| 401 | AUTHORIZATION_HEADER_INVALID | Perbaiki Authorization Header menjadi tepat Bearer <API_KEY>; tidak ada tugas yang dikirim. |
| 401 | API_KEY_INVALID_OR_REVOKED | Buat kunci API baru dan ganti hanya Authorization dalam konfigurasi yang ada; mulai ulang Codex dan verifikasi di tugas baru. |
| 401 | API_KEY_INVALID_CREDENTIAL | Buat kunci API baru dan ganti kredensial pada klien tujuan; kredensial yang ada tidak dapat didekripsi. |
| 401 | ACCOUNT_SESSION_REFRESH_REQUIRED | Masuk ke VidMage satu kali. Layanan memperbarui kredensial akun backend yang dibungkus oleh kunci API yang ada; konfigurasi klien tidak berubah. |
| 401 REST | NEED_API_KEY | Hanya untuk kompatibilitas REST: berikan kunci API. |
| 402 | NEED_PURCHASE_CREDITS | Tambahkan kredit atau pilih operasi yang lebih hemat. |
| 403 | NEED_SUBSCRIBE | Aktifkan atau perpanjang langganan akun. |
| 404 | CAPABILITY_NOT_ENABLED | Perbarui discovery kemampuan. Kemampuan dinonaktifkan atau tidak tersedia di deployment ini. |
| 409 | UPLOAD_NOT_READY / IDEMPOTENCY_CONFLICT / IDEMPOTENCY_IN_PROGRESS | Jika pengiriman masih diproses, tunggu selama waktu yang ditunjukkan dan gunakan kembali idempotencyKey yang sama. Buat kunci baru hanya untuk permintaan pembuatan yang berbeda. |
| 410 | UPLOAD_EXPIRED | Buat unggahan sementara baru; URL file sebelumnya sudah kedaluwarsa. |
| 429 | RATE_LIMITED | Tunggu selama Retry-After, lalu coba lagi dengan exponential backoff yang dibatasi. |
| 503 | CREDENTIAL_STORAGE_UNAVAILABLE | Patuhi Retry-After dan coba ulang hanya sekali. Jika berlanjut, berhenti, laporkan requestId, dan minta operator memulihkan Developers MySQL readiness. Pertahankan kunci API dan jangan kirim ulang. |
| 503 / MCP | SUBMISSION_OUTCOME_UNKNOWN / BILLING_OUTCOME_UNKNOWN / REFUND_OUTCOME_UNKNOWN | Ikuti recovery terlebih dahulu: GET_RECENT_TASKS berarti memanggil get_recent_tasks; QUERY_TASK_ID_OR_CONTACT_SUPPORT berarti menanyakan taskId yang sama atau menghubungi dukungan; CONTACT_SUPPORT_WITH_IDEMPOTENCY_KEY_AND_BUSINESS_ID berarti menghubungi dukungan dengan idempotencyKey dan businessId. Jangan pernah membuat idempotencyKey baru, mengirim ulang, atau mencoba pengembalian dana lagi. |
| 503 / MCP | TASK_PERSISTENCE_UNCERTAIN | Simpan taskId, jangan kirim ulang tugas, dan hubungi dukungan dengan taskId jika masalah berlanjut. |
| MCP | TASK_QUERY_INTERRUPTED | Lanjutkan polling taskId yang sama; jangan kirim tugas lain. |
| MCP | RESULT_MISSING | Terus polling taskId yang sama; jangan kirim ulang tugas. |
| 404 / MCP | TASK_NOT_FOUND | Panggil get_recent_tasks sebelum mencoba lagi; jangan kirim ulang tugas berbayar. |
| 502 / MCP | BILLING_INVARIANT_FAILED | Jangan coba lagi, ganti kunci API, ubah Idempotency-Key asli, atau kirim ulang. Hubungi dukungan dengan taskId jika tersedia, capability, dan Idempotency-Key asli; untuk REST, sertakan juga X-Request-Id. |
| 5xx | *_SERVICE_UNAVAILABLE / UPSTREAM_* | Untuk kesalahan 5xx lainnya, coba ulang dengan exponential backoff terbatas dan simpan ID tugas. Ini tidak berlaku untuk CREDENTIAL_STORAGE_UNAVAILABLE. |
Parameter di bawah ini membentuk request body untuk submit. Gunakan kolom ID tugas yang sama saat melakukan polling melalui query.