Qiklab API Documentation
Use the Qiklab REST API to generate AI images and videos programmatically.
Authentication
All API requests require an API key. Generate one from your account settings. Requires a minimum balance of $9.99.
Include your API key in the Authorization header:
Authorization: Bearer qkapi_{replace-with-your-api-key-here}Base URL
https://www.qiklab.com/api/v1Rate Limits
5 requests per second per API key. Exceeding this returns 429 Too Many Requests.
Endpoints
/api/v1/meGet your profile and balance.
Example Request
curl https://www.qiklab.com/api/v1/me \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}"Response
{
"username": "johndoe",
"email": "john@example.com",
"bio": "AI enthusiast",
"location": "San Francisco, CA",
"balance_cents": 999,
"balance_dollars": "9.99",
"created_at": "2026-03-15T12:00:00+00:00"
}/api/v1/generateStart a generation job.
Request Body (JSON)
| Parameter | Type | Required | Description |
|---|---|---|---|
| mode | string | Yes | t2i, i2i, t2v, i2v, t2i_pro, t2v_pro, i2v_pro, i2i_pro, i2i_pro_plus, motion, mm2v |
| positive_prompt | string | Yes | What to generate. Limits: mm2v 5..30000 chars; t2i_pro 10000 chars; t2v / i2v 5000 chars; t2v_pro / i2v_pro 4500 chars; t2i 4000 chars; motion 2500 chars; all other modes 1500 chars. mm2v supports inline reference tagging via @imageN, @audioN, @videoN in the multimodal_reference scenario. |
| negative_prompt | string | No | What to avoid (max 500 chars). Used by i2i, i2v_pro. Not used for t2i, t2i_pro, i2i_pro, i2i_pro_plus, motion, t2v, i2v, or t2v_pro (request will be rejected with 400). |
| resolution | string | No | t2i/i2i/i2i_pro: 1k, 2k, 4k. t2i_pro: 1k (default), 2k, 4k; the 27:16, 16:27, 9:8 and 8:9 aspect ratios support 1k only. t2v / i2v: 480p (default) or 720p. t2v_pro: 480P, 720P (default) or 1080P (either case accepted, sent uppercase). i2v_pro: 720p (default) or 1080p. motion: 720p or 1080p (default 720p). |
| orientation | string | No | i2i only: square, horizontal, vertical. Not used for t2i, t2i_pro, t2v, t2v_pro, i2v, i2v_pro, i2i_pro, i2i_pro_plus, or motion. |
| aspect_ratio | string | No | t2i: 1:1, 2:3, 3:2, 9:16, 16:9. t2i_pro: 1:1, 3:2, 2:3, 4:3, 3:4, 16:9, 9:16, 21:9, 27:16, 16:27, 9:8, 8:9 — REQUIRED for t2i_pro. i2i_pro/i2i_pro_plus: 1:1, 3:4, 4:3, 9:16, 16:9. t2v: 1:1, 2:3, 3:2, 9:16, 16:9 — REQUIRED for t2v. i2v: 1:1, 2:3, 3:2, 9:16, 16:9 — REQUIRED for i2v. t2v_pro: 1:1, 3:4, 4:3, 9:16, 16:9 (default 16:9). mm2v: adaptive (default; the model picks the shape), 1:1, 3:4, 4:3, 9:16, 16:9, 21:9. Not accepted for i2v_pro (output orientation comes from the input image). Default: 1:1 (where optional). |
| background | string | No | t2i_pro only: auto (default), transparent, or opaque. transparent returns a PNG with a transparent background. t2i_pro output is always PNG. Rejected with 400 on other modes. |
| duration | integer | No | Video duration in seconds. t2v / i2v / t2v_pro: any integer 6 to 30 (default 6). i2v_pro: any integer 2 to 15 (default 5). mm2v: any integer 5 to 30 (default 5). Not used for motion — duration is derived from the uploaded reference video. |
| image | string | No | Image for i2i / i2v_pro — accepts a public URL (http(s)://...) OR a base64-encoded payload (data URI prefix optional). Base64 is uploaded to S3 server-side. Required for i2i, i2v_pro. Not accepted on i2v non-pro (use `images` array). |
| images | string[] | No | Image URLs (or base64). i2i_pro / i2i_pro_plus: 1-12 (REQUIRED). i2v non-pro: 1-7 (REQUIRED). 15 MB max per image when base64. |
| last_frame_url | string | No | i2v_pro: optional second image to use as the closing frame of the generated video. Accepts a URL or base64 (same handling as `image`). Not accepted on i2v non-pro. |
| motion_image_upload_id | string | No | Motion mode only: reference-image upload handle returned by POST /api/v1/uploads/motion/image (required for motion). |
| motion_video_upload_id | string | No | Motion mode only: reference-video upload handle returned by POST /api/v1/uploads/motion/video (required for motion). |
| audio_upload_id | string | No | i2v_pro only: optional driving-audio upload handle returned by POST /api/v1/uploads/t2v/audio (lip-sync / audio-driven motion). Rejected with 400 on t2v_pro, which makes its own soundtrack (use generate_audio). |
| clip_upload_id | string | No | i2v_pro only: optional first-clip video upload handle returned by POST /api/v1/uploads/i2v/clip. The upstream model continues motion from the supplied clip (forwarded as `first_clip_url`). |
| scenario | string | No | mm2v / Compose only (REQUIRED for mm2v): one of text_only, first_frame, first_and_last_frame, multimodal_reference. Determines which input slots are valid — mixing slots across scenarios returns 400. Only multimodal_reference accepts inline @imageN / @audioN / @videoN tags in the prompt. |
| generate_audio | boolean | No | mm2v / Compose and t2v_pro: request a generated soundtrack in the output video. Default true. mm2v: forced false server-side when compose_audio_upload_ids is non-empty (uploaded audio overrides synthesis); the effective value is reflected in pricing (a +$0.05 surcharge applies when synthesis runs). t2v_pro: same price on or off. |
| compose_image_upload_ids | string[] | No | mm2v / Compose, multimodal_reference scenario only: 1..30 reference image upload handles from POST /api/v1/uploads/compose/image. Index in the array maps to the @imageN tag in the prompt. |
| compose_video_upload_ids | string[] | No | mm2v / Compose, multimodal_reference scenario only: 1..10 reference video upload handles from POST /api/v1/uploads/compose/video. Combined duration capped at 30 seconds across the array. |
| compose_audio_upload_ids | string[] | No | mm2v / Compose, multimodal_reference scenario only: 1..10 reference audio upload handles from POST /api/v1/uploads/compose/audio. Combined duration capped at 30 seconds. Audio without an image or video reference is rejected. |
| compose_first_frame_upload_id | string | No | mm2v / Compose, first_frame or first_and_last_frame scenarios only: first-frame image upload handle from POST /api/v1/uploads/compose/first-frame. |
| compose_last_frame_upload_id | string | No | mm2v / Compose, first_and_last_frame scenario only: last-frame image upload handle from POST /api/v1/uploads/compose/last-frame. |
Example Request (t2i)
Text-to-Image generates 4 images per request. The status response will include a result_urls array with all 4 image URLs.
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "t2i",
"positive_prompt": "A beautiful sunset over the ocean",
"aspect_ratio": "3:2"
}'Example Request (i2i)
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "i2i",
"positive_prompt": "Oil painting style, warm sunset tones",
"negative_prompt": "blurry, low quality",
"resolution": "1k",
"orientation": "square",
"image": "data:image/png;base64,iVBORw0KGgo..."
}'Example Request (t2i_pro)
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "t2i_pro",
"positive_prompt": "A photorealistic portrait, studio lighting",
"aspect_ratio": "2:3",
"resolution": "2k",
"background": "auto"
}'Example Request (t2v)
duration accepts any integer from 6 to 30 (default 6). aspect_ratio is required. negative_prompt is not supported on this mode and will be rejected with 400.
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "t2v",
"positive_prompt": "A drone shot flying over a mountain range",
"resolution": "480p",
"aspect_ratio": "16:9",
"duration": 6
}'Example Request (t2v_pro)
resolution is 480P, 720P (default) or 1080P. duration accepts any integer from 6 to 30 (default 6). generate_audio (default true) gives the video its own soundtrack; set it to false for a silent video. negative_prompt and audio_upload_id are not supported on this mode and will be rejected with 400.
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "t2v_pro",
"positive_prompt": "Cinematic slow-motion waves crashing on rocks",
"resolution": "720P",
"aspect_ratio": "16:9",
"duration": 10,
"generate_audio": true
}'Example Request (i2v)
images is required (1–7 entries; URLs or base64). aspect_ratio is required. duration accepts any integer 6–30 (default 6). negative_prompt, image (singular), and last_frame_url are not supported on this mode and will be rejected with 400.
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "i2v",
"positive_prompt": "A bird takes flight from the branch",
"resolution": "480p",
"aspect_ratio": "16:9",
"duration": 6,
"images": [
"https://example.com/bird-on-branch.jpg"
]
}'Example Request (i2v_pro)
Same payload shape as i2v; image accepts URL or base64. duration accepts any integer 2–15. audio_upload_id (driving audio) and clip_upload_id (first clip) are optional — see the upload helpers below.
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "i2v_pro",
"positive_prompt": "Camera slowly zooms in, cinematic motion",
"negative_prompt": "static, low resolution",
"resolution": "720p",
"duration": 8,
"image": "https://example.com/scene.jpg",
"clip_upload_id": "qiklabclp_eyJ1aWQiOiIuLi4ifQ.AbCdEf...",
"audio_upload_id": "qiklabaud_eyJ1aWQiOiIuLi4ifQ.GhIjKl..."
}'Example Request (motion)
Motion requires a two-step flow: first upload the reference image and reference video via the helpers below, then pass the two returned upload_id values here. Duration (and therefore pricing) is derived from the uploaded video — no duration field is accepted.
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "motion",
"positive_prompt": "The character dances gracefully",
"motion_image_upload_id": "qiklabimg_eyJ1aWQiOiIuLi4ifQ.AbCdEf...",
"motion_video_upload_id": "qiklabvid_eyJ1aWQiOiIuLi4ifQ.GhIjKl...",
"resolution": "720p"
}'Example Request (mm2v / Compose — Multimodal Reference)
Compose accepts text alone or any combination of image / video / audio reference inputs. Pick a scenario first — text_only, first_frame, first_and_last_frame, or multimodal_reference — and only the slots valid for that scenario are accepted. Inline reference tagging (@imageN, @audioN, @videoN) is supported in multimodal_reference.
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "mm2v",
"scenario": "multimodal_reference",
"positive_prompt": "Combine @image1 with @video1 and overlay @audio1 — cinematic slow-motion",
"aspect_ratio": "adaptive",
"resolution": "720p",
"duration": 8,
"generate_audio": false,
"compose_image_upload_ids": ["qiklabcmpi_..."],
"compose_video_upload_ids": ["qiklabcmpv_..."],
"compose_audio_upload_ids": ["qiklabcmpa_..."]
}'Example Request (mm2v / Compose — Text Only)
Text Only scenario: no input slots needed, just a prompt + scenario + the standard video controls. generate_audio defaults to true and adds a +$0.05 surcharge to the per-second rate.
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "mm2v",
"scenario": "text_only",
"positive_prompt": "A cinematic wide shot of a sailboat at sunset, slow camera dolly",
"aspect_ratio": "21:9",
"resolution": "1080p",
"duration": 12,
"generate_audio": true
}'Example Request (i2i_pro with URLs)
The images field accepts URLs or base64 strings (with or without data:image/png;base64, prefix). Base64 images are automatically uploaded and converted server-side.
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "i2i_pro",
"positive_prompt": "Recreate me perfectly in this pose",
"resolution": "1k",
"aspect_ratio": "3:4",
"images": [
"https://your-storage.com/photo1.jpg",
"https://your-storage.com/photo2.jpg"
]
}'Example Request (i2i_pro with base64)
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "i2i_pro",
"positive_prompt": "Recreate me perfectly in this pose",
"resolution": "1k",
"aspect_ratio": "3:4",
"images": [
"data:image/png;base64,iVBORw0KGgo...",
"/9j/4AAQSkZJRg..."
]
}'Both data:image/...;base64, prefixed and raw base64 strings are accepted. You can also mix URLs and base64 in the same request.
Example Request (i2i_pro_plus)
Pro+ variant uses a higher-quality model. Same parameters as i2i_pro but with mode: "i2i_pro_plus". Pricing: 1K = $0.20, 2K = $0.25, 4K = $0.30.
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "i2i_pro_plus",
"positive_prompt": "Recreate me perfectly in this pose",
"resolution": "2k",
"aspect_ratio": "3:4",
"images": [
"https://your-storage.com/photo1.jpg",
"https://your-storage.com/photo2.jpg"
]
}'Example Request (i2i_pro_plus with base64)
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-H "Content-Type: application/json" \
-d '{
"mode": "i2i_pro_plus",
"positive_prompt": "Recreate me perfectly in this pose",
"resolution": "2k",
"aspect_ratio": "3:4",
"images": [
"data:image/png;base64,iVBORw0KGgo...",
"/9j/4AAQSkZJRg..."
]
}'Both data:image/...;base64, prefixed and raw base64 strings are accepted. You can also mix URLs and base64 in the same request.
Response
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "QUEUED",
"kind": "Image"
}kind is one of Image, Video, or Audio — derived from the request mode. Use it to decide how to render the eventual result_url.
/api/v1/uploads/motion/imageUpload a reference image for motion mode. Returns a signed upload handle.
Motion is a two-step flow. First upload the reference image and reference video through these helpers; both endpoints return an upload_id that you pass back to POST /api/v1/generate with mode=motion. Handles are valid for 24 hours.
Request Body (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | JPEG or PNG, max 10 MB, minimum dimension > 340 px, aspect ratio 2:5 to 5:2. |
Example Request
curl -X POST https://www.qiklab.com/api/v1/uploads/motion/image \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-F "file=@/path/to/reference.jpg"Response
{
"status": "success",
"data": {
"upload_id": "qiklabimg_eyJ1aWQiOiIuLi4ifQ.AbCdEf...",
"expires_at": "2026-04-18T17:00:00Z",
"width": 1024,
"height": 1024,
"size_bytes": 845221
}
}/api/v1/uploads/motion/videoUpload a reference video for motion mode. Returns a signed upload handle with duration.
Request Body (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | MP4 or MOV, max 100 MB, duration 3-30 s, minimum dimension > 340 px, aspect ratio 2:5 to 5:2. |
The video's duration drives motion pricing and is baked into the signed upload handle — you don't need to pass it back separately.
Example Request
curl -X POST https://www.qiklab.com/api/v1/uploads/motion/video \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-F "file=@/path/to/reference.mp4"Response
{
"status": "success",
"data": {
"upload_id": "qiklabvid_eyJ1aWQiOiIuLi4ifQ.GhIjKl...",
"expires_at": "2026-04-18T17:00:00Z",
"duration_seconds": 8,
"width": 1920,
"height": 1080,
"size_bytes": 34215441
}
}Example: end-to-end motion generation
Upload the reference image, upload the reference video, then call POST /api/v1/generate with mode=motion and the two returned handles. Poll GET /api/v1/status/{job_id} until completion.
# 1) Upload the reference image
IMG=$(curl -s -X POST https://www.qiklab.com/api/v1/uploads/motion/image \
-H "Authorization: Bearer qkapi_..." \
-F "file=@reference.jpg" | jq -r .data.upload_id)
# 2) Upload the reference video
VID=$(curl -s -X POST https://www.qiklab.com/api/v1/uploads/motion/video \
-H "Authorization: Bearer qkapi_..." \
-F "file=@reference.mp4" | jq -r .data.upload_id)
# 3) Start the motion generation job
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_..." \
-H "Content-Type: application/json" \
-d "{
\"mode\": \"motion\",
\"positive_prompt\": \"The character dances gracefully.\",
\"motion_image_upload_id\": \"$IMG\",
\"motion_video_upload_id\": \"$VID\",
\"resolution\": \"720p\"
}"Motion is billed per second of the uploaded reference video's duration — 720p is $0.15/s and 1080p is $0.20/s. A 10-second clip at 720p costs $1.50.
/api/v1/uploads/t2v/audioUpload an audio file for use as an i2v_pro driving-audio input. Returns a signed upload handle.
Request Body (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | MP3, WAV, AAC, M4A (audio/mp4), or OGG. Max 50 MB. |
The returned upload_id is passed back to POST /api/v1/generate as audio_upload_id for mode=i2v_pro (forwarded as driving_audio_url). Handles are valid for 24 hours.
Example Request
curl -X POST https://www.qiklab.com/api/v1/uploads/t2v/audio \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-F "file=@/path/to/track.mp3"Response
{
"status": "success",
"data": {
"upload_id": "qiklabaud_eyJ1aWQiOiIuLi4ifQ.AbCdEf...",
"expires_at": "2026-04-26T17:00:00Z",
"size_bytes": 4823104,
"content_type": "audio/mpeg"
}
}/api/v1/uploads/i2v/clipUpload a short video clip for use as an i2v_pro first-clip input. Returns a signed upload handle.
Request Body (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | MP4, MOV (video/quicktime), or MKV (video/x-matroska). Max 30 MB. |
The returned upload_id is passed back to POST /api/v1/generate as clip_upload_id for mode=i2v_pro. The upstream model continues motion from the supplied clip (forwarded as first_clip_url). Handles are valid for 24 hours.
Example Request
curl -X POST https://www.qiklab.com/api/v1/uploads/i2v/clip \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}" \
-F "file=@/path/to/clip.mp4"Response
{
"status": "success",
"data": {
"upload_id": "qiklabclp_eyJ1aWQiOiIuLi4ifQ.AbCdEf...",
"expires_at": "2026-04-27T17:00:00Z",
"size_bytes": 12582912,
"content_type": "video/mp4"
}
}/api/v1/uploads/compose/imageUpload one reference image for Compose / mm2v. Returns a signed upload handle.
Request Body (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | JPEG, PNG, WEBP, BMP, TIFF, or GIF. <30 MB. Width and height each in (300, 6000) pixels (open interval). Aspect ratio in (0.4, 2.5). |
Pass back as one entry in compose_image_upload_ids (array, 1..30) on POST /api/v1/generate with mode=mm2v, scenario=multimodal_reference. Index in the array maps to the @imageN tag in the prompt (1-indexed).
/api/v1/uploads/compose/videoUpload one reference video for Compose / mm2v. Returns a signed upload handle with duration.
Request Body (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | MP4 or MOV. ≤200 MB. Per-file duration [2, 30]s. FPS [24, 60]. Resolution 480p or 720p. Width and height each in [300, 6000]; total pixels in [409,600, 927,408]. |
Pass back in compose_video_upload_ids (array, 1..10). Combined duration across the array is capped at 30 seconds (re-summed at /generate time from the signed handles — tampering rejected).
/api/v1/uploads/compose/audioUpload one reference audio file for Compose / mm2v. Returns a signed upload handle with duration.
Request Body (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | MP3, WAV, or MP4 audio (audio/mp4; converted to MP3 on upload). ≤15 MB per file. Per-file duration [2, 30]s. |
Pass back in compose_audio_upload_ids (array, 1..10). Combined duration across the array is capped at 30 seconds. Audio without an image or video reference in the same request is rejected.
/api/v1/uploads/compose/first-frameUpload the first-frame image for Compose. Returns a signed upload handle.
Request Body (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | JPEG, PNG, WEBP, BMP, or GIF (TIFF NOT accepted on frame slots, even though it is on reference images). ≤30 MB. Same dimensional bounds as the reference image array. |
Pass back as compose_first_frame_upload_id on POST /api/v1/generate with scenario=first_frame or first_and_last_frame.
/api/v1/uploads/compose/last-frameUpload the last-frame image for Compose (first_and_last_frame scenario only). Returns a signed upload handle.
Request Body (multipart/form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | Same MIME allowlist + bounds as /api/v1/uploads/compose/first-frame (no TIFF, ≤30 MB). |
Pass back as compose_last_frame_upload_id on POST /api/v1/generate with scenario=first_and_last_frame.
Example: i2v_pro with first clip + driving audio
Upload the clip + audio (independent, optional), then call POST /api/v1/generate with mode=i2v_pro + the reference image + both handles. Duration is your slider value (any integer 2–15).
# 1) (optional) Upload the first-clip video
CLP=$(curl -s -X POST https://www.qiklab.com/api/v1/uploads/i2v/clip \
-H "Authorization: Bearer qkapi_..." \
-F "file=@first-clip.mp4" | jq -r .data.upload_id)
# 2) (optional) Upload the driving audio
AUD=$(curl -s -X POST https://www.qiklab.com/api/v1/uploads/t2v/audio \
-H "Authorization: Bearer qkapi_..." \
-F "file=@track.mp3" | jq -r .data.upload_id)
# 3) Start the i2v_pro generation job
curl -X POST https://www.qiklab.com/api/v1/generate \
-H "Authorization: Bearer qkapi_..." \
-H "Content-Type: application/json" \
-d "{
\"mode\": \"i2v_pro\",
\"positive_prompt\": \"The character takes a deep breath and starts to dance.\",
\"resolution\": \"720p\",
\"duration\": 10,
\"image\": \"https://example.com/scene.jpg\",
\"clip_upload_id\": \"$CLP\",
\"audio_upload_id\": \"$AUD\"
}"/api/v1/status/{job_id}Check the status of a generation job.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| job_id | string | Yes | The job_id returned from /generate |
Example Request
curl https://www.qiklab.com/api/v1/status/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}"Response (in progress)
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "IN_PROGRESS"
}Response (processing)
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "PROCESSING"
}PROCESSING means the generation is done but the result is being prepared. Continue polling.
Response (completed)
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "COMPLETED",
"result_url": "https://...",
"expires_at": 1738128502
}result_url is a time-limited signed URL. expires_at is the Unix epoch (seconds, UTC) when the signature stops working — safe to cache the URL until then. Download the file before then.
Response (failed)
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "FAILED",
"error": "Generation failed"
}/api/v1/balanceCheck your current account balance.
Example Request
curl https://www.qiklab.com/api/v1/balance \
-H "Authorization: Bearer qkapi_{replace-with-your-api-key-here}"Response
{
"balance_cents": 999,
"balance_dollars": "9.99"
}Pricing
Each generation deducts from your wallet balance. Prices vary by mode, resolution, and duration.
| Mode | Starting Price |
|---|---|
| t2i (1k) | $0.05 |
| i2i (1k) | $0.05 |
| t2i_pro (1k) | $0.07 |
| t2i_pro (2k) | $0.10 |
| t2i_pro (4k) | $0.12 |
| i2i_pro (1k) | $0.15 |
| i2i_pro_plus (1k) | $0.20 |
| t2v (480p, per second) | $0.02/s — e.g. 6s $0.12 / 15s $0.30 / 30s $0.60 |
| t2v (720p, per second) | $0.04/s — e.g. 6s $0.24 / 15s $0.60 / 30s $1.20 |
| i2v (480p, per second) | $0.02/s — e.g. 6s $0.12 / 15s $0.30 / 30s $0.60 |
| i2v (720p, per second) | $0.04/s — e.g. 6s $0.24 / 15s $0.60 / 30s $1.20 |
| t2v_pro (480P, per second) | $0.06/s — e.g. 6s $0.36 / 15s $0.90 / 30s $1.80 |
| t2v_pro (720P, per second) | $0.10/s — e.g. 6s $0.60 / 15s $1.50 / 30s $3.00 |
| t2v_pro (1080P, per second) | $0.18/s — e.g. 6s $1.08 / 15s $2.70 / 30s $5.40 |
| i2v_pro (720p) — 2s / 5s / 10s / 15s | $0.83 / $0.99 / $1.25 / $1.75 |
| i2v_pro (1080p) — 2s / 5s / 10s / 15s | $0.83 / $0.99 / $1.75 / $2.50 |
| motion (720p, per second) | $0.15/s |
| motion (1080p, per second) | $0.20/s |
| mm2v / Compose (480p, with reference video, per second) | $0.10/s |
| mm2v / Compose (480p, no reference video, per second) | $0.15/s |
| mm2v / Compose (720p, with reference video, per second) | $0.15/s |
| mm2v / Compose (720p, no reference video, per second) | $0.25/s |
| mm2v / Compose (1080p, with reference video, per second) | $0.35/s |
| mm2v / Compose (1080p, no reference video, per second) | $0.55/s |
| mm2v / Compose — generate_audio surcharge* (when no reference audio uploaded) | +$0.05 flat* |
mm2v / Compose duration is 5–30 seconds. Range: $0.50 (480p × 5s with reference video, no synthesized audio) up to $16.55 (1080p × 30s without reference video, with synthesized audio).
* The generate_audio surcharge of $0.05 is current at the time of writing and may change in the future. The live cost shown in the Studio and the amount actually charged are always authoritative.
Error Codes
| Code | Meaning |
|---|---|
| 400 | Bad request (invalid parameters) |
| 401 | Invalid or missing API key |
| 402 | Insufficient balance |
| 403 | Account banned |
| 404 | Job not found |
| 429 | Rate limit exceeded (5 req/s) |
| 502 | Generation service error |