VidgenDùng thử miễn phí
Nhà phát triển

Tài liệu API Vidgen

Gọi Vidgen từ website, hệ thống nội bộ hay bot để tạo video tự động: gửi yêu cầu, nhận mã video, hỏi tiến độ hoặc nhận webhook, rồi tải mp4.

Mô tả máy đọc được (OpenAPI 3.0): https://vidgen.vn/api/v1/openapi.json.

Bắt đầu

  1. Đăng nhập, mở trang API (mục «API» ở chân trang của ứng dụng, địa chỉ #api), bấm «Tạo khoá». Khoá vg_live_… và bí mật webhook chỉ hiện một lần: lưu ngay. Gói của tổ chức (Đội nhóm, Doanh nghiệp): chọn tổ chức trước rồi mới tạo khoá.
  2. Mọi yêu cầu gửi tới địa chỉ gốc https://vidgen.vn/api/v1, thân và kết quả là JSON UTF-8.
  3. Thử ngay bằng một dòng: POST /quick với {"text": "…"} (mục Tạo nhanh).

Xác thực

Gửi tiêu đề Authorization: Bearer vg_live_… trong mọi yêu cầu. Không cần cookie hay tiêu đề chống giả mạo yêu cầu khi dùng khoá. Khoá có quyền như tài khoản của bạn (hạn mức, gói, giọng đọc): chỉ dùng ở máy chủ, không nhúng vào trang web hay ứng dụng di động; lộ thì thu hồi ngay ở trang API. Tối đa 10 khoá mỗi tài khoản (hoặc mỗi tổ chức), 120 yêu cầu mỗi phút mỗi khoá. Máy chủ chỉ lưu bản băm SHA-256 của khoá.

Khoá của tổ chức: tạo khi đang chọn tổ chức (chỉ Chủ tổ chức, Quản trị). Video, dự án tạo bằng khoá này thuộc tổ chức, tính vào gói, số video và lượt API của tổ chức, và theo cài đặt của tổ chức (giới hạn mỗi thành viên, «Duyệt trước khi dựng»: video giải thích dừng ở review). Người tạo khoá rời tổ chức, thôi quyền quản trị hoặc tổ chức bị khoá thì khoá trả 401.

curl -s "https://vidgen.vn/api/v1/me" -H "Authorization: Bearer vg_live_..."

Hạn mức

Mỗi video tạo thành công qua khoá API (POST /videos, POST /quick, làm bản khác …/duplicate, bản ngôn ngữ khác …/translate) tính một lượt API của tháng, đồng thời tính vào số video của gói. Yêu cầu lỗi (400, 402…) và lần gọi lại cùng external_id không tốn lượt. Nhiều biến thể trong một lần gọi tính một lượt API, mỗi biến thể một video.

GóiLượt APIVideo mỗi tháng
Miễn phíKhông dùng API3
Cơ bảnKhông dùng API20
Chuyên nghiệp200 lượt/tháng60
Đội nhóm1.000 lượt/tháng250
Doanh nghiệp10.000 lượt/tháng1.000

Gói không có API: không tạo được khoá; khoá tạo khi còn gói cao rồi hạ gói thì mọi điểm cuối trả 402 (trừ GET /me để xem gói). Gói Đội nhóm và Doanh nghiệp mua cho tổ chức: Chủ tổ chức hoặc Quản trị chọn tổ chức rồi tạo khoá của tổ chức (mục Xác thực); khoá cá nhân theo gói cá nhân.

Xem chi tiết và nâng gói ở bảng giá. Lượt đã dùng: api.used, api.limit của GET /me và trang Tài khoản.

Tạo nhanh một dòng: POST /quick

«Viết một dòng. Nhận một video.» Vidgen tự đoán loại video (quảng cáo, hướng dẫn, bài giảng), chọn mẫu gần chủ đề nhất, khổ, độ dài, giọng đọc, soạn kịch bản rồi dựng luôn. Đi qua đúng các kiểm tra như POST /videos: gói, lượt API, số video của tháng, bảo trì.

KhoáÝ nghĩa
textBắt buộc. Một dòng mô tả, 5 đến 600 ký tự
purposemarketing, huong-dan hoặc kien-thuc; bỏ trống thì đoán từ câu chữ
layoutshort (dọc 9:16, tối đa 60 giây) hoặc long (ngang 16:9); bỏ trống: quảng cáo dọc, còn lại ngang
external_id, callback_urlNhư ở POST /videos
curl -s -X POST "https://vidgen.vn/api/v1/quick" -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"text": "Giải thích định lý Pythagoras cho học sinh lớp 8", "external_id": "toan-8-pytago"}'

