Runway's Gen-4.5 text- and image-to-video model.
# 1 · start the render
curl https://www.ninjachat.ai/api/v1/videos \
-H "Authorization: Bearer $NINJACHAT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "runway-gen4.5", "prompt": "a paper boat drifting down a neon rain stream", "duration": 8, "aspect_ratio": "16:9" }'
# 2 · poll until it is ready
curl "https://www.ninjachat.ai/api/v1/videos/JOB_ID" \
-H "Authorization: Bearer $NINJACHAT_API_KEY"Each request below is generated from what Runway Gen-4.5 serves on NinjaChat today — the same capabilities and parameters that GET /models reports — so it runs as written with your key.
Rendering takes minutes, so the API returns a job id and you poll it until the file is ready.
# export NINJACHAT_API_KEY="nj_sk_..." (Developers → Keys)
curl https://www.ninjachat.ai/api/v1/videos \
-H "Authorization: Bearer $NINJACHAT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "runway-gen4.5",
"prompt": "a paper boat drifting down a neon rain stream, slow dolly-in",
"duration": 5,
"aspect_ratio": "16:9"
}'
# → { "id": "JOB_ID", "status": "processing" }
curl https://www.ninjachat.ai/api/v1/videos/JOB_ID \
-H "Authorization: Bearer $NINJACHAT_API_KEY"
# → { "id": "JOB_ID", "status": "completed", "video_url": "https://..." }POST /videos charges the flat per-video price up front and returns a job. GET /videos/{id} reports processing, then completed with video_url, or failed — a failed render is refunded automatically.duration is in seconds; this model accepts 4–10 seconds. aspect_ratio is 16:9 or 9:16.Start from a photo or a generated frame and let the prompt describe the motion.
# export NINJACHAT_API_KEY="nj_sk_..." (Developers → Keys)
curl https://www.ninjachat.ai/api/v1/videos \
-H "Authorization: Bearer $NINJACHAT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "runway-gen4.5",
"prompt": "the camera pulls back slowly as steam rises from the cup",
"image_url": "https://example.com/espresso.jpg",
"duration": 5,
"aspect_ratio": "16:9"
}'image_url becomes the first frame. Write the prompt as motion and camera direction — the image already fixes subject and composition.POST /images/generations can be passed straight through.Register an HTTPS endpoint once and receive a signed event when each render finishes or fails.
# export NINJACHAT_API_KEY="nj_sk_..." (Developers → Keys)
curl https://www.ninjachat.ai/api/v1/webhooks \
-H "Authorization: Bearer $NINJACHAT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://example.com/hooks/ninjachat", "events": ["video.completed", "video.failed"] }'
# → { "id": "...", "secret": "whsec_..." } (the secret is shown once)
curl https://www.ninjachat.ai/api/v1/videos \
-H "Authorization: Bearer $NINJACHAT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "runway-gen4.5", "prompt": "a paper boat drifting down a neon rain stream", "duration": 5 }'
# your endpoint receives POST { "type": "video.completed", "data": { "id": "...", "video_url": "..." } }{timestamp}.{rawBody} with the endpoint's secret, sent as X-Ninja-Signature next to X-Ninja-Timestamp. Verify against the raw request body, not a re-serialized copy.POST /webhooks/test sends one synthetic event to check the wiring before a real render.secret rule applies.