Images and video
Image generation and asynchronous video generation with the OpenAI SDK.
Images come back immediately, and video is made asynchronously: you create a job, wait for its status and download the file. Both APIs are compatible with the OpenAI SDK.
Images
import base64
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.morphogen.ru/v1",
api_key=os.environ["MORPHOGEN_API_KEY"],
)
resp = client.images.generate(
model="flux-2-klein",
prompt="красное яблоко на белом столе",
n=2,
)
for i, image in enumerate(resp.data):
with open(f"apple-{i}.jpg", "wb") as f:
f.write(base64.b64decode(image.b64_json))The image arrives as a b64_json string. The response_format: "url" mode is not supported: there is no image hosting. Streaming is not supported either. Parameters: Images.
Image models also work through /v1/chat/completions with modalities: ["image"]: the image then arrives in choices[0].message.images[].image_url.url as a data URL. This is handy if your app is already built on chat.
Video
- Create a job
video = client.videos.create( model="grok-imagine-video", prompt="бумажный кораблик на озере на закате", seconds="4", size="854x480", ) print(video.id, video.status)The response comes back immediately with the
queuedstatus. - Wait for the result
import time while video.status in ("queued", "in_progress"): time.sleep(10) video = client.videos.retrieve(video.id) print(video.status)A clip usually takes up to a couple of minutes to generate. The
failedstatus means generation failed, and no money is charged for it. - Download the file
client.videos.download_content(video.id).write_to_file("boat.mp4") - Delete it when you no longer need the file
client.videos.delete(video.id)Until you delete the job, the file is stored on our side.
The same calls are available over plain HTTP, and the SDK is optional: Create, Get, Download, Delete.
Money
Before a video starts, an amount is reserved: the seconds multiplied by the price per second at the chosen resolution. If you do not set generate_audio, a model with sound takes the price with sound. After completion, the actual cost is charged. A job cancelled in the queue and any job with the failed status cost nothing. For images, the reserve equals the number of images multiplied by the price of one.
It does not apply to images and video: a masked prompt would put placeholders into the image, and an image cannot be unmasked. For images, an explicit X-PII-Masking: on returns 400 pii_masking_unsupported_endpoint. For video the header is ignored: the request goes through and the prompt reaches the provider unmasked, so do not send personal data in a video prompt.
Errors
| Code | What to do |
|---|---|
400 unsupported_video_parameter | choose a duration and resolution allowed for the model |
400 invalid_image_count | n must be from 1 to 10 |
404 video_not_ready | the file was requested before the completed status |
409 video_cancel_unsupported | the job is already with the provider, wait for it to finish |
All codes: Errors.