← Về trang chính

Bắt đầu

Mọi request gửi và nhận JSON. Phản hồi luôn có trường ok; khi lỗi có thêm error mô tả bằng tiếng Việt.

Base URL

http://localhost:3000

Xác thực

Gửi API key ở header của mọi request. Chấp nhận cả hai kiểu — dùng kiểu nào tool của bạn hỗ trợ.

X-API-Key: vk_xxxxx

# hoac, neu tool cua ban chi co o "Bearer token":
Authorization: Bearer vk_xxxxx
Giữ key bí mật. Ai có key đều tiêu được credit của bạn. Nếu lộ, vào trang chính thu hồi key đó và tạo key mới — key cũ ngừng hoạt động ngay lập tức.

Credit

LoạiCreditThành tiền
Video 5 giây5.0005.000đ
Video 10 giây10.00010.000đ
Ảnh AI100100đ

Credit bị trừ ngay khi tạo job. Nếu tạo thất bại vì lỗi hệ thống, credit được hoàn lại tự động. Xem bảng giá chi tiết từng model, hoặc gọi GET /api/v1/models để lấy bảng giá theo thời gian thực thay vì ghi cứng số trong code.

Tạo video

POST/api/v1/videos

Tham số

TrườngKiểuMô tả
prompt *stringMô tả nội dung video. Từ 3 ký tự.
durationintSố giây, mặc định 10. Không chọn model thì dùng 5 hoặc 10. Có chọn model thì tuỳ model — trong kho có model nhận tới 30 giây. Danh sách chính xác nằm ở durations_avail của GET /api/v1/models.
ratiostring9:16, 16:9 hoặc 1:1. Mặc định 9:16.
modelstringMã model nếu muốn dùng model cao cấp. Xem GET /api/v1/models.
server_idintChọn server. Bỏ trống là dùng server mặc định. Mỗi server có kho model riêng, nên server_id phải khớp với server của model bạn chọn — sai server thì trả về lỗi 400 và không trừ credit. Xem danh sách ở GET /api/v1/models hoặc trang bảng giá.
resolutionstringVí dụ 720p, 1080p. Chỉ với model hỗ trợ — xem resolutions_avail.
modestringChế độ render của model, ví dụ standard, professional, fast, turbo. Giá đổi theo chế độ, có model chênh nhau vài lần. Mỗi model có bộ chế độ riêng — lấy đúng tên ở price_combos.
image_urlstringURL ảnh tham chiếu để tạo video từ ảnh. Lấy qua POST /api/v1/upload-image.
image_urlsstring[]Nhiều ảnh tham chiếu, tối đa 5. Được ưu tiên nếu gửi cùng image_url.
video_urlstringURL video nguồn, cho các model sửa/chuyển động video.

Ví dụ

curl -X POST http://localhost:3000/api/v1/videos \
  -H "X-API-Key: vk_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Chú mèo phi hành gia trôi trong vũ trụ, ánh sáng rực rỡ",
    "duration": 10,
    "ratio": "9:16"
  }'

Phản hồi

{
  "ok": true,
  "video": {
    "id": "cms8rhkln0001vne0gfseyy7x",
    "status": "queued",
    "prompt": "Chú mèo phi hành gia...",
    "duration": 10,
    "ratio": "9:16",
    "credit_cost": 10000,
    "video_url": null,
    "error": null,
    "created_at": "2026-07-31T09:50:14.411Z",
    "done_at": null
  },
  "balance": 458000
}

Chọn model

GET/api/v1/models

Không gửi model thì hệ thống dùng cấu hình mặc định. Muốn chọn cụ thể thì lấy danh sách ở đây — đừng ghi cứng vào code, kho model đổi theo thời gian.

{
  "ok": true,
  "servers": [{
    "id": 2,
    "name": "Máy chủ chính",
    "models": [{
      "model": "kling_video_3_0",
      "name": "Kling AI 3.0",
      "media_type": "video",
      "durations_avail": ["5", "10"],
      "resolutions_avail": [],
      "credit_cost_matrix": { "5||standard": 5, "10||standard": 10 },
      "price_combos": ["5||standard", "10||standard"],
      "requires": null
    }]
  }]
}

Đọc bảng giá của một model

Khoá trong credit_cost_matrix có dạng duration|resolution|mode — phần nào model không dùng thì để trống. Giá trị chính là số credit sẽ bị trừ.

KhoáGửi lên
10|1080p|professional{ "duration": 10, "resolution": "1080p", "mode": "professional" }
5||standard{ "duration": 5, "mode": "standard" }
||chỉ cần prompt, model có một mức giá duy nhất
Trường requires
image — model bắt buộc có image_url. video — bắt buộc có video_url. null — chỉ cần prompt.
Gửi thiếu thì nhận lỗi 400 ngay và không bị trừ credit — hệ thống chặn trước khi gọi đi, không để bạn mất tiền vào một job chắc chắn hỏng.