Kết quả giống POST /videos: 202 kèm video (request.template, request.layout, request.seconds cho biết lựa chọn tự động).

Tạo, hỏi tiến độ, tải

Việc dựng chạy nền vài phút. POST /videos trả ngay 202 với id; hỏi GET /videos/{id} mỗi 5 đến 15 giây hoặc chờ webhook; khi status là done thì tải /videos/{id}/video.

curl

KEY=vg_live_...                     # khoá của bạn
B=https://vidgen.vn/api/v1

# 1. Tạo video giải thích 45 giây, nhận webhook khi xong
curl -s -X POST "$B/videos" -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{
  "kind": "explainer", "brief": "Cache là gì và vì sao website nhanh hơn", "seconds": 45,
  "external_id": "bai-viet-42", "callback_url": "https://ung-dung.cua-ban.vn/hooks/vidgen"}'
# -> 202 {"id": "3f2a…", "status": "queued", ...}

# 2. Hỏi tiến độ (vài giây một lần, hoặc chờ webhook)
curl -s "$B/videos/3f2a…" -H "Authorization: Bearer $KEY"

# 3. Tải mp4 và phụ đề khi status = done
curl -sL "$B/videos/3f2a…/video" -H "Authorization: Bearer $KEY" -o video.mp4
curl -sL "$B/videos/3f2a…/srt" -H "Authorization: Bearer $KEY" -o video.srt

Python

import os, time, requests

B = "https://vidgen.vn/api/v1"
H = {"Authorization": "Bearer " + os.environ["VIDGEN_KEY"]}

r = requests.post(B + "/quick", headers=H, json={"text": "Quảng cáo quán cà phê Mộc giảm 20% tuần này",
                                                "external_id": "cafe-moc-1"})
if r.status_code == 402:                       # hết lượt hoặc gói chưa có API: r.json()["upgrade"] là gói gợi ý
    raise SystemExit(r.json()["error"])
r.raise_for_status()
vid = r.json()["id"]

while True:
    v = requests.get(f"{B}/videos/{vid}", headers=H).json()
    if v["status"] in ("done", "failed", "canceled"):
        break
    print(v["status"], v.get("stage"), round((v.get("progress") or 0) * 100), "%")
    time.sleep(10)

if v["status"] == "done":
    with open("video.mp4", "wb") as f:
        f.write(requests.get(f"{B}/videos/{vid}/video", headers=H).content)
else:
    print("Lỗi:", v["error"])

JavaScript

// Node.js 18+ (có sẵn fetch)
const B = "https://vidgen.vn/api/v1";
const H = {"Authorization": `Bearer ${process.env.VIDGEN_KEY}`, "Content-Type": "application/json"};

const r = await fetch(`${B}/videos`, {method: "POST", headers: H, body: JSON.stringify({
  kind: "explainer", brief: "Hướng dẫn đăng ký tài khoản trên ứng dụng của chúng tôi", layout: "long", seconds: 60,
  external_id: "huong-dan-dang-ky"})});
const v = await r.json();
if (!r.ok) throw new Error(`${r.status}: ${v.error}`);

let s;
do {
  await new Promise(ok => setTimeout(ok, 10000));
  s = await (await fetch(`${B}/videos/${v.id}`, {headers: H})).json();
} while (!["done", "failed", "canceled"].includes(s.status));
console.log(s.status, s.result?.video_url ?? s.error);

Tham số tạo video: POST /videos

