{"openapi":"3.1.0","info":{"title":"KinoGenie API","version":"0.4.0","description":"Generate short video clips with native audio from a text prompt or a start frame through a simple API, MCP server or n8n node. MiniMax H3, 480p or 768p, flat per-second pricing."},"servers":[{"url":"https://kinogenie.com"}],"security":[{"bearerAuth":[]}],"paths":{"/api/v1/uploads":{"post":{"operationId":"createMediaUpload","summary":"Create a direct media upload","description":"Returns a short-lived signed multipart upload policy. Submit the returned fields and file, then use mediaUrl as a job input.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectUploadRequest"}}}},"responses":{"201":{"description":"A direct upload was created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectUploadResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"503":{"$ref":"#/components/responses/QueueUnavailable"}}}},"/api/v1/jobs":{"get":{"operationId":"listVideoEdits","summary":"List recent video editing jobs","description":"Newest first. A cheap authenticated read: integrations use it to validate an API key without creating anything.","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"The most recent jobs for this account.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/JobStatus"}}}}}}},"401":{"description":"Missing or invalid API key."}}},"post":{"operationId":"createVideoEdit","summary":"Create a video editing job","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRequest"}}}},"responses":{"200":{"description":"An existing idempotent job was returned."},"202":{"description":"The edit was accepted for asynchronous processing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptedJob"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/InsufficientCredits"},"409":{"description":"The Idempotency-Key was already used for a different request."},"503":{"$ref":"#/components/responses/QueueUnavailable"}}}},"/api/v1/jobs/{jobId}":{"get":{"operationId":"getVideoEdit","summary":"Read a video editing job","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Current job state, including the output when it has succeeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatus"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"The job was not found for this account."}}}},"/api/v1/tools/{slug}":{"post":{"operationId":"runVideoTool","summary":"Run a ready-made video editing tool","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","enum":["minimax-h3","generate-video"]}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolRequest"}}}},"responses":{"200":{"description":"An existing idempotent tool run was returned."},"202":{"description":"The tool run was accepted for asynchronous processing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptedJob"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/InsufficientCredits"},"404":{"description":"The requested tool is not executable."},"409":{"description":"The Idempotency-Key was already used for a different request."},"503":{"$ref":"#/components/responses/QueueUnavailable"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A KinoGenie API key beginning with kp_live_."}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Reuse a stable value when retrying the same edit.","schema":{"type":"string","maxLength":160}}},"schemas":{"DirectUploadRequest":{"type":"object","required":["filename","contentType","byteSize"],"properties":{"filename":{"type":"string","minLength":1,"maxLength":180},"contentType":{"type":"string","minLength":1,"maxLength":120,"example":"video/mp4"},"byteSize":{"type":"integer","minimum":1,"maximum":314572800}}},"DirectUploadResponse":{"type":"object","required":["ok","upload"],"properties":{"ok":{"const":true},"upload":{"type":"object","required":["uploadUrl","mediaUrl","method","fields","uploadExpiresAt","mediaExpiresAt"],"properties":{"objectKey":{"type":"string"},"uploadUrl":{"type":"string","format":"uri","description":"Signed storage form target valid for 15 minutes."},"mediaUrl":{"type":"string","format":"uri","description":"Signed input URL valid for 24 hours."},"method":{"const":"POST"},"fields":{"type":"object","additionalProperties":{"type":"string"},"description":"Append every field to multipart form data before the file."},"headers":{"type":"object","additionalProperties":{"type":"string"}},"uploadExpiresAt":{"type":"string","format":"date-time"},"mediaExpiresAt":{"type":"string","format":"date-time"}}}}},"JobRequest":{"type":"object","required":[],"properties":{"name":{"type":"string","maxLength":120,"default":"Untitled job"},"inputs":{"type":"array","minItems":0,"maxItems":6,"description":"Unused: generation takes no media inputs. Send an empty array or omit it.","items":{"$ref":"#/components/schemas/MediaInput"}},"operations":{"type":"array","maxItems":1,"items":{"oneOf":[{"$ref":"#/components/schemas/GenerateVideoOperation"},{"$ref":"#/components/schemas/GenerateImageOperation"}]},"default":[],"minItems":1},"output":{"$ref":"#/components/schemas/Output"},"webhook":{"$ref":"#/components/schemas/Webhook"},"maxCredits":{"type":"integer","minimum":1,"maximum":720,"description":"Optional hard ceiling for billable credits. Successful jobs use the greater of rounded-up worker seconds or rounded-up 6 MiB output units. The full amount is reserved before enqueue and unused credits are refunded after success."}}},"ToolRequest":{"type":"object","required":[],"properties":{"inputs":{"type":"array","minItems":0,"maxItems":6,"description":"Unused: generation takes no media inputs. Send an empty array or omit it.","items":{"$ref":"#/components/schemas/MediaInput"}},"options":{"oneOf":[{"$ref":"#/components/schemas/GenerateVideoOptions"},{"$ref":"#/components/schemas/GenerateImageOptions"}]},"webhook":{"$ref":"#/components/schemas/Webhook"},"maxCredits":{"type":"integer","minimum":1,"maximum":720,"description":"Optional hard ceiling for billable credits. Successful jobs use the greater of rounded-up worker seconds or rounded-up 6 MiB output units. The full amount is reserved before enqueue and unused credits are refunded after success."}}},"MediaInput":{"type":"object","required":["id","url"],"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_-]*$","maxLength":40,"description":"A stable name used by operations to reference this input."},"url":{"type":"string","format":"uri","description":"A public HTTP(S) URL or the mediaUrl returned by POST /api/v1/uploads."},"filename":{"type":"string","maxLength":180}}},"OverlayPosition":{"type":"string","enum":["top-left","top-right","bottom-left","bottom-right","center"],"default":"bottom-right"},"Output":{"type":"object","properties":{"format":{"type":"string","enum":["mp4","webm","mp3","wav","jpg","webp","gif"],"default":"mp4"},"quality":{"type":"string","enum":["fast","balanced","quality"],"default":"balanced"}}},"Webhook":{"type":"object","required":["url","secret"],"properties":{"url":{"type":"string","format":"uri","description":"A public HTTPS endpoint using the default port."},"secret":{"type":"string","minLength":16,"maxLength":256,"writeOnly":true,"description":"Used to sign X-KinoPipe-Signature with HMAC-SHA256."},"events":{"type":"array","minItems":1,"maxItems":2,"items":{"type":"string","enum":["job.succeeded","job.failed"]},"default":["job.succeeded","job.failed"]}}},"Job":{"type":"object","required":["id","status","progress"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["queued","processing","succeeded","failed","canceled"]},"progress":{"type":"integer","minimum":0,"maximum":100},"consumedCredits":{"type":"integer","minimum":0},"reservedCredits":{"type":"integer","minimum":0,"description":"Credits reserved for this job before it was enqueued."},"maxCredits":{"type":["integer","null"],"minimum":1,"maximum":720,"description":"Hard billable credit ceiling across worker time and output size, when supplied."},"creditBalance":{"type":"integer","minimum":0},"error":{"$ref":"#/components/schemas/Error"}}},"AcceptedJob":{"type":"object","required":["ok","job","statusUrl"],"properties":{"ok":{"const":true},"reused":{"type":"boolean"},"job":{"$ref":"#/components/schemas/Job"},"statusUrl":{"type":"string","description":"Relative URL to poll with the same API key."}}},"JobStatus":{"type":"object","required":["ok","job"],"properties":{"ok":{"const":true},"job":{"$ref":"#/components/schemas/Job"},"result":{"$ref":"#/components/schemas/JobResult"}}},"JobResult":{"type":"object","required":["output","runtimeMs"],"properties":{"output":{"$ref":"#/components/schemas/MediaOutput"},"outputs":{"type":"array","minItems":1,"maxItems":50,"items":{"$ref":"#/components/schemas/MediaOutput"}},"runtimeMs":{"type":"integer","minimum":0},"analysis":{"type":"object","additionalProperties":true,"description":"Present for analysis tools (detect-scenes, detect-silence, analyze-audio, detect-visual-issues, describe-video): the same JSON as the output file, inline. Also present on smart-crop-video renders (kind smart_crop: the layout chosen per shot). The kind field names the shape: scene_detection, silence_detection, audio_analysis, visual_issues, video_description or smart_crop."}}},"MediaOutput":{"type":"object","required":["objectKey","downloadUrl","contentType","byteSize"],"properties":{"objectKey":{"type":"string"},"storageUri":{"type":"string","description":"Provider-neutral storage URI such as r2://bucket/key or gs://bucket/key."},"gcsUri":{"type":"string","deprecated":true,"description":"Legacy storage URI field kept for backward compatibility."},"downloadUrl":{"type":"string","format":"uri","description":"Signed temporary download URL."},"downloadUrlExpiresAt":{"type":"string","format":"date-time"},"contentType":{"type":"string"},"byteSize":{"type":"integer","minimum":0},"filename":{"type":"string"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"message":{"type":"string"}}},"GenerateVideoOptions":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","minLength":1,"maxLength":2000,"description":"What to generate, including the audio. Reference a supplied image as <Picture 1>."},"seconds":{"type":"number","minimum":4,"maximum":15,"default":5},"resolution":{"type":"string","enum":["480p","768p"],"default":"768p","description":"Short edge of the clip. Billed per second of video at the rate for this resolution."},"seed":{"type":"integer","minimum":0,"maximum":2147483647},"aspect_ratio":{"type":"string","enum":["16:9","9:16","1:1","4:3","3:4","21:9"],"default":"16:9","description":"Ignored when a start image is supplied: the clip then follows the image ratio (capped at 21:9)."},"image_url":{"type":"string","format":"uri","description":"Image-to-video: a public HTTPS image (JPEG, PNG or WebP, up to 20 MB) or a mediaUrl from the upload endpoint, used as the first frame."},"last_image_url":{"type":"string","format":"uri","description":"Optional last frame. Requires the start image."}}},"GenerateVideoOperation":{"type":"object","required":["type","prompt"],"properties":{"type":{"const":"generate_video"},"prompt":{"type":"string","minLength":1,"maxLength":2000,"description":"What to generate, including the audio. Reference a supplied image as <Picture 1>."},"seconds":{"type":"number","minimum":4,"maximum":15,"default":5},"resolution":{"type":"string","enum":["480p","768p"],"default":"768p","description":"Short edge of the clip. Billed per second of video at the rate for this resolution."},"seed":{"type":"integer","minimum":0,"maximum":2147483647},"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:3","3:4","21:9"],"default":"16:9","description":"Ignored when a start image is supplied: the clip then follows the image ratio (capped at 21:9)."},"imageUrl":{"type":"string","format":"uri","description":"Image-to-video: a public HTTPS image (JPEG, PNG or WebP, up to 20 MB) or a mediaUrl from the upload endpoint, used as the first frame."},"lastImageUrl":{"type":"string","format":"uri","description":"Optional last frame. Requires the start image."}}},"GenerateImageOptions":{"type":"object","required":["prompt"],"properties":{"model":{"type":"string","enum":["z-image-turbo","qwen-image"],"default":"z-image-turbo","description":"z-image-turbo: Z-Image Turbo (Apache-2.0) — fast and cheap, 1k only, ignores negative prompts. qwen-image: Qwen-Image (Apache-2.0) — slower and dearer, renders legible text, honours negative prompts, up to 2k"},"prompt":{"type":"string","minLength":1,"maxLength":2000,"description":"What to depict: subject, framing, light, style."},"size":{"type":"string","enum":["1k","2k"],"default":"1k","description":"Resolution tier; dimensions are derived from it and the ratio. 2k renders four times the pixels and is billed accordingly, and only Qwen-Image offers it."},"images":{"type":"integer","minimum":1,"maximum":4,"default":1,"description":"Variations to render (1-4), each billed separately and returned as its own output."},"seed":{"type":"integer","minimum":0,"maximum":2147483647,"description":"Fixed seed for reproducible results. A batch uses consecutive seeds from it."},"aspect_ratio":{"type":"string","enum":["1:1","16:9","9:16","4:3","3:4","3:2","2:3"],"default":"1:1","description":"Shape of the image. Every ratio costs the same at a given size: the pixel budget is held constant, not the edge."},"negative_prompt":{"type":"string","maxLength":2000,"description":"What to keep out of the image. Only Qwen-Image acts on it; Z-Image Turbo is guidance-distilled and ignores it."},"format":{"type":"string","enum":["png","webp"],"default":"png","description":"Delivery format. PNG is lossless; WebP is smaller."}}},"GenerateImageOperation":{"type":"object","required":["type","prompt"],"properties":{"type":{"const":"generate_image"},"model":{"type":"string","enum":["z-image-turbo","qwen-image"],"default":"z-image-turbo","description":"z-image-turbo: Z-Image Turbo (Apache-2.0) — fast and cheap, 1k only, ignores negative prompts. qwen-image: Qwen-Image (Apache-2.0) — slower and dearer, renders legible text, honours negative prompts, up to 2k"},"prompt":{"type":"string","minLength":1,"maxLength":2000,"description":"What to depict: subject, framing, light, style."},"size":{"type":"string","enum":["1k","2k"],"default":"1k","description":"Resolution tier; dimensions are derived from it and the ratio. 2k renders four times the pixels and is billed accordingly, and only Qwen-Image offers it."},"images":{"type":"integer","minimum":1,"maximum":4,"default":1,"description":"Variations to render (1-4), each billed separately and returned as its own output."},"seed":{"type":"integer","minimum":0,"maximum":2147483647,"description":"Fixed seed for reproducible results. A batch uses consecutive seeds from it."},"aspectRatio":{"type":"string","enum":["1:1","16:9","9:16","4:3","3:4","3:2","2:3"],"default":"1:1","description":"Shape of the image. Every ratio costs the same at a given size: the pixel budget is held constant, not the edge."},"negativePrompt":{"type":"string","maxLength":2000,"description":"What to keep out of the image. Only Qwen-Image acts on it; Z-Image Turbo is guidance-distilled and ignores it."}}}},"responses":{"BadRequest":{"description":"The request is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"A valid KinoGenie API key is required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InsufficientCredits":{"description":"The account does not have enough credits to start another edit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"QueueUnavailable":{"description":"The video edit could not be placed on the render queue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}