Dành cho nhà phát triển

Tài liệu API

Gọi các công cụ AI (video, ảnh, giọng nói, âm nhạc...) từ website, ứng dụng hoặc quy trình tự động của bạn. Credits trừ vào tài khoản giống hệt khi dùng trên web.

Xác thực

Mọi yêu cầu gửi tới địa chỉ gốc dưới đây. Tạo API key ở trang API cho nhà phát triển (cần đăng nhập), rồi gửi kèm trong header X-API-Key hoặc Authorization: Bearer.

https://nov.ai.vn/api
curl https://nov.ai.vn/api/auth/me \
  -H "X-API-Key: cmsnt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  • Key chỉ hiện đầy đủ một lần khi tạo. Mất key thì thu hồi và tạo key mới.
  • Chỉ dùng key ở máy chủ của bạn, không nhúng vào mã chạy trên trình duyệt hay ứng dụng di động.
  • Key chỉ gọi được các API trong tài liệu này; mua gói, rút tiền, đổi thông tin tài khoản vẫn phải đăng nhập trên web.

Quy ước chung

  • Dữ liệu gửi và nhận ở dạng JSON (trừ API tải file dùng multipart/form-data).
  • Lỗi trả mã HTTP 4xx/5xx kèm thông báo đọc được: { "statusCode": 400, "message": "...", "error": "Bad Request" }
  • 401 key sai, hết hạn hoặc đã thu hồi · 403 key không được gọi API này · 404 công cụ/tác vụ không tồn tại · 409 đang chạy quá số luồng của gói · 429 gọi quá nhanh, chờ rồi thử lại.
  • Giới hạn tốc độ: chạy công cụ 20 lần/phút, báo giá và hỏi trạng thái 120 lần/phút, tải file 30 lần/phút.
  • Số luồng chạy đồng thời theo gói cước đang dùng (xem trường concurrency ở API số dư credits).

Danh mục công cụ

GET/public/ai/toolsKhông cần key

Trả danh sách công cụ đang bật. Mỗi công cụ có key (dùng trong các API khác), loại kết quả (output), cách tính giá và danh sách ô nhập (fields).

GET/public/ai/tools/{key}Không cần key

Chi tiết một công cụ, quan trọng nhất là fields: mô tả các tham số cần gửi khi chạy.

{
  "key": "tmc.image-to-video",
  "name": "...",
  "category": "video",
  "output": "video",            // image | video | audio | text
  "pricing": { "mode": "fixed", "base": 100, "perUnit": 0, "unitLabel": null, "min": 0 },
  "fields": [
    { "name": "prompt", "label": "Mô tả", "type": "textarea", "required": true, "max": 2000 },
    { "name": "ratio", "label": "Tỉ lệ", "type": "select", "default": "16:9",
      "options": [{ "value": "16:9", "label": "Ngang" }, { "value": "9:16", "label": "Dọc" }] },
    { "name": "image", "label": "Ảnh mẫu", "type": "image", "accept": "image/*" }
  ]
}

Ý nghĩa các trường của field:

  • type: text, textarea, select, number, boolean hoặc file (image, video, audio, file) — field file nhận URL trả về từ API tải file đầu vào.
  • required, default, min/max (với text là độ dài tối đa), options (giá trị hợp lệ của select).
  • multiple + maxFiles: field file nhận mảng nhiều URL.
  • showIf: field chỉ có hiệu lực khi field khác có giá trị nằm trong danh sách. optionsBy: lựa chọn thay đổi theo giá trị field khác.

Báo giá credits

POST/account/ai/tools/{key}/quote

Tính số credits sẽ trừ với bộ tham số cho trước, không chạy và không trừ credits.

curl -X POST https://nov.ai.vn/api/account/ai/tools/tmc.image-to-video/quote \
  -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{ "input": { "prompt": "Một chú mèo phi hành gia" } }'

# => { "credits": 120 }

Tải file đầu vào

POST/account/ai/uploads

Gửi multipart/form-data với trường file. Kết quả trả về url để đặt vào field kiểu image/video/audio/file khi chạy công cụ. Chỉ dùng được file do chính tài khoản bạn tải lên.

