Skip to content
All docs

Reference

POST /v1/videos

Make a clip with sound from a text prompt, in OpenAI’s format: the SDK’s videos methods work with only the base URL changed. Queue it, check it, download it once, and it is deleted.

Checked 6 November 2026

Make a clip

import os
import time
from openai import OpenAI

client = OpenAI(
    base_url="https://nokeep.ai/v1",
    api_key=os.environ["NOKEEP_API_KEY"],
)

clip = client.videos.create(
    model="minimax-h3-max-turbo",
    prompt="Waves breaking on a rocky coast at dusk",
    seconds="5",
    size="1280x720",
)

while clip.status in ("queued", "in_progress"):
    time.sleep(5)
    clip = client.videos.retrieve(clip.id)

if clip.status == "completed":
    client.videos.download_content(clip.id).write_to_file("clip.mp4")

Models

ModelGood for480p per second768p per second1080p per second
minimax-h3-max-turboFast, with sound. The one to start with.$0.045$0.07$0.14
minimax-h3-maxMore steps than Turbo for finer detail, with sound.$0.09$0.14$0.28

You pay for the seconds you ask for. Both models make clips of 5 to 15 seconds with sound.

Request

FieldTakesWhat it does
modelRequiredOne of the model ids above.
promptRequired, up to 10,000 charactersWhat to film, sent to the model as written. Over the limit is refused, never cut.
seconds5 to 15The clip’s length, as a number or a string. The default is 5. OpenAI’s 4 is refused; 8 and 12 work.
sizeWIDTHxHEIGHTPicks the nearest resolution and shape. 1280x720 becomes 768p at 16:9, and that is what you pay for.
resolution480p, 768p or 1080pSets the price and wins over size. The default is 768p.
aspect_ratio16:9, 21:9, 4:3, 1:1, 3:4, 9:16Wins over size. The default is 16:9.

Send JSON or the multipart form OpenAI’s SDKs use. Any other field, such as seed, is dropped and named in x-nokeep-ignored. A field that carries a picture or clip, such as input_reference, is refused with 400 unsupported_input: these models work from text only. OpenAI’s Python SDK prints a deprecation warning on its videos methods, about OpenAI’s own video service. It doesn’t affect calls to us, and a type checker may flag the model id.

The clip’s routes

RouteWhat it does
POST /v1/videosQueues a clip and holds its price.
GET /v1/videos/{id}Says where it is. Check every few seconds.
GET /v1/videos/{id}/contentThe mp4. It works once, then the clip is deleted from the model’s host. If the download is cut off, ask again.
DELETE /v1/videos/{id}Deletes a finished clip without downloading it. A clip still rendering answers 409 video_not_ready.
GET /v1/videosThe account’s recent clips.

The clip object

JSON
{
  "id": "video_8f3a…",
  "object": "video",
  "model": "minimax-h3-max-turbo",
  "status": "completed",
  "progress": 100,
  "created_at": 1793960000,
  "completed_at": 1793960030,
  "expires_at": 1794042800,
  "seconds": "5",
  "size": "1366x768",
  "resolution": "768p",
  "aspect_ratio": "16:9",
  "error": null,
  "downloaded": false,
  "expired": false,
  "usage": {
    "nokeep_credits": 350
  }
}
  • status is queued, in_progress, completed or failed.
  • progress is 0 until the clip is finished, then 100. The model doesn’t report anything in between.
  • size is worked out from the resolution and shape, so the file can differ by a few pixels.

What you pay

  • The clip’s full price is held when it is queued, against your bought credits and the key’s daily cap.
  • It is charged when the clip finishes, whether or not you download it.
  • A clip that fails costs nothing, and its status says so.

Where the clip stays

A finished clip waits on the model’s host, on its private tier, for up to 23 hours. It is deleted there after its one download, or when you delete it. We never hold the file, and past that time it answers 410 video_gone. Our own row about a clip holds its id, key, model, length, resolution, shape, credits and times, and never the prompt. It is deleted after 48 hours.

Content, limits and errors

Four hard limits stay: sexual content involving minors, sexual content of real people, mass-casualty harm and targeting a real person. A prompt that crosses one gets 422 hard_limit and costs nothing. A model’s host can also refuse a request, which is 422 content_refused, also free. See Hard limits.

A key can queue 20 clips a minute, inside its 120 requests overall, and have 10 rendering at once. Past that is 429 rate_limited. The errors page lists every code.

To check your code without spending anything, send sk-nokeep-test as the key. It runs every check, reports the clip finished at once as video_test, and its file is empty.