Async & Webhook Integration Snippets
Copy-paste examples for the CreativeAI video generation API. Submit jobs, poll for status, or receive webhook callbacks β in Python, Node.js, and cURL.
How Async Video Generation Works
1. Submit Job
POST /v1/video/generations returns 202 immediately with a generation ID.
2. Processing
CreativeAI processes your video (30sβ3min). Auto-failover handles provider issues.
3a. Webhook Callback
If you provided webhook_url, we POST the result to your server with HMAC signature.
3b. Poll Status
Or poll GET /v1/video/generations/{id} until status is completed or failed.
4. Retrieve Result
output_url contains your video. Download it, store it, or serve it to users.
1. Create Job with Webhook
Submit a video generation and receive the result via webhook callback. Returns 202 Accepted immediately.
import httpx
API_KEY = "rph_live_..."
BASE = "https://api.creativeai.run"
resp = httpx.post(
f"{BASE}/v1/video/generations",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "seedance-1.5-pro", # or "kling-v3", "auto"
"prompt": "A golden retriever running on the beach at sunset",
"aspect_ratio": "16:9",
"duration": 5,
"webhook_url": "https://your-server.com/webhooks/creativeai",
},
)
data = resp.json()
print(f"Job created: {data['id']} status={data['status']}")
# β Job created: gen_abc123 status=pending2. Create Job for Polling
Submit without webhook_url and poll for the result instead. Same endpoint, just omit the webhook field.
resp = httpx.post(
f"{BASE}/v1/video/generations",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "auto", # auto-selects best provider
"prompt": "Timelapse of a flower blooming in a garden",
"aspect_ratio": "9:16",
"duration": 5,
},
)
generation_id = resp.json()["id"]
print(f"Polling mode β track: {generation_id}")3. Poll for Status
Poll GET /v1/video/generations/{id} until the status reaches completed or failed. Recommended poll interval: 5 seconds.
import time
def poll_until_done(generation_id: str, timeout: int = 600) -> dict:
"""Poll GET /v1/video/generations/{id} until terminal state."""
start = time.time()
while time.time() - start < timeout:
resp = httpx.get(
f"{BASE}/v1/video/generations/{generation_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
)
data = resp.json()
status = data["status"]
if status == "completed":
print(f"Done! Video URL: {data['output_url']}")
return data
elif status == "failed":
raise Exception(f"Generation failed: {data.get('error')}")
# Still processing β wait before next poll
print(f" status={status} β waiting 5s...")
time.sleep(5)
raise TimeoutError(f"Generation {generation_id} timed out after {timeout}s")
result = poll_until_done(generation_id)4. Webhook Callback Handler
Receive and verify webhook notifications with HMAC-SHA256 signature validation.
"""Flask / FastAPI webhook receiver with HMAC-SHA256 verification."""
import hmac, hashlib, json
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
WEBHOOK_SECRET = "your-api-key" # use your API key as signing secret
@app.post("/webhooks/creativeai")
async def handle_creativeai_webhook(request: Request):
body = await request.body()
# 1. Verify HMAC-SHA256 signature
signature = request.headers.get("X-CreativeAI-Signature", "")
expected = "sha256=" + hmac.new(
WEBHOOK_SECRET.encode(), body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
raise HTTPException(status_code=401, detail="Invalid signature")
# 2. Parse the payload
payload = json.loads(body)
gen_id = payload["id"] # e.g. "gen_abc123"
status = payload["status"] # "completed" or "failed"
model = payload["model"] # requested model name
event = request.headers.get("X-CreativeAI-Event")
# β "video.generation.completed"
# 3. Handle the result
if status == "completed":
video_url = payload["output_url"]
credits = payload["credits"]
print(f"Video ready: {video_url} ({credits} credits)")
# β download, store, notify user, etc.
else:
error = payload["error_message"]
print(f"Generation {gen_id} failed: {error}")
# β alert, retry, etc.
return {"received": True}5. End-to-End Example
Complete production pattern: submit with webhook, auto-failover enabled, and auto model selection.
"""Complete async video generation with webhook β production pattern."""
import httpx
API_KEY = "rph_live_..."
BASE = "https://api.creativeai.run"
# Step 1: Submit job with webhook
resp = httpx.post(
f"{BASE}/v1/video/generations",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "auto",
"prompt": "Drone shot over a misty mountain valley at sunrise",
"aspect_ratio": "21:9",
"duration": 5,
"resolution": "1080p",
"webhook_url": "https://your-app.com/webhooks/creativeai",
"failover": True, # auto-retry on alternate provider if primary fails
},
)
resp.raise_for_status()
job = resp.json()
print(f"Submitted: id={job['id']} model={job['model_actual']} "
f"credits={job['credits']} failover={job['failover_used']}")
# Step 2: Your webhook handler receives the result asynchronously.
# No polling needed β just handle the POST to your webhook_url.
#
# Or, if you prefer polling, omit webhook_url and use:
# GET /v1/video/generations/{job['id']}
# until status is "completed" or "failed".Webhook Reference
Details about the webhook delivery your server will receive.
Headers
| Header | Description |
|---|---|
| X-CreativeAI-Signature | HMAC-SHA256 signature: sha256=<hex> |
| X-CreativeAI-Event | Always video.generation.completed |
| X-CreativeAI-Delivery-Id | The generation ID (for deduplication) |
| User-Agent | CreativeAI-Webhooks/1.0 |
Payload Fields
| Field | Type | Description |
|---|---|---|
| id | string | Generation ID |
| object | string | Always "video.generation" |
| status | string | "completed" or "failed" |
| model | string | Model you requested |
| model_actual | string | Provider that fulfilled the request |
| prompt | string | Your original prompt |
| output_url | string | null | Video URL (null on failure) |
| error_message | string | null | Error details (null on success) |
| credits | integer | Credits charged |
| failover_used | boolean | Whether a fallback provider was used |
| completed_at | string | ISO 8601 timestamp |
Delivery Behavior
- Your endpoint must respond with 2xx within 10 seconds
- 3 retry attempts with exponential backoff (0s, 5s, 30s)
- Idempotent delivery β same generation + status won't be sent twice (7-day window)
- Signature uses your API key as the HMAC secret
Ready to Build?
Get an API key and start generating videos in under 2 minutes.