curl -X POST https://nov.ai.vn/api/account/ai/uploads \
  -H "X-API-Key: $API_KEY" \
  -F "file=@./anh-mau.jpg"

# => { "url": "https://nov.ai.vn/uploads/ai/inputs/...", "name": "anh-mau.jpg", "mimeType": "image/jpeg", "size": 183204 }

Chạy công cụ

POST/account/ai/tools/{key}/run

Kiểm tra tham số, trừ credits và tạo tác vụ. Tác vụ xử lý bất đồng bộ: lưu lại id rồi hỏi trạng thái định kỳ.

curl -X POST https://nov.ai.vn/api/account/ai/tools/tmc.image-to-video/run \
  -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{ "input": { "prompt": "Một chú mèo phi hành gia", "ratio": "16:9" } }'

# => {
#   "id": "3f1c...-uuid",
#   "code": "T8KQ2M4X",
#   "toolKey": "tmc.image-to-video",
#   "status": "PENDING",
#   "progress": 0,
#   "credits": 120,
#   "output": null,
#   ...
# }

Trạng thái tác vụ

GET/account/ai/tasks/{id}

Nhận id (uuid) hoặc mã tác vụ (code). Nên hỏi lại mỗi 5–10 giây cho tới khi status là SUCCEEDED, FAILED hoặc CANCELLED.

statusÝ nghĩa
PENDINGĐã nhận, đang gửi sang máy chủ AI
PROCESSINGĐang xử lý; progress là phần trăm hoàn thành (nếu nhà cung cấp báo)
SUCCEEDEDXong; kết quả nằm trong output
FAILEDLỗi; lý do ở error, credits tự hoàn lại (refunded = true)
CANCELLEDĐã huỷ, credits được hoàn lại
{
  "id": "3f1c...-uuid",
  "code": "T8KQ2M4X",
  "status": "SUCCEEDED",
  "progress": 100,
  "credits": 120,
  "refunded": false,
  "error": null,
  "output": {
    "files": [{ "url": "https://nov.ai.vn/uploads/ai/outputs/....mp4", "type": "video", "name": "video.mp4" }],
    "text": "..."          // chỉ có với công cụ trả văn bản
  },
  "createdAt": "2026-10-29T08:00:00.000Z",
  "completedAt": "2026-10-29T08:01:12.000Z"
}

Nên tải file kết quả về hệ thống của bạn: file trên máy chủ có thể được dọn sau một thời gian.

Lịch sử & huỷ tác vụ

GET/account/ai/tasks?page=1&limit=20&status=SUCCEEDED&tool={key}

Danh sách tác vụ mới nhất trước, có phân trang: { "data": [...], "meta": { "total", "page", "limit", "totalPages" } }. Lọc tuỳ chọn theo status, tool, category.

POST/account/ai/tasks/{id}/cancel

Huỷ tác vụ đang chờ gửi lại sau lỗi tạm thời (id dạng uuid), credits được hoàn lại. Tác vụ đã gửi sang máy chủ AI thì không huỷ được.

Số dư credits

GET/account/credits
{
  "credits": 5400,            // credits hiện có
  "plan": { "name": "Pro", "expiresAt": "2026-11-29T00:00:00.000Z", "active": true, ... },
  "concurrency": 3,           // số tác vụ được chạy cùng lúc
  "totalUsed": 12600,
  ...
}
GET/account/credits/transactions?page=1&limit=20

Lịch sử cộng/trừ credits (mua gói, chạy công cụ, hoàn credits...).

Ví dụ hoàn chỉnh

Node.js (18+)

const BASE = "https://nov.ai.vn/api";
const headers = { "X-API-Key": process.env.API_KEY, "Content-Type": "application/json" };

async function call(path, init = {}) {
  const res = await fetch(BASE + path, { ...init, headers });
  const body = await res.json();
  if (!res.ok) throw new Error(body.message);
  return body;
}

// 1) chạy công cụ
const task = await call("/account/ai/tools/tmc.image-to-video/run", {
  method: "POST",
  body: JSON.stringify({ input: { prompt: "Một chú mèo phi hành gia" } }),
});

// 2) hỏi trạng thái tới khi xong
let t = task;
while (["PENDING", "PROCESSING"].includes(t.status)) {
  await new Promise((r) => setTimeout(r, 5000));
  t = await call("/account/ai/tasks/" + task.id);
}
if (t.status !== "SUCCEEDED") throw new Error(t.error ?? t.status);
console.log(t.output.files.map((f) => f.url));