Kho model đi theo nhà cung cấp: model nào đang bán được thì có trong danh sách này. Vì vậy hãy gọi lại định kỳ thay vì lưu một bản chép cứng.

Kiểm tra kết quả

GET/api/v1/videos/{id}

Hỏi lại mỗi 15–30 giây. Khi status done thì video_url có link tải.

curl http://localhost:3000/api/v1/videos/cms8rhkln0001vne0gfseyy7x \
  -H "X-API-Key: vk_xxxxx"

Trạng thái

statusÝ nghĩa
queuedĐang xếp hàng chờ xử lý
processingĐang render
doneXong — video_url đã sẵn sàng
failedThất bại — xem error, credit đã được hoàn

Webhook — khỏi phải hỏi lại

Thêm callback_url khi tạo job, hệ thống sẽ gọi về địa chỉ đó ngay khi xong. Một video 30 phút mà hỏi lại mỗi 20 giây là ~90 request rỗng; có webhook thì còn đúng một.

curl -X POST http://localhost:3000/api/v1/videos \
  -H "Authorization: Bearer vk_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Chú mèo phi hành gia",
    "duration": 10,
    "callback_url": "https://server-cua-ban.com/webhook"
  }'

Hệ thống gửi về

POST https://server-cua-ban.com/webhook
X-Webhook-Timestamp: 1785600000
X-Webhook-Signature: sha256=a3f1...

{
  "event": "video.completed",
  "video": {
    "id": "cms...",
    "status": "done",
    "video_url": "https://...mp4",
    "credit_cost": 10000,
    "error": null
  }
}

Xác minh chữ ký

Ai biết địa chỉ webhook của bạn cũng gửi được thông báo giả. Hãy kiểm tra chữ ký trước khi tin. Lấy khoá bí mật ở trang chính, mục Webhook.

// Node.js
const crypto = require('crypto')

app.post('/webhook', express.raw({ type: '*/*' }), (req, res) => {
  const ts  = req.headers['x-webhook-timestamp']
  const sig = req.headers['x-webhook-signature']
  const body = req.body.toString()

  const mong = 'sha256=' + crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(ts + '.' + body)
    .digest('hex')

  if (sig !== mong) return res.status(401).end()
  // Quá 5 phút thì bỏ — chặn phát lại request cũ
  if (Math.abs(Date.now()/1000 - Number(ts)) > 300) return res.status(401).end()

  const data = JSON.parse(body)
  console.log('xong:', data.video.video_url)
  res.status(200).end()   // trả 200, nếu không hệ thống sẽ gửi lại
})
Thử lại khi lỗi
Server của bạn không trả HTTP 2xx, hệ thống thử lại 5 lần trong vòng 80 phút (ngay, 1 phút, 5, 15, 60). Hết lượt vẫn không được thì kết quả vẫn lấy bình thường bằng GET /api/v1/videos/{id} — webhook chỉ là đường nhanh hơn, không phải đường duy nhất.

Địa chỉ phải dùng https và trỏ ra Internet công cộng. Địa chỉ nội bộ (localhost, 10.x, 192.168.x…) bị từ chối vì lý do bảo mật.

Dùng qua lớp tương thích thì đặt tên trường theo nhà đó: fal_webhook (query, fal.ai), callBackUrl (kie.ai), config.webhook_config.endpoint (PiAPI).

Ảnh tham chiếu

POST/api/v1/upload-image

Gửi multipart/form-data, field tên image. Nhận png/jpg/webp, tối đa 10MB. Bước này không tốn credit.

# 1) Tải ảnh lên
curl -X POST http://localhost:3000/api/v1/upload-image \
  -H "X-API-Key: vk_xxxxx" \
  -F "image=@nhan-vat.png"
# → { "ok": true, "image_url": "https://..." }

# 2) Tạo video từ ảnh đó
curl -X POST http://localhost:3000/api/v1/videos \
  -H "X-API-Key: vk_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"Nhân vật vẫy tay chào, camera zoom nhẹ","image_url":"https://..."}'

Viết kịch bản

POST/api/v1/chat/completions

Đúng chuẩn OpenAI — tool nào nói được với OpenAI thì chỉ cần đổi Base URL sang địa chỉ này, không phải sửa gì thêm.

curl -X POST http://localhost:3000/api/v1/chat/completions   -H "X-API-Key: vk_xxxxx"   -H "Content-Type: application/json"   -d '{
    "model": "gpt-5.5",
    "messages": [
      {"role": "user", "content": "Viết kịch bản video 15 giây quảng cáo quán tạp hoá"}
    ],
    "max_tokens": 1000
  }'

