Create an AI avatar and its first talking video in one bash script
Two Sume jobs in order: create the avatar, wait, then render a talking video with its handle. A bash script with curl and jq, plus the cost of both steps.
Making a talking video from scratch on Sume is two jobs in a fixed order: create the avatar, wait until its job is completed, then submit a talking video that uses the avatar's handle. The script below does both with curl and jq. Sume avatars are async jobs: you submit a request, get a job id back, and read the finished video later. There is no live video session.
The first job costs a flat $0.95. The second costs per second of video, so a 10-second standard clip adds $1.84 for a total of $2.79.
The script
It needs curl, jq, and your key in SUME_API_KEY. The function wait_job polls the status endpoint, sleeps for next_poll_after_seconds when present and five seconds otherwise, and exits with the status body if the job did not complete. Each submit has its own Idempotency-Key, so running the script a second time does not create a second avatar or a second clip.
#!/usr/bin/env bash
set -euo pipefail
API=https://api.sume.com
AUTH=(-H "Authorization: Bearer $SUME_API_KEY")
JSON=(-H "Content-Type: application/json")
wait_job() {
while true; do
s=$(curl -s "${AUTH[@]}" "$API/v1/jobs/$1/status")
[ "$(echo "$s" | jq -r .terminal)" = "true" ] && break
sleep "$(echo "$s" | jq -r '.next_poll_after_seconds // 5')"
done
[ "$(echo "$s" | jq -r .sume_status)" = "completed" ] || { echo "$s" >&2; exit 1; }
}
job=$(curl -s -X POST "$API/v1/avatar-1.0/generate" "${AUTH[@]}" "${JSON[@]}" \
-H "Idempotency-Key: host-create-001" \
-d '{"avatar_handle":"launch_host","input":{"type":"prompt","prompt":"Friendly presenter, neutral studio light"}}')
wait_job "$(echo "$job" | jq -r .request_id)"
job=$(curl -s -X POST "$API/v1/avatar-1.0/talking-video" "${AUTH[@]}" "${JSON[@]}" \
-H "Idempotency-Key: host-first-clip-001" \
-d '{"avatar_handle":"launch_host","script":"Hi, I am your launch host. Here is what is new this week.","quality":"standard"}')
id=$(echo "$job" | jq -r .request_id)
wait_job "$id"
curl -s "${AUTH[@]}" "$API/v1/jobs/$id/result"Why the order matters
The Create new avatar page says each request creates a job and that you use the returned handle or resource id to generate avatar videos after the job completes. If you submit the talking video before the avatar is ready, the handle does not resolve to a ready avatar. The wait between the two steps is not optional.
Cost of the two steps
| Clip length | Tier | Avatar creation | Clip | Total |
|---|---|---|---|---|
| 10 s | standard | $0.95 | $1.84 | $2.79 |
| 10 s | plus | $0.95 | $2.45 | $3.40 |
| 10 s | max | $0.95 | $5.50 | $6.45 |
| 30 s | standard | $0.95 | $5.52 | $6.47 |
| 30 s | plus | $0.95 | $7.35 | $8.30 |
| 30 s | max | $0.95 | $16.50 | $17.45 |
Next steps
Once the avatar exists, every later video is one job and you skip the creation. Use an Avatar video preview if you want to approve the first frame before paying for the render. Switch to webhook mode when a server, not a person, is waiting for the result. For many clips, store each job id in your own table so you can look it up later.
Keep the handle in a config file, not in code, so a new presenter is a one-line change.
Making it your own
Change avatar_handle, the prompt and the script to fit your product. To build the avatar from a reference photo, replace the input with {"type":"photo","image_url":"https://example.com/reference.png"}; the URL must be a fetchable public HTTPS image, because Sume rejects localhost, private-network, non-HTTPS and non-image URLs before it submits the generation. To build it from structured traits, use {"type":"props","ethnicity":"Asian","sex":"female","age":28}.
If you run the script twice with the same keys, the second run returns the original jobs and does not charge again. If you want a new avatar, change the handle and the keys together. The script exits non-zero when a job does not complete, so a CI step or a scheduler can treat it as a failure and show the status body that explains why.
Sources
Related posts
More in Developers
- CTA end card for an AI video ad: use last_frame on Sume
End an ad clip on your CTA card by sending it as a last_frame image on /v1/videos. Which models accept it, which do not, and the Timeline alternative.
- How do I narrate a DIY tutorial step by step with a TTS API?
Narrate an 8-step DIY tutorial with one TTS job per step: 1,570 characters, $0.10 on Sume. Why per-step jobs make a fixed step a 1-cent redo.
- Do I pay for a failed AI avatar video job? Refunds on Sume
Sume reserves the avatar video price at submit, captures it on completion, and releases or refunds it where a job fails. What it means for retries.
- Does PNG, JPEG or WebP change the price of an AI image on Sume?
No. On Sume's Image API, output_format picks the file type, not the price: per-image cards and GPT Image 2.5 token math ignore it. Which models list which.
Written by Sume