Skip to content
API Reference

Clip Generation

Turn a portrait image and a voice track into a talking-avatar video clip. The voice comes from Text to Speech (audio_id) or from an audio file you supply (sound_file).

POST https://llm.siraya.ai/v1/avatar/generations
GET https://llm.siraya.ai/v1/avatar/generations/{id}

Send async: true

Without it, the call blocks until the video is finished, which takes minutes and will outlast most client timeouts. With "async": true you get an id back immediately and poll GET /v1/avatar/generations/{id} until status is completed or failed.

Supported Models

Model ID Description
kling-avatar Portrait + audio → talking-avatar clip

Request

Field Type Required Details
model string Yes kling-avatar
image string Yes Portrait image: URL or bare base64 (no data: prefix). jpg/jpeg/png, ≤10MB, ≥300px, aspect ratio 1:2.5–2.5:1 — see Kling's avatar reference
audio_id string one of two From Text to Speech. 30-day validity, duration 2–300 s
sound_file string one of two Audio URL or base64. mp3/wav/m4a/aac, ≤5MB, duration 2–300 s
prompt string No Actions, emotions, camera moves. Max 2500 characters
mode string No std (default, cheaper) or pro (higher quality). Which tiers apply varies by model — see Kling's Capability Map
watermark_info object No {"enabled": true} to also receive a watermarked copy
async boolean Recommended true — poll instead of blocking

audio_id and sound_file are mutually exclusive: send exactly one.

image takes bare base64

Unlike the other video endpoints, image does not accept a data:image/png;base64,… URI. Send the raw base64 string, or a public URL.

Example

curl https://llm.siraya.ai/v1/avatar/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <API_KEY>" \
  -d '{
    "model": "kling-avatar",
    "image": "https://your-domain.com/portrait.png",
    "audio_id": "<AUDIO_ID>",
    "prompt": "A person talking happily to the camera",
    "mode": "std",
    "async": true
  }'

Response

Create (async: true):

{
    "id": "video_Mt_F0IY5sFCEH8fOFbe7auEghYcqVQmSwlGdIKLo2gdlkJ...",
    "object": "video",
    "status": "processing",
    "model": "kling-avatar",
    "usage": { "completion_tokens": 0, "total_tokens": 0 },
    "vendor_data": { "created_at": 1791773116011, "mode": "avatar", "updated_at": 1791773116011 }
}

Poll GET /v1/avatar/generations/{id}:

curl https://llm.siraya.ai/v1/avatar/generations/<VIDEO_ID> \
  -H "Authorization: Bearer <API_KEY>"
{
    "id": "video_Mt_F0IY5sFCEH8fOFbe7auEghYcqVQmSwlGdIKLo2gdlkJ...",
    "object": "video",
    "status": "completed",
    "seconds": 7,
    "model": "kling-avatar",
    "output_url": "https://.../output.mp4?Expires=...",
    "usage": { "completion_tokens": 0, "total_tokens": 0 },
    "vendor_data": {
        "created_at": 1791773116011, "mode": "avatar",
        "outputs": [ { "duration": "7.2", "id": "938452881199079449", "type": "video", "url": "https://..." } ]
    }
}
  • output_url is signed and expires — download the file if you need to keep it.
  • vendor_data.outputs[0].duration carries the unrounded length ("7.2"); seconds is rounded.
  • Output is h264 + AAC. Resolution follows the reference image (e.g. 816×1104 for a portrait URL; 1232×1648 from the same portrait sent as bare base64).
  • With "watermark_info": {"enabled": true}, each entry in vendor_data.outputs gains a watermark_url alongside url — a separately downloadable watermarked copy of the same video.

See also the shared errors and unsupported parameters for the avatar family.