📡 Webhook API — Hướng Dẫn Tích Hợp

Địa chỉ: http://127.0.0.1:8765 (chỉ localhost) · Xác thực: API Key qua header X-API-Key · Yêu cầu: MAX

ℹ️Tham khảo đầy đủ tham số từng endpoint ở mục Webhook API (phần Hướng Dẫn Sử Dụng). API bất đồng bộ: submit → poll /api/status → tải file. Xử lý tối đa 10 tác vụ đồng thời; tác vụ lưu trong RAM (mất khi tắt app).
📄Tài liệu chi tiết để đưa cho AI tích hợp nhanh: WEBHOOK_INTEGRATION.vi.md · WEBHOOK_INTEGRATION.en.md

🔑 Xác Thực

Tất cả endpoint (trừ /api/health/api/files/*) yêu cầu API key trong header:

text
X-API-Key: YOUR_API_KEY

API key (token URL-safe 32 byte) được tạo tự động trong Cài đặt → Webhook. Bạn có thể tạo lại bất kỳ lúc nào.

Phản hồi 401 (Không có quyền):

json
{
  "error": "Invalid or missing API key"
}

📡 Danh Sách Endpoint

MethodEndpointAuthMô tả
GET/api/healthKiểm tra server
POST/api/image/generateTạo ảnh (Flow — Nano Banana)
POST/api/video/generateTạo video (Veo)
POST/api/grok/generateTạo ảnh/video Grok (T2I/I2I/T2V/I2V) MỚI
POST/api/meta/generateTạo ảnh/video Meta AI (T2I/I2I/T2V/I2V) MỚI
GET/api/status/{task_id}Kiểm tra trạng thái
GET/api/result/{task_id}Lấy kết quả
GET/api/tasksDanh sách 50 tác vụ gần nhất
GET/api/files/{filename}Tải file nhị phân

1. Tạo Ảnh — POST /api/image/generate

TrườngKiểuMặc địnhMô tả
promptstring— (bắt buộc)Mô tả ảnh
modelstringnano_banana_2nano_banana_2, nano_banana_pro hoặc nano_banana_2_lite (giá trị lạ → nano_banana_2)
aspect_ratiostring1:11:1, 3:4, 4:3, 9:16, 16:9
reference_imagesarray[]Tối đa 10 ảnh base64 hoặc object
upscalearray[]["2K"], ["4K"] (4K cần tài khoản Ultra)

2. Tạo Video — POST /api/video/generate

TrườngKiểuMặc địnhMô tả
promptstring— (bắt buộc)Mô tả chuyển động
modelstringveo_31_fastveo_31_fast, veo_31_lite, veo_31_quality, veo_31_lite_relaxed (Ultra), omni_flash
modestringtext_to_videotext_to_video, start_image, start_end_image, components
aspect_ratiostring16:916:9, 9:16
resolutionarray["720p"]720p, 1080p, 4K (chỉ 4K cần Ultra)
reference_imagesarray[]Bắt buộc khi mode ≠ text. Tối đa 3 (Veo), 7 (Omni Flash)
voicestring""Giọng đọc — chỉ mode components
video_lengthint8Giây. Veo: 4/6/8 (4/6 cần Ultra). Omni Flash: 4/6/8/10
⚠️veo_31_fast_relaxed không còn hợp lệ (tự về veo_31_fast). Omni Flash không hỗ trợ start_end_image.

3. Tạo Grok — POST /api/grok/generate MỚI

TrườngKiểuMặc địnhMô tả
promptstring— (bắt buộc)Mô tả nội dung
modestringt2vt2i, i2i, t2v, i2v (mode sai → failed)
aspect_ratiostring9:169:16, 16:9, 1:1, 2:3, 3:2
reference_imagesarray[]Tối đa 5; bắt buộc cho i2i & i2v
video_lengthint66 hoặc 10 (chỉ mode video)
resolutionstring480p480p hoặc 720p (chỉ mode video; ảnh luôn 1K)

4. Tạo Meta AI — POST /api/meta/generate MỚI

TrườngKiểuMặc địnhMô tả
promptstring— (bắt buộc)Mô tả nội dung
modestringt2it2i, i2i, t2v, i2v (mode sai → failed)
aspect_ratiostring9:169:16, 16:9, 1:1
resolutionstring720p480p hoặc 720p (chỉ mode video; ảnh luôn 1K)
countint11–4 kết quả mỗi prompt
character_image / scene_image / style_imagestringbase64 — thành phần cho mode i2i (cần ≥1)
start_image / end_imagestringbase64 — khung đầu (bắt buộc) / khung cuối (tùy chọn) cho mode i2v
ℹ️Meta AI cần tài khoản Meta riêng (cookie meta_session của vibes.ai). Trang Meta AI trong app chỉ dành cho gói PLUS/MAX; ảnh tham chiếu truyền theo slot có tên, không dùng mảng reference_images.

Ảnh tham chiếu & @tag

json
"reference_images": [
  "data:image/png;base64,...",
  {"data": "base64...", "category": "subject", "name": "red_car.png"}
]

category (subject/scene/style) bị bỏ qua với model Flow. Khi ảnh có name, trỏ vào prompt bằng @tag (khớp chuỗi con tên file) — chỉ dùng cho ảnh & video (Veo), Grok & Meta AI không hỗ trợ.

5–8: Trạng Thái · Kết Quả · Danh Sách · Tải File

text
GET /api/status/{task_id}    — Kiểm tra trạng thái
GET /api/result/{task_id}    — Lấy kết quả
GET /api/tasks               — Danh sách tác vụ (tối đa 50)
GET /api/files/{filename}    — Tải file nhị phân

Các trạng thái: pendingrunningcompleted / failed

🔄 Quy Trình Polling

Vì quá trình tạo ảnh/video mất thời gian, dùng polling (đề xuất 3–5 giây/lần):

python
import requests, time

BASE = "http://127.0.0.1:8765"
HEADERS = {"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"}

resp = requests.post(f"{BASE}/api/image/generate", headers=HEADERS, json={
    "prompt": "thanh pho tuong lai luc hoang hon",
    "model": "nano_banana_2",
    "aspect_ratio": "16:9"
})
task_id = resp.json()["task_id"]

while True:
    s = requests.get(f"{BASE}/api/status/{task_id}", headers=HEADERS).json()
    if s["status"] == "completed":
        for url in s["results"]:
            data = requests.get(url).content   # /api/files khong can key
            open(url.split("/")[-1], "wb").write(data)
        break
    if s["status"] == "failed":
        print(s["error_code"], s["error"])
        break
    time.sleep(4)

🔗 Ví Dụ Tích Hợp

JavaScript / Node.js

javascript
const BASE = "http://127.0.0.1:8765";
const H = { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" };

const res = await fetch(`${BASE}/api/image/generate`, {
  method: "POST", headers: H,
  body: JSON.stringify({ prompt: "a cat in space", model: "nano_banana_2", aspect_ratio: "1:1" })
});
const { task_id } = await res.json();

const poll = setInterval(async () => {
  const s = await fetch(`${BASE}/api/status/${task_id}`, { headers: H }).then(r => r.json());
  if (s.status === "completed") { clearInterval(poll); console.log(s.results); }
  if (s.status === "failed") { clearInterval(poll); console.error(s.error); }
}, 5000);

cURL Kiểm Tra Nhanh

bash
curl http://127.0.0.1:8765/api/health

curl -X POST http://127.0.0.1:8765/api/grok/generate \
  -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"prompt": "a girl swimming", "mode": "t2i", "aspect_ratio": "16:9"}'

curl -X POST http://127.0.0.1:8765/api/meta/generate \
  -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"prompt": "a girl swimming", "mode": "t2i", "aspect_ratio": "16:9"}'

curl -H "X-API-Key: YOUR_KEY" http://127.0.0.1:8765/api/status/TASK_ID

⚠️ Bảng Mã Lỗi

Mã HTTPÝ nghĩa
202Đã nhận tác vụ (đang xếp hàng)
400Body rỗng / JSON sai
401API key không hợp lệ hoặc thiếu
404Không tìm thấy tác vụ/file/endpoint
500Lỗi đọc file server

Khi tác vụ failed, response status có error_code:

error_codeÝ nghĩa
429Hết quota / rate-limit → nghỉ, xoay tài khoản, thử lại
403PERMISSION_DENIED / lỗi phiên
400Yêu cầu sai / vi phạm chính sách prompt
500Lỗi máy chủ Google/xAI/Meta
0Lỗi đầu vào (thiếu prompt, không có tài khoản, mode Grok/Meta sai, timeout...)