Python 3

import os, time, requests

BASE = "https://nov.ai.vn/api"
H = {"X-API-Key": os.environ["API_KEY"]}

def call(method, path, **kw):
    r = requests.request(method, BASE + path, headers=H, timeout=60, **kw)
    body = r.json()
    if not r.ok:
        raise RuntimeError(body.get("message"))
    return body

task = call("POST", "/account/ai/tools/tmc.image-to-video/run",
            json={"input": {"prompt": "Một chú mèo phi hành gia"}})

t = task
while t["status"] in ("PENDING", "PROCESSING"):
    time.sleep(5)
    t = call("GET", f"/account/ai/tasks/{task['id']}")

if t["status"] != "SUCCEEDED":
    raise RuntimeError(t.get("error") or t["status"])
print([f["url"] for f in t["output"]["files"]])

Mã công cụ hiện có

keyCông cụoutputGiá
tmc.image-to-videoẢnh thành videovideoTheo tham số (dùng API báo giá)
tmc.text-to-videoVăn bản thành videovideoTheo tham số (dùng API báo giá)
tmc.motion-controlĐiều khiển chuyển độngvideoTheo tham số (dùng API báo giá)
tmc.video-outfitThay trang phục videovideoTheo tham số (dùng API báo giá)
tmc.talking-photoẢnh biết nóivideoTheo tham số (dùng API báo giá)
tmc.video-enhanceLàm nét video 4KvideoTheo tham số (dùng API báo giá)
tmc.text-to-imageTạo ảnh AIimageTheo tham số (dùng API báo giá)
tmc.body-editChỉnh dáng ngườiimageTheo tham số (dùng API báo giá)
tmc.text-to-speechTạo giọng nói AIaudioTheo tham số (dùng API báo giá)
tmc.text-to-musicSáng tác nhạc AIaudioTheo tham số (dùng API báo giá)
sangtao.gpt-imageGPT Image 2imageTheo tham số (dùng API báo giá)
sangtao.videoVideo AI Veo 3.1 / GrokvideoTheo tham số (dùng API báo giá)
sangtao.voiceover-videoVideo từ kịch bảnvideoTheo tham số (dùng API báo giá)
sangtao.article-videoBài báo thành videovideoTheo tham số (dùng API báo giá)
sangtao.slideshow-videoVideo slideshowvideoTheo tham số (dùng API báo giá)
kapend.imageTạo ảnh đa modelimage3.000 credits
kapend.videoTạo video đa modelvideo900 credits / giây
kapend.motionKling Motion Controlvideo12.000 credits
kapend.upscale-videoNâng cấp video Topazvideo15.000 credits
kapend.ttsTạo Giọng Đọcaudio100 credits + 1 credits / ký tự
kapend.remove-logoXoá logo / watermarkvideo2.000 credits
aideepcut.swap-characterThay nhân vật videovideo25.000 credits
aideepcut.face-swapGhép mặt nhiều ảnhimage8.000 credits
kapend.seedanceSeedance VideovideoTheo tham số (dùng API báo giá)
kapend.klingKling AI VideovideoTheo tham số (dùng API báo giá)
kapend.avatarKling AvatarvideoTheo tham số (dùng API báo giá)
aideepcut.motion-imageMotion control nền ảnhvideoTheo tham số (dùng API báo giá)
aideepcut.video-face-swapĐổi mặt videovideoTheo tham số (dùng API báo giá)
aideepcut.basic-videoTạo video AI cơ bảnvideoTheo tham số (dùng API báo giá)
aideepcut.music-videoTạo video âm nhạcvideoTheo tham số (dùng API báo giá)
aideepcut.outfitThay đổi trang phụcimageTheo tham số (dùng API báo giá)
aideepcut.image-editChỉnh ảnh theo mô tảimageTheo tham số (dùng API báo giá)
aideepcut.character-views4 góc nhìn nhân vậtimageTheo tham số (dùng API báo giá)
aideepcut.image-to-promptDịch ngược ảnh ra prompttextTheo tham số (dùng API báo giá)