Model dùng được: gpt-5.5 claude-opus-4-8. Trả về đúng hình dạng choices[0].message.content usage như OpenAI, kèm hai trường thêm credit_costbalance để bạn biết vừa tiêu bao nhiêu mà khỏi gọi thêm request.

Tính tiền theo token thật
Hệ thống giữ tạm một khoản theo max_tokens, gọi xong biết số token thật thì trả lại phần thừa ngay. Nên đặt max_tokens sát nhu cầu để không bị giữ tạm quá nhiều — tiền vẫn về đủ, nhưng trong lúc chờ thì số dư khả dụng thấp hơn.

Bóc lời từ audio

POST/api/v1/audio/transcriptions

Gửi multipart/form-data. Cũng theo chuẩn OpenAI.

# Cach 1 — gui thang file (chi hop voi file nho)
curl -X POST http://localhost:3000/api/v1/audio/transcriptions   -H "X-API-Key: vk_xxxxx"   -F "file=@ghi-am.mp3"

# Cach 2 — dua dia chi, he thong tu tai ve
curl -X POST http://localhost:3000/api/v1/audio/transcriptions   -H "X-API-Key: vk_xxxxx"   -F "file_url=https://server-cua-ban.com/ghi-am.mp3"
File lớn thì phải dùng file_url
Gửi thẳng file bị chặn ở 4,5MB — đó là giới hạn của hạ tầng, không phải của chúng tôi. Đưa địa chỉ thì hệ thống tự tải nên không vướng — nhưng nhà cung cấp vẫn chặn ở khoảng 4MB (đo thực tế: 3,7MB chạy được, 9,2MB bị từ chối). Audio nén mp3 ở 32kbps thì 4MB tương đương khoảng 17 phút; nén 64kbps được khoảng 8 phút. Địa chỉ phải là https và trỏ ra Internet công cộng.
TrườngMô tả
fileFile âm thanh gửi kèm. mp3, m4a, wav, webm…
file_urlĐịa chỉ file, dùng thay cho file
modelBỏ trống là dùng loại rẻ nhất. Xem GET /api/v1/models.

Trả về text (nội dung), duration (số giây), credit_costbalance.

Tính tiền theo phút
Giá theo độ dài audio, biết chính xác sau khi xử lý xong. Hệ thống giữ tạm theo dung lượng file rồi quyết toán bằng thời lượng thật — phần thừa trả lại ngay. File rất ngắn thì tính theo mức tối thiểu.

Hỏi giá trước khi làm

POST/api/v1/estimate

Trả về số credit sẽ bị trừ mà không trừ đồng nào. Gọi cái này trước khi tạo job thì tool của bạn biết trước chi phí, và biết cả lựa chọn rẻ hơn.

curl -X POST http://localhost:3000/api/v1/estimate   -H "X-API-Key: vk_xxxxx"   -H "Content-Type: application/json"   -d '{"kind":"image","model":"google_image_gen_banana_pro"}'
{
  "ok": true,
  "credit_cost": 7000,
  "vnd": 7000,
  "balance": 124374,
  "du_credit": true,
  "re_hon": [
    { "model": "gemini-3.0-pro-image-portrait", "name": "Gemini 3.0 Pro — Ảnh dọc", "tu_khoang": "28 credit" },
    { "model": "gpt-image-2", "name": "GPT Image 2", "tu_khoang": "500 credit" }
  ]
}
TrườngMô tả
kind *stringvideo, image, text hoặc transcribe.
modelstringBỏ trống thì báo giá cho lựa chọn rẻ nhất của loại đó.
durationintSố giây, cho video.
resolutionstringCho video và ảnh có nhiều mức.
modestringChế độ render — giá đổi theo nó.
max_tokensintCho kind: text. Giá cuối vẫn tính theo token thật.
duration_secondsintCho kind: transcribe. Không gửi thì báo giá cho 1 phút.
Trường re_hon
Danh sách model làm được cùng việc mà rẻ hơn đáng kể. Cùng một việc tách nền, tuỳ model mà tốn 28 hay 7.000 credit — chênh 250 lần. Đây là chỗ để bạn thấy khoảng cách đó trước khi trả tiền.

Sửa ảnh · Tách nền · Ghép ảnh

POST/api/v1/images/edits

Gửi multipart/form-data với file ảnh đính kèm, đúng chuẩn OpenAI. Khác với /api/v1/images ở chỗ nhận thẳng file thay vì bắt bạn tự đưa ảnh lên đâu đó lấy địa chỉ.

# Tach nen, giu nguyen chu tren bao bi
curl -X POST http://localhost:3000/api/v1/images/edits   -H "X-API-Key: vk_xxxxx"   -F "image=@san-pham.png"   -F "prompt=Tach nen, giu nguyen chu the va chu tren bao bi"   -F "background=transparent"

