Render a video clip from an image and a prompt
Renders a short mp4 (1 to 15 seconds, 25 fps) of the person or
character in image, moving as prompt describes, optionally
speaking audio. No avatar is made or needed: the clip is rendered
directly by Atmee's v2 renderer.
image is upload:<uploadId> (a portrait upload, which stays
usable afterwards) or a public https link to a jpg, png or webp of at
most 10 MB; audio the same for a voice upload or link (wav, mp3,
webm, ...). The audio plays once from the start of the clip, padded
with silence and cut at its end. durationSeconds is required with
audio (the audio's own length is not read: set it to the audio's
length, at most 15; without it the request is 400 invalid_input)
and defaults to 8 for a silent clip; resolution defaults to
512 x 512 (see RenderResolution; e.g. 384 x 672 for portrait,
672 x 384 for landscape) and seed to 0. The prompt and the image
are moderated first. If the image shows a real person other than the
creator, have that person's permission first.
The clip is returned as upload:<uploadId> (24 hours) with a
short-lived url to download it. It costs the price per 15 seconds
(GET /v1/account, pricing.generation.clipPer15SecondsMicrocredits)
times durationSeconds / 15, rounded up to a whole microcredit (1
credit for a 15-second clip), charged only when the clip comes back; a
flagged, failed or refused call costs nothing. Clips use the v2
renderer, so an account without v2 access gets
403 v2_access_required. A render can take
minutes when the renderer starts cold: past about 45 seconds the
request answers 409 request_in_progress, and a retry with the same
Idempotency-Key after Retry-After returns the clip once it is
done, charged once. An image or audio the renderer cannot use (no
face, an unreadable file) is 400 invalid_input naming
input_failure image or input_failure audio. Where clips are not
offered the route answers 503 generation_unavailable. A size this
deployment offers but its render pool does not serve is 400 invalid_input naming input_failure resolution ("the render pool
does not serve WxH"), not an image error. Requires
generation:write and avatars:write.
X-Api-Key<token>Secret embed API key (sk_atmee_...; keys minted before 2026-09
carry sk_live_...), held by the customer's own backend and never
sent to a browser. Format: X-Api-Key: sk_atmee_....
Idempotency-Key*stringA new UUID minted for this request. Reuse it only to retry the same request: a retry never charges twice and returns the first result. A malformed key, or a key already used with different inputs, gets 400 invalid_input.
length <= 255application/json- body
image*stringWho or what the clip shows, upload:<uploadId> (a portrait upload) or a public https link (jpg, png or webp, at most 10 MB).
1 <= length <= 2048prompt*stringThe shot and the motion, e.g. "she walks along the beach at sunset, the camera following".
1 <= length <= 2000audio?stringWhat the clip says or plays, upload:<uploadId> (a voice upload) or a public https link to an audio file. Absent, the clip is silent.
1 <= length <= 2048durationSeconds?integerThe clip's length. Required with audio (set it to the audio's length, at most 15; it is not read from the file); default 8 for a silent clip.
1 <= value <= 15resolution?A frame size in pixels for the v2 renderer: width and height are each
a multiple of 32 from 256 to 1024, and width x height is at most
262,144 (512 x 512); a larger frame is 400 invalid_manifest on an
avatar, 400 invalid_input on a clip. Default 512 x 512 (square).
Common shapes: square 512 x 512, portrait 384 x 672, landscape
672 x 384. A deployment offers only some sizes (512 x 512 always;
GET /v1/account pricing.generation.clipResolutions lists them
where clips are offered): another is 400 invalid_input ("resolution
WxH is not offered; offered: ..."). On an avatar it is a build input of v2 avatars only
(400 invalid_input for a v1 avatar): the portrait is preprocessed
at that size, so a change on PATCH builds a new version with new
candidates, like a new portrait; sending the current size again
builds nothing. Absent or null keeps the current size (on create:
the default).
seed?integerThe render's seed; another seed gives other motion. Default 0.
int640 <= valueThe clip (or the replayed first result).
application/json- response
clip*microcreditsCharged*integerWhat this call charged (100 microcredits = 1 credit), the price per 15 seconds times durationSeconds / 15, rounded up; 0 on a replay.
replayed*booleanTrue when an earlier call with the same Idempotency-Key was replayed.
curl -X POST 'https://api.atmanity.us/v1/generation/clips' \ -H 'Idempotency-Key: string' \ -H 'Content-Type: application/json' \ -d '{ "image": "string", "prompt": "string"}'{ "clip": { "upload": "upload:3f1c2a9e-8d4b-4f6a-9c2e-1b7d5a0e4c11", "url": "http://example.com", "expiresAt": "2019-08-24T14:15:22Z", "durationSeconds": 0, "width": 0, "height": 0, "unavailable": true }, "microcreditsCharged": 0, "replayed": true}Design a voice from a description POST
Designs voice previews from a description of how the voice should sound.
Render an avatar into your own LiveKit room (API-key authenticated) POST
Starts an avatar session: the avatar is rendered into a LiveKit room that YOU own, on behalf of YOUR agent — the bring-your-own-agent path the livekit-plugins-atmee plugin uses.

