📡 Webhook API — Integration Guide
Base URL: http://127.0.0.1:8765 (localhost only) · Auth: API Key via X-API-Key header · License: MAX
Full per-endpoint parameters are in the Webhook API section (User Guide). The API is asynchronous: submit → poll
/api/status → download files. Up to 10 tasks run concurrently; tasks live in memory (lost on app restart).Detailed reference to hand to an AI for fast integration: WEBHOOK_INTEGRATION.en.md · WEBHOOK_INTEGRATION.vi.md
🔑 Authentication
All endpoints (except /api/health and /api/files/*) require an API key header:
text
X-API-Key: YOUR_API_KEYThe API key (32-byte URL-safe token) is auto-generated in Settings → Webhook. You can regenerate it anytime.
json
{
"error": "Invalid or missing API key"
}📡 Endpoints
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET | /api/health | ❌ | Server health |
POST | /api/image/generate | ✅ | Generate image (Flow — Nano Banana) |
POST | /api/video/generate | ✅ | Generate video (Veo) |
POST | /api/grok/generate | ✅ | Generate Grok image/video (T2I/I2I/T2V/I2V) NEW |
POST | /api/meta/generate | ✅ | Generate Meta AI image/video (T2I/I2I/T2V/I2V) NEW |
GET | /api/status/{task_id} | ✅ | Check status |
GET | /api/result/{task_id} | ✅ | Get result |
GET | /api/tasks | ✅ | List 50 most recent tasks |
GET | /api/files/{filename} | ❌ | Download binary file |
1. Image — POST /api/image/generate
| Field | Type | Default | Description |
|---|---|---|---|
prompt | string | — (required) | Image description |
model | string | nano_banana_2 | nano_banana_2, nano_banana_pro or nano_banana_2_lite (unknown → nano_banana_2) |
aspect_ratio | string | 1:1 | 1:1, 3:4, 4:3, 9:16, 16:9 |
reference_images | array | [] | Up to 10 base64 images or objects |
upscale | array | [] | ["2K"], ["4K"] (4K requires an Ultra account) |
2. Video — POST /api/video/generate
| Field | Type | Default | Description |
|---|---|---|---|
prompt | string | — (required) | Motion description |
model | string | veo_31_fast | veo_31_fast, veo_31_lite, veo_31_quality, veo_31_lite_relaxed (Ultra), omni_flash |
mode | string | text_to_video | text_to_video, start_image, start_end_image, components |
aspect_ratio | string | 16:9 | 16:9, 9:16 |
resolution | array | ["720p"] | 720p, 1080p, 4K (only 4K requires Ultra) |
reference_images | array | [] | Required when mode ≠ text. Max 3 (Veo), 7 (Omni Flash) |
voice | string | "" | Voice name — components mode only |
video_length | int | 8 | Seconds. Veo: 4/6/8 (4/6 require Ultra). Omni Flash: 4/6/8/10 |
veo_31_fast_relaxed is no longer valid (falls back to veo_31_fast). Omni Flash does not support start_end_image.3. Grok — POST /api/grok/generate NEW
| Field | Type | Default | Description |
|---|---|---|---|
prompt | string | — (required) | Content description |
mode | string | t2v | t2i, i2i, t2v, i2v (invalid mode → failed) |
aspect_ratio | string | 9:16 | 9:16, 16:9, 1:1, 2:3, 3:2 |
reference_images | array | [] | Up to 5; required for i2i & i2v |
video_length | int | 6 | 6 or 10 (video modes only) |
resolution | string | 480p | 480p or 720p (video modes only; images always 1K) |
4. Meta AI — POST /api/meta/generate NEW
| Field | Type | Default | Description |
|---|---|---|---|
prompt | string | — (required) | Content description |
mode | string | t2i | t2i, i2i, t2v, i2v (invalid mode → failed) |
aspect_ratio | string | 9:16 | 9:16, 16:9, 1:1 |
resolution | string | 720p | 480p or 720p (video modes only; images always 1K) |
count | int | 1 | 1–4 outputs per prompt |
character_image / scene_image / style_image | string | — | base64 — components for i2i mode (≥1 required) |
start_image / end_image | string | — | base64 — start frame (required) / end frame (optional) for i2v mode |
Meta AI needs a separate Meta account (the vibes.ai
meta_session cookie). The Meta AI page in the app is PLUS/MAX only; reference images are passed as named slots, not the reference_images array.Reference images & @tag
json
"reference_images": [
"data:image/png;base64,...",
{"data": "base64...", "category": "subject", "name": "red_car.png"}
]category (subject/scene/style) is ignored for Flow models. When an image has a name, point at it in the prompt with @tag (substring of filename) — works for image & video (Veo) only, Grok & Meta AI do not support it.
5–8: Status, Result, Tasks, Files
text
GET /api/status/{task_id} — Check task status
GET /api/result/{task_id} — Get result
GET /api/tasks — List tasks (max 50)
GET /api/files/{filename} — Download binary fileStatus values: pending → running → completed / failed
🔄 Polling Pattern
Since generation takes time, poll (suggested every 3–5 seconds):
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": "a futuristic city at sunset",
"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 needs no key
open(url.split("/")[-1], "wb").write(data)
break
if s["status"] == "failed":
print(s["error_code"], s["error"])
break
time.sleep(4)🔗 Integration Examples
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 Quick Test
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⚠️ Error Codes
| HTTP Code | Meaning |
|---|---|
202 | Task accepted (queued) |
400 | Empty body / invalid JSON |
401 | Invalid or missing API key |
404 | Task/file/endpoint not found |
500 | File read error |
When a task is failed, the status response carries an error_code:
| error_code | Meaning |
|---|---|
429 | Quota / rate limit → back off, rotate accounts, retry |
403 | PERMISSION_DENIED / session issue |
400 | Invalid request / prompt policy violation |
500 | Upstream Google/xAI/Meta error |
0 | Validation error (missing prompt, no accounts, invalid Grok/Meta mode, timeout...) |