🌐 Webhook API Server
Máy chủ REST API cục bộ — cho phép công cụ bên ngoài (n8n, Make.com, Zapier, Python, cURL, AI agent...) gửi yêu cầu tạo ảnh, video (Veo) và Grok tự động qua HTTP.
Webhook API yêu cầu gói Max. Các gói khác không thể bật máy chủ.
Bất đồng bộ (async): Mọi yêu cầu trả về
task_id ngay lập tức (HTTP 202). Bạn poll /api/status/{task_id} đến khi completed/failed rồi tải file từ results. Server xử lý tối đa 10 tác vụ đồng thời, phần còn lại xếp hàng chờ.Tài liệu kỹ thuật đầy đủ (cho lập trình viên / AI agent): WEBHOOK_INTEGRATION.vi.md · WEBHOOK_INTEGRATION.en.md — chỉ cần đưa file này cho AI là tích hợp webhook nhanh gọn.
7.1 Thiết Lập

Bước 1: Cấu hình Server
| Thành phần | Mô tả |
|---|---|
| Trạng thái | 🔴 Offline / 🟢 Online — hiển thị trực tiếp trên giao diện |
| Cổng (Port) | Mặc định: 8765. Phạm vi: 1024 – 65535 |
| URL | Máy chủ luôn chạy tại http://127.0.0.1:{port} — chỉ truy cập được trên máy cục bộ (loopback). Muốn gọi từ máy khác phải tự dựng tunnel/reverse proxy |
CORS được bật sẵn (
Access-Control-Allow-Origin: *) và xử lý preflight OPTIONS → client chạy trên trình duyệt vẫn gọi được.Bước 2: Tạo API Key
- Nhấn 🔑 Generate — hệ thống tạo API key ngẫu nhiên (token URL-safe 32 byte)
- Nhấn 📋 Copy để sao chép key vào clipboard
- Thêm key vào header
X-API-Keycho mọi request (trừ/api/healthvà/api/files/*)
Bước 3: Bật Server
- Chọn port → Nhấn ▶ Start Server
- Server chạy nền — không ảnh hưởng đến các tính năng khác của app
- Nhấn ⏹ Stop Server để tắt bất kỳ lúc nào
API key được lưu tự động, không cần tạo lại mỗi lần mở app. Tác vụ được lưu trong RAM (in-memory) — nếu khởi động lại app, danh sách
task_id và kết quả sẽ mất. Hãy gửi → poll → tải file trong cùng một phiên chạy app.7.2 Danh Sách API Endpoints
| Phương thức | Đường dẫn | Xác thực | Mô tả |
|---|---|---|---|
| GET | /api/health | ❌ Không | Kiểm tra trạng thái server, thời gian chạy, số tác vụ đang chờ/đang chạy |
| POST | /api/image/generate | ✅ Có | Gửi yêu cầu tạo ảnh (Flow — Nano Banana) |
| POST | /api/video/generate | ✅ Có | Gửi yêu cầu tạo video (Veo) |
| POST | /api/grok/generate | ✅ Có | Gửi yêu cầu tạo ảnh/video bằng Grok (T2I/I2I/T2V/I2V) MỚI |
| POST | /api/meta/generate | ✅ Có | Gửi yêu cầu tạo ảnh/video bằng Meta AI (T2I/I2I/T2V/I2V) MỚI |
| GET | /api/status/{task_id} | ✅ Có | Kiểm tra trạng thái tác vụ (pending/running/completed/failed) |
| GET | /api/result/{task_id} | ✅ Có | Lấy kết quả (chỉ khi đã completed) |
| GET | /api/tasks | ✅ Có | Danh sách 50 tác vụ gần nhất (mới nhất trước) |
| GET | /api/files/{filename} | ❌ Không | Tải file ảnh/video đã tạo |
Dấu
/ ở cuối đường dẫn được chấp nhận (vd: /api/health/). Thiếu/sai key → 401 {"error":"Invalid or missing API key"}.7.3 Tạo Ảnh Flow Qua API
POST /api/image/generate
| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
| prompt | string | ✅ | — | Mô tả ảnh cần tạo |
| model | string | ❌ | nano_banana_2 | nano_banana_pro, nano_banana_2 hoặc nano_banana_2_lite. Giá trị lạ → tự về nano_banana_2 |
| aspect_ratio | string | ❌ | 1:1 | 1:1, 3:4, 4:3, 9:16, 16:9 |
| reference_images | array | ❌ | [] | Tối đa 10 ảnh base64 (xem mục 7.7) |
| upscale | array | ❌ | [] | ["2K"], ["4K"] hoặc ["2K","4K"] — 4K cần tài khoản Google Ultra |
API ảnh nhận 3 model Flow:
nano_banana_2, nano_banana_pro và nano_banana_2_lite. Các model cũ (imagen4, nano_banana Whisk) không còn dùng cho webhook — nếu truyền vào sẽ tự đổi thành nano_banana_2 (không báo lỗi).Bảng Model Ảnh
| model (API) | Tên hiển thị | Tỷ lệ hỗ trợ |
|---|---|---|
nano_banana_2 | Nano Banana 2 (mặc định) | 1:1, 3:4, 4:3, 9:16, 16:9 |
nano_banana_pro | Nano Banana Pro | 1:1, 3:4, 4:3, 9:16, 16:9 |
nano_banana_2_lite | Nano Banana 2 Lite | 1:1, 3:4, 4:3, 9:16, 16:9 |
Số file trả về: không có
upscale → 1 ảnh gốc. Có upscale → 1 file cho mỗi độ phân giải yêu cầu (theo thứ tự tăng dần, vd ["2K","4K"] → 2 file); ảnh gốc không được trả kèm. Nếu độ phân giải yêu cầu không tạo được (vd 4K mà không có Ultra) → tác vụ failed, không trả ảnh nhỏ thay thế.7.4 Tạo Video Flow Qua API (Veo)
POST /api/video/generate
| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
| prompt | string | ✅ | — | Mô tả chuyển động / cảnh quay |
| model | string | ❌ | veo_31_fast | Xem bảng model bên dưới |
| aspect_ratio | string | ❌ | 16:9 | 16:9 hoặc 9:16 |
| mode | string | ❌ | text_to_video | text_to_video, start_image, start_end_image, components |
| reference_images | array | Tùy mode | [] | Base64 — bắt buộc khi mode ≠ text_to_video. Tối đa 3 (Veo), 7 (Omni Flash, mode components) |
| resolution | array | ❌ | ["720p"] | ["720p"], ["1080p"], ["4K"] — chỉ 4K cần Ultra (1080p không cần) |
| voice | string | ❌ | "" | Tên giọng đọc (chữ thường) — chỉ dùng cho mode components |
| video_length | int | ❌ | 8 | Độ dài clip (giây). Veo: 4/6/8 (4 và 6 cần Ultra). Omni Flash: 4/6/8/10 |
Bảng Model Video
| model (API) | Tên hiển thị | Ghi chú |
|---|---|---|
veo_31_fast | Veo 3.1 Fast | Mặc định |
veo_31_lite | Veo 3.1 Lite | Phiên bản nhẹ |
veo_31_quality | Veo 3.1 Quality | Chất lượng cao nhất |
veo_31_lite_relaxed | Veo 3.1 Lite Relaxed | Yêu cầu tài khoản Ultra |
omni_flash | Omni Flash | Mode components hỗ trợ tới 7 ảnh + giọng đọc; không hỗ trợ start_end_image |
Model
veo_31_fast_relaxed không còn hợp lệ — nếu truyền vào sẽ tự về veo_31_fast (bản thường, không relaxed). Mode lạ sẽ chạy như text_to_video (bỏ qua ảnh). Omni Flash + start_end_image bị từ chối (chưa hỗ trợ khung hình cuối).Chế Độ Video (mode)
| mode | Mô tả | reference_images |
|---|---|---|
text_to_video | Tạo video từ prompt | Không cần |
start_image | Ảnh đầu + prompt → video | 1 ảnh (ảnh bắt đầu) |
start_end_image | Ảnh đầu + ảnh cuối + prompt | 2 ảnh (đầu, cuối). Veo only |
components | Ghép ảnh thành phần + prompt (hỗ trợ voice) | Veo tối đa 3, Omni Flash tối đa 7 |
Thứ tự ảnh: với
start_end_image, reference_images[0] là khung đầu, [1] là khung cuối. Với start_image chỉ dùng [0]. Video trả về 1 file cho mỗi độ phân giải tạo được.7.5 Tạo Ảnh/Video Grok AI Qua API MỚI
POST /api/grok/generate
Một endpoint cho cả 4 chế độ Grok — phân biệt bằng tham số mode.
| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
| prompt | string | ✅ | — | Mô tả nội dung |
| mode | string | ❌ | t2v | t2i, i2i, t2v, i2v — mode sai → tác vụ failed |
| aspect_ratio | string | ❌ | 9:16 | 9:16, 16:9, 1:1, 2:3, 3:2 |
| reference_images | array | Tùy mode | [] | Tối đa 5 ảnh base64. Bắt buộc ≥1 cho i2i và i2v; bỏ qua với t2i/t2v |
| video_length | int | ❌ | 6 | 6 hoặc 10 giây — chỉ cho mode video (t2v/i2v) |
| resolution | string | ❌ | 480p | 480p hoặc 720p — chỉ cho mode video. Mode ảnh luôn xuất 1K |
Khác với image/video,
aspect_ratio là string và resolution Grok cũng là string (không phải array). Grok luôn tạo đúng 1 ảnh/video mỗi yêu cầu. Grok không hỗ trợ gắn ảnh bằng @tag (xem 7.7).7.6 Tạo Ảnh/Video Meta AI Qua API MỚI
POST /api/meta/generate
Một endpoint cho cả 4 chế độ Meta AI (backend nội bộ tên "vibes") — phân biệt bằng tham số mode. Ảnh tham chiếu truyền theo slot có tên (không dùng mảng reference_images).
| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
| prompt | string | ✅ | — | Mô tả nội dung |
| mode | string | ✅ | t2i | t2i, i2i, t2v, i2v — mode sai → tác vụ failed |
| aspect_ratio | string | ❌ | 9:16 | 9:16, 16:9, 1:1 |
| resolution | string | ❌ | 720p | 480p hoặc 720p — chỉ cho mode video (t2v/i2v). Mode ảnh luôn xuất 1K |
| count | int | ❌ | 1 | 1–4 kết quả mỗi prompt |
| character_image | string | i2i | — | base64 — thành phần chủ thể/nhân vật (mode i2i cần ≥1 trong 3 slot) |
| scene_image | string | i2i | — | base64 — thành phần bối cảnh (mode i2i) |
| style_image | string | i2i | — | base64 — thành phần phong cách (mode i2i) |
| start_image | string | i2v | — | base64 — khung hình đầu (bắt buộc cho mode i2v) |
| end_image | string | ❌ | — | base64 — khung hình cuối để nội suy (tùy chọn, mode i2v) |
Meta AI là trang Meta AI trong app (backend nội bộ tên "vibes", chạy trên vibes.ai). Cần tài khoản Meta (cookie
meta_session) đã bật trong app. Trang Meta AI trong app chỉ dành cho gói PLUS/MAX; Webhook API chỉ dành cho gói MAX. Mode ảnh (t2i/i2i) luôn 1K; mode video (t2v/i2v) hỗ trợ 480p/720p.7.7 Ảnh Tham Chiếu & Gắn Ảnh Bằng @tag
Mỗi phần tử trong reference_images có thể là:
// Dạng 1: Chuỗi base64 (data URI hoặc base64 thô) — PNG/JPG/WEBP
"reference_images": ["data:image/png;base64,iVBOR..."]
// Dạng 2: Object — kèm category và/hoặc name
"reference_images": [
{"data": "data:image/png;base64,...", "category": "subject", "name": "red_car.png"},
{"data": "data:image/jpeg;base64,...", "name": "house.jpg"}
]
category(tùy chọn):subject/scene/style— được chấp nhận nhưng bỏ qua với model Flow (chỉ dùng 1 slot ảnh chung)name(hoặcfilename, tùy chọn): tên file gốc của ảnh → cho phép gắn ảnh vào prompt bằng@tag- Giới hạn số ảnh: image = 10, grok = 5, video = 3 (Omni Flash components = 7). Phần dư bị bỏ qua
Gắn ảnh theo tên với @tag
Khi ảnh có name, bạn trỏ tới nó ngay trong prompt bằng @<từ khóa> — đúng cơ chế như trang Tạo Ảnh / Veo trong app.
- So khớp:
<từ khóa>là chuỗi con (không phân biệt hoa thường) của tên file (bỏ đuôi). VDname: "red_car.png"→@red_car,@car,@redđều trúng; ảnh xuất hiện đầu tiên trong danh sách thắng - Phạm vi: dùng cho ảnh (Flow) và video (Veo); Grok KHÔNG hỗ trợ
@tag - Tag không khớp giữ nguyên dạng văn bản — không gây lỗi
{
"prompt": "a @red_car parked next to a @house at night",
"reference_images": [
{"data": "data:image/png;base64,...", "name": "red_car.png"},
{"data": "data:image/jpeg;base64,...", "name": "house.jpg"}
]
}
7.8 Response & Trạng Thái
Khi gửi request thành công (202 Accepted)
{
"task_id": "abc12345",
"status": "pending",
"message": "Image task queued for processing",
"poll_url": "/api/status/abc12345"
}
Kiểm tra trạng thái: GET /api/status/{task_id}
| Trạng thái | Ý nghĩa |
|---|---|
pending | Đã nhận, đang chờ xử lý |
running | Đang tạo ảnh/video |
completed | Hoàn thành — có URL tải file trong results |
failed | Thất bại — xem error_code, error, error_detail |
Khi hoàn thành (completed)
{
"task_id": "abc12345",
"type": "image",
"status": "completed",
"prompt": "a cat ...",
"created_at": 1707782400.0,
"results": ["http://127.0.0.1:8765/api/files/image_001.png"],
"completed_at": 1707782460.0
}
Khi thất bại (failed)
{
"task_id": "abc12345",
"type": "image",
"status": "failed",
"error_code": 429,
"error": "Daily image quota exhausted (user@gmail.com)",
"error_detail": "429: Daily image quota exhausted (user@gmail.com)"
}
Bảng mã lỗi (error_code)
| error_code | Ý nghĩa | error điển hình |
|---|---|---|
429 | Hết quota ngày / rate-limit → nên nghỉ, xoay tài khoản, thử lại sau | thông báo quota (kèm email tài khoản) |
403 | Bị từ chối quyền / lỗi phiên | PERMISSION_DENIED |
400 | Yêu cầu sai / vi phạm chính sách prompt | INVALID_ARGUMENT |
500 | Lỗi máy chủ phía Google/xAI | INTERNAL / HTTP_500 |
0 | Lỗi xác thực đầu vào / môi trường | No active accounts available, Missing required field: prompt, mode Grok sai, upscale thất bại, timeout... |
Xử lý tự động nên rẽ nhánh theo
error_code (không phụ thuộc ngôn ngữ). error_code == 429 là tín hiệu để nghỉ / xoay tài khoản / thử lại sau.7.9 Ví Dụ Sử Dụng
Ví dụ 1: Tạo ảnh bằng cURL
# 1. Gửi yêu cầu tạo ảnh
curl -X POST http://127.0.0.1:8765/api/image/generate \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"prompt": "a golden retriever on a beach at sunset", "model": "nano_banana_2", "aspect_ratio": "16:9"}'
# → {"task_id":"abc12345","status":"pending","poll_url":"/api/status/abc12345"}
# 2. Poll cho đến khi completed
curl http://127.0.0.1:8765/api/status/abc12345 -H "X-API-Key: YOUR_API_KEY"
# 3. Tải ảnh kết quả (không cần API key)
curl -O http://127.0.0.1:8765/api/files/image_001.png
Ví dụ 2: Python (submit → poll → download)
import time, requests
BASE = "http://127.0.0.1:8765"
H = {"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"}
# Gửi yêu cầu
resp = requests.post(f"{BASE}/api/image/generate", json={
"prompt": "cyberpunk city at night, neon lights",
"model": "nano_banana_pro",
"aspect_ratio": "16:9",
"upscale": ["2K"]
}, headers=H)
task_id = resp.json()["task_id"]
# Poll cho đến khi xong
while True:
s = requests.get(f"{BASE}/api/status/{task_id}", headers=H).json()
if s["status"] == "completed":
for url in s["results"]:
data = requests.get(url).content # /api/files không cần key
open(url.split("/")[-1], "wb").write(data)
break
if s["status"] == "failed":
print(f"[{s['error_code']}] {s['error']}")
break
time.sleep(4)
Ví dụ 3: Video (ảnh đầu) + Grok (image-to-video)
# Veo — ảnh đầu + prompt, xuất 1080p
curl -X POST http://127.0.0.1:8765/api/video/generate \
-H "Content-Type: application/json" -H "X-API-Key: YOUR_API_KEY" \
-d '{"prompt":"flowing water, cinematic","mode":"start_image","reference_images":["data:image/png;base64,..."],"resolution":["1080p"]}'
# Grok — image-to-video, 720p, 6 giây
curl -X POST http://127.0.0.1:8765/api/grok/generate \
-H "Content-Type: application/json" -H "X-API-Key: YOUR_API_KEY" \
-d '{"prompt":"make it rain over the city","mode":"i2v","aspect_ratio":"16:9","resolution":"720p","reference_images":["data:image/png;base64,..."]}'
7.10 Nhật Ký Yêu Cầu
Mọi request đều được ghi lại trong bảng Request Log trên giao diện — gồm thời gian, endpoint, mã trạng thái, task ID và IP nguồn.
Server có watchdog: tác vụ kẹt ở trạng thái
running quá 15 phút sẽ tự động bị đánh dấu failed.