KhoáÝ nghĩa
kindexplainer (video giải thích, marketing tự vẽ) hoặc screen (mặc định: AI quay màn hình một ứng dụng web công khai)
briefChủ đề (explainer) hoặc điều cần trình diễn (screen); 10 đến 1500 ký tự (explainer từ 5)
seconds, layoutexplainer: 30, 40, 45, 50, 60, 75, 90, 120, 150 hoặc 180 giây (mặc định 45), không vượt độ dài tối đa của gói (plan_features.max_seconds của GET /me); short dọc 9:16 (mặc định, tối đa 60 giây) hoặc long ngang 16:9
sourceexplainer: bài viết nguồn để video bám đúng nội dung (tối đa 20.000 ký tự)
look, style, cinemaexplainer: kiểu hình auto, motion, classic; phong cách và lớp điện ảnh khi dùng motion (giá trị hợp lệ: styles, cinemas của GET /config)
review_firstexplainer: true thì dừng ở review để bạn sửa kịch bản (PUT /videos/{id}/script) rồi POST /videos/{id}/render
voiceGiọng đọc, một trong voices của GET /me (neu, vbee, dry); bỏ trống thì dùng giọng đầu danh sách
url, format, quality, max_scenes, authscreen: địa chỉ công cộng cần quay, long/shorts, 1080/4k, số cảnh, phiên đăng nhập (xoá ngay khi quay xong)
project_id, nameLưu vào dự án; đặt tên video
marketing, variants, anglesVideo marketing theo brief sản phẩm và bộ nhận diện của dự án; 1 đến 3 biến thể; góc mở đầu
external_idKhoá của bạn, tối đa 100 ký tự A-Za-z0-9._:@/- (xem mục dưới)
callback_urlhttps://… công cộng nhận webhook

Nhiều biến thể trả thêm variants[], mỗi biến thể một video. Chi tiết kiểu dữ liệu ở OpenAPI.

Không tạo trùng: external_id

Gắn mã của bạn (vd. mã bài viết, mã đơn) vào external_id. Gọi lại với cùng mã thì nhận 200 kèm video cũ và "reused": true: không tạo video mới, không tốn hạn mức hay lượt API. Nhờ vậy gửi lại an toàn khi mất kết nối. Video cũ đã lỗi hoặc bị huỷ thì lần gọi sau tạo video mới. Mã riêng theo tài khoản; nhiều biến thể nhận mã <mã>#1, <mã>#2…

Webhook

Khi gửi kèm callback_url (bằng khoá API), Vidgen POST JSON tới địa chỉ đó khi video tới done, failed hoặc review:

{"event": "video.done",
 "video": {"id": "3f2a…", "status": "done", "external_id": "bai-viet-42", "kind": "explainer", "name": null, "project_id": null, "error": null,
           "result": {"title": "Cache là gì", "seconds": 48.2, "bytes": 8435270, "scenes": [{"title": "…", "say": ["…"]}],
                      "video_url": "/api/v1/videos/3f2a…/video", "srt_url": "/api/v1/videos/3f2a…/srt"}}}
Tiêu đềÝ nghĩa
X-Vidgen-Eventvideo.done, video.failed, video.review
X-Vidgen-Signaturesha256=<hex>: HMAC-SHA256 của THÂN yêu cầu bằng bí mật webhook của khoá đã tạo video
X-Vidgen-DeliveryMã lần gửi; lưu lại để không xử lý trùng

Kiểm chữ ký (Python)

import hashlib, hmac, json
from flask import Flask, request, abort

SECRET = "bí mật webhook hiện cùng khoá API"
app = Flask(__name__)