# Ghep hai anh — dua ca hai vao cung luc
curl -X POST http://localhost:3000/api/v1/images/edits   -H "X-API-Key: vk_xxxxx"   -F "image[]=@san-pham.png"   -F "image[]=@nhan-vat.png"   -F "prompt=Nhan vat cam san pham tren tay"
TrườngMô tả
image *fileẢnh gốc. Dùng image[] để gửi nhiều ảnh — tối đa 5, mỗi ảnh tối đa 4MB.
prompt *stringMô tả việc cần làm với ảnh.
modelstringBỏ trống là dùng model rẻ nhất. Xem GET /api/v1/models.
backgroundstringĐặt transparent để ra nền trong suốt — dùng cho tách nền.
input_fidelitystringMức giữ chi tiết ảnh gốc. Mặc định đã là high, chỉ gửi khi muốn hạ xuống.
qualitystringlow, medium, high.
sizestringTỉ lệ khung ảnh, ví dụ 1:1.
Vì sao input_fidelity quan trọng
Thiếu nó thì model vẽ lại ảnh thay vì sửa ảnh — chữ trên bao bì ra sai chính tả, logo biến dạng, nền không trong. Chúng tôi đã bật sẵn mức cao nhất, nên bạn không phải làm gì. Chỉ hạ xuống khi muốn model tự do sáng tạo hơn.

Phản hồi trả về job giống /api/v1/images, kèm input_urls — địa chỉ ảnh bạn vừa gửi, dùng lại được cho lần sau mà không phải tải lên nữa.

Các endpoint khác

MethodĐường dẫnTrả về
POST/api/v1/imagesTạo ảnh AI. Tham số như tạo video nhưng không có duration.
GET/api/v1/images/{id}Trạng thái ảnh, có image_url khi xong.
GET/api/v1/videosDanh sách video. Phân trang bằng page per_page (tối đa 50).
GET/api/v1/imagesDanh sách ảnh.
GET/api/v1/balanceSố dư credit và quy đổi ra VNĐ.
GET/api/v1/pricingBảng giá hiện hành.
POST/api/v1/estimateHỏi giá trước, không trừ credit — xem mục Hỏi giá trước khi làm.
POST/api/v1/images/editsSửa ảnh, tách nền, ghép ảnh — xem mục Sửa ảnh ở trên.
POST/api/v1/chat/completionsViết kịch bản, tóm tắt, dịch — xem mục Viết kịch bản ở trên.
POST/api/v1/audio/transcriptionsBóc lời từ audio — xem mục Bóc lời từ audio ở trên.
GET/api/v1/modelsDanh sách model kèm giá từng tổ hợp — xem mục Chọn model ở trên.

Dùng key trong tool có sẵn

Nếu tool của bạn không cho điền API tuỳ ý mà chỉ hỗ trợ một số nhà cung cấp, hãy chọn nhà tương ứng bên dưới rồi đổi Base URL sang địa chỉ ở cột giữa. Key vẫn là key của bạn, credit vẫn trừ trong cùng một ví.

Chọn trong toolBase URL điền vàoÔ API key
fal.aihttp://localhost:3000/compat/faldán key như bình thường
PiAPIhttp://localhost:3000/compat/piapidán key như bình thường
kie.aihttp://localhost:3000/compat/kiedán key như bình thường
Về việc chọn model trong tool
Tên model của các nhà đó không trùng với model bên này. Hệ thống sẽ cố khớp gần đúng — ví dụ chọn kling-2.6 sẽ ra model Kling tương ứng. Khớp không nổi thì dùng cấu hình mặc định (5.000 credit cho 5 giây, 10.000 credit cho 10 giây).
Muốn chắc chắn dùng đúng model nào, điền thẳng mã model của bên này — xem bảng giá.

Lớp tương thích chỉ đổi hình dạng request. Giá, hạn mức và cách trừ credit hoàn toàn giống khi gọi /api/v1 trực tiếp.

Mã lỗi

HTTPÝ nghĩaNên làm gì
400Dữ liệu sai, hoặc model đòi ảnh/video mà không gửi kèmSửa request. Thử lại y hệt cũng sẽ lỗi.
401Thiếu, sai, hoặc key đã bị thu hồiKiểm tra header X-API-Key.
402Không đủ creditNạp thêm ở trang chính.
403Tài khoản bị khoáLiên hệ hỗ trợ.
404Không tìm thấy jobKiểm tra lại id.
429Gọi quá nhanh hoặc quá nhiều job cùng lúcChờ theo header Retry-After rồi thử lại.
503Hệ thống quá tải hoặc đang bảo trìThử lại sau vài phút. Credit chưa bị trừ.
Giới hạn mặc định: 60 request/phút mỗi key và 10 job xử lý cùng lúc mỗi tài khoản. Cần hạn mức cao hơn thì liên hệ.
Hỗ trợ