@app.post("/hooks/vidgen")
def vidgen_hook():
    raw = request.get_data()                                   # THÂN GỐC, chưa phân tích JSON
    want = "sha256=" + hmac.new(SECRET.encode(), raw, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(want, request.headers.get("X-Vidgen-Signature", "")):
        abort(401)
    ev = json.loads(raw)
    # chống xử lý trùng: lưu X-Vidgen-Delivery đã xử lý, gặp lại thì bỏ qua
    print(ev["event"], ev["video"]["external_id"])
    return "", 204

Kiểm chữ ký (JavaScript)

// Express: lấy thân gốc bằng express.raw, KHÔNG dùng express.json trước khi kiểm chữ ký
import crypto from "node:crypto";
import express from "express";
const SECRET = process.env.VIDGEN_WEBHOOK_SECRET;
const app = express();
app.post("/hooks/vidgen", express.raw({type: "application/json"}), (req, res) => {
  const want = "sha256=" + crypto.createHmac("sha256", SECRET).update(req.body).digest("hex");
  const got = req.get("X-Vidgen-Signature") || "";
  if (want.length !== got.length || !crypto.timingSafeEqual(Buffer.from(want), Buffer.from(got))) return res.sendStatus(401);
  const ev = JSON.parse(req.body);
  console.log(ev.event, ev.video.external_id);
  res.sendStatus(204);
});
  • Trả mã 2xx trong 10 giây là thành công; mã khác hoặc lỗi kết nối thì Vidgen thử lại sau 1, 5, 30 giây (tối đa 4 lần).
  • Vidgen không theo chuyển hướng: địa chỉ trả 3xx bị coi là thất bại. Đặt đúng địa chỉ cuối cùng.
  • callback_url phải là https:// tới máy chủ trên Internet công cộng; địa chỉ nội bộ, localhost bị từ chối, và Vidgen nối thẳng tới đúng địa chỉ IP đã kiểm.
  • Đường dẫn trong webhook là tương đối: ghép với https://vidgen.vn; tải video vẫn cần khoá API.
  • Webhook là «cố gắng hết sức»: lâu không thấy thì hỏi lại GET /videos/{id}.

Mã lỗi

Lỗi trả JSON {"error": "…"} bằng tiếng Việt, nói rõ cần sửa gì.

MãKhi nào
400Yêu cầu sai: thiếu hoặc sai tham số, địa chỉ nội bộ, external_id sai dạng. Đọc error để sửa.
401Thiếu khoá, khoá sai hoặc đã thu hồi, tài khoản bị khoá. Có khoá sai thì KHÔNG quay về phiên đăng nhập web.
402Gói chưa có API (khoá tạo khi còn gói cao, sau đó hạ gói), hết lượt API của tháng, hết video, hoặc tính năng không có trong gói. upgrade là mã gói gợi ý, feature cho biết giới hạn nào; buy_pack: true thì mua thêm video được.
403Thao tác chỉ làm được trên web (quản lý khoá, thanh toán, đổi mật khẩu, Video demo) hoặc vượt giới hạn video mỗi thành viên của tổ chức.
404Không có video, dự án này (hoặc của tài khoản khác).
409Video chưa xong (tải mp4, SRT) hoặc đang chạy (xoá).
429Quá 120 yêu cầu mỗi phút cho một khoá. Chờ rồi gọi lại, nên lùi dần.
503Hệ thống đang bảo trì; đọc tiêu đề Retry-After (giây) rồi gửi lại. Xem và tải video vẫn được.

Ví dụ 402

{"error": "Đã dùng hết 200 lượt tạo video qua API của tháng này (gói «Chuyên nghiệp»). Nâng cấp lên gói «Đội nhóm» để dùng.",
 "upgrade": "team", "feature": "api", "plan": "pro"}

Các điểm cuối khác

Phương thứcĐường dẫnÝ nghĩa
GET/videos?project=<id|none>Danh sách video của bạn
GET/videos/{id}Trạng thái queued, running, review, done, failed, canceled; stage, progress (0 đến 1), result
GET/videos/{id}/video, /srt, /scormTải mp4 (hỗ trợ Range), phụ đề SRT, gói SCORM cho LMS (theo gói)
GET/PUT/videos/{id}/scriptXem, sửa kịch bản khi status là review
POST/videos/{id}/renderDuyệt xong: xếp dựng từ kịch bản đã sửa
POST/videos/{id}/translateBản ngôn ngữ khác ({"lang": "en"}): video mới chờ duyệt
POST/videos/{id}/cancelHuỷ video đang chờ, đang chạy (hoàn hạn mức)
PATCH/DELETE/videos/{id}Đổi tên, chuyển dự án; xoá
GET/POST/projects; PATCH/DELETE /projects/{id}Dự án, kèm brief sản phẩm (product) và bộ nhận diện (brand)
GET/meGói, hạn mức và số video đã dùng, lượt API (api.limit, api.used), giọng dùng được (voices)
GET/configTuỳ chọn hợp lệ: phong cách, lớp điện ảnh, độ dài, ngôn ngữ dịch

Quản lý khoá API chỉ làm được khi đăng nhập trên web. Cần hỗ trợ tích hợp: liên hệ.