Digital human / smart edit API
Avatar library, digital-human video, lip sync, motion transfer and smart editing — all on one sk-gpushare-* key
Register a reusable digital-human avatar from one photo or a short video, then drive it with audio or text to produce video. You can also lip-sync an existing video, transfer the motion from one video onto still portraits, or cut a finished piece from a template.
Authentication is identical to every other endpoint — the same sk-gpushare-* key in whichever of the four forms you prefer (x-api-key or x-goog-api-key header, ?key= query, Authorization: Bearer); see Authentication. Everything bills against your account balance (shared by all keys), and an insufficient balance returns 402 quota_exceeded.
| Endpoint | Purpose | Billing |
|---|---|---|
POST /v1/videos/avatars | Register an avatar (async) | per call |
GET /v1/videos/avatars | Your avatar library | free |
GET /v1/videos/avatars/{id} | Check an avatar's creation status | free |
DELETE /v1/videos/avatars/{id} | Delete an avatar | free |
GET /v1/videos/avatars/presets | The platform's built-in avatars | free |
GET /v1/videos/clip-templates | List smart-edit templates | free |
GET /v1/videos/clip-templates/{id} | A template's structure | free |
POST /v1/videos/generations | Produce video (digital human / lip sync / motion transfer / smart edit) | per second |
GET /v1/videos/generations/{id} | Poll a production task | free |
Producing and polling use the same generic video endpoints from the media APIs; only the model and the body fields change. Each variation below comes with a complete example.
1. The avatar library#
POST /v1/videos/avatars#
Register an avatar from a front-facing photo (or a video of the person). This is async: you get a pending record straight away and can only produce video once it polls ready, typically 5–10 minutes upstream.
{
"name": "My presenter",
"source_url": "https://example.com/portrait.jpg",
"source_kind": "image"
}
| Field | Required | Notes |
|---|---|---|
name | yes | 1–20 characters, the avatar's name in your library |
source_url | yes | A publicly reachable direct http(s) link. Upstream fetches the material itself and we offer no upload endpoint — host it yourself (object storage, a CDN, any public direct link) |
source_kind | no | image (default) or video |
Response:
{
"id": "9f1c…",
"name": "My presenter",
"source_kind": "image",
"status": "pending",
"error": null,
"created_at": "2026-07-29T08:12:00+00:00"
}
That id is the avatar reference you'll use from now on — put it in the avatar field when producing video; the underlying upstream identifier is not your concern.
GET /v1/videos/avatars/{id}#
Poll the creation status, every 15–30 seconds.
{ "id": "9f1c…", "name": "My presenter", "status": "ready", "error": null, "created_at": "…" }
status has three states: pending / ready / failed. Failures are refunded in full automatically — the refund uses this record as its evidence, which is why deletion is blocked while it is pending.
GET /v1/videos/avatars#
Lists this account's avatars (up to 200, newest first).
DELETE /v1/videos/avatars/{id}#
Deletes an avatar. One still being created (pending) can't be deleted — wait until it succeeds or fails.
GET /v1/videos/avatars/presets#
The platform's built-in avatars, free to use directly with no registration:
{ "avatars": [ { "id": "…", "name": "Professional female presenter" }, … ] }
Drop any id from presets straight into the avatar field of a production request.
2. Digital-human video (dh-avatar)#
Make a ready avatar speak. The driving audio or script sets the length, and you're billed per second of finished video.
Option 1: drive with audio#
{
"model": "dh-avatar",
"avatar": "9f1c…",
"audio_url": "https://example.com/voice.mp3",
"duration": 32
}
Option 2: drive with text plus a voice (one step, no separate synthesis)#
{
"model": "dh-avatar",
"avatar": "9f1c…",
"voice": "<voice id>",
"text": "Hello everyone — today I want to introduce…",
"duration": 30
}
voice can be either:
- the id of a voice you cloned through
POST /v1/audio/voices, or - a platform preset voice id from the
presetsinGET /v1/audio/voices.
durationis required, in seconds. It's the basis for our cost hold — use the real length of the driving audio, or estimate from the script (Mandarin narration runs at roughlycharacters ÷ 3.3seconds). When the task ends we settle on the actual seconds upstream reports and refund the excess automatically; the hold also caps what this production can cost.
Submit and poll on the generic video endpoints:
curl https://dianqi.zsopc.com/v1/videos/generations \
-H "Authorization: Bearer $GPUSHARE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"dh-avatar","avatar":"9f1c…","audio_url":"https://example.com/voice.mp3","duration":32}'
# → {"id":"…","status":"queued","model":"dh-avatar","created_at":1753…}
curl https://dianqi.zsopc.com/v1/videos/generations/<id> \
-H "Authorization: Bearer $GPUSHARE_API_KEY"
# → {"id":"…","status":"succeeded","video_url":"https://…","expires_at":…}
3. Lip sync (dh-lipsync / -pro / -max)#
Swap the audio track on an existing video of a person and match the lips to it. The three tiers step up in quality and price.
{
"model": "dh-lipsync-pro",
"source_video_url": "https://example.com/source.mp4",
"audio_url": "https://example.com/new-voice.mp3",
"duration": 45
}
The finished length follows the driving audio. Both the source video and the audio must be publicly reachable direct links.
4. Motion transfer (dh-motion)#
Transfer the motion from a source video onto 1–7 portraits.
{
"model": "dh-motion",
"source_video_url": "https://example.com/dance.mp4",
"face_count": 2,
"resolution": "standard",
"content": [
{ "type": "image_url", "image_url": { "url": "https://example.com/person1.jpg" } },
{ "type": "image_url", "image_url": { "url": "https://example.com/person2.jpg" } }
],
"duration": 20
}
| Field | Notes |
|---|---|
source_video_url | The motion source video (public direct link) |
content[] | 1–7 portraits |
face_count | How many people are in frame, 1–7; should match the number of portraits |
resolution | fast / standard (default) / max — the tier sets the unit price; see the pricing table below |
duration | Required; use the source video's length |
The finished length follows the motion source video.
5. Smart editing (clip-realman / clip-mixcut / clip-news)#
Cut your assets into a finished piece using a platform template. You must fetch a template id first and pass it as style_id.
Step 1: get a template#
curl "https://dianqi.zsopc.com/v1/videos/clip-templates?scene=realMan" \
-H "Authorization: Bearer $GPUSHARE_API_KEY"
Allowed values for scene:
| scene | What it does |
|---|---|
virtualman | Virtual-presenter broadcast |
realMan | Real talking head (clip-realman) |
oralMixCutting | Narration mixcut (clip-mixcut) |
newsMixCutting | News mixcut (clip-news) |
Each template in the response carries an id, a title, a cover and two capability flags:
has_title— the template has a title layer, so you can pass title text;has_persona— the template has a persona layer, so you can pass persona text.
When a flag is false the matching input is ignored upstream, so don't bother sending it. For a template's full structure (canvas and layers), call GET /v1/videos/clip-templates/{id}.
Both endpoints are free and server-side cached, so calling them every time your client opens is fine. The key must be allowed at least one
clip-*model to reach the template catalogue.
Step 2: submit the edit#
{
"model": "clip-realman",
"style_id": "<the template id from step 1>",
"duration": 60
}
The remaining fields (assets, narration audio, title and persona text, and so on) depend on the template — consult the layer structure in its details.
Pricing#
For the per-second SKUs, settlement uses the actual seconds upstream reports; duration sizes the hold on submit and the excess is refunded.
| Model ID | Purpose | Price |
|---|---|---|
dh-avatar-create | Register an avatar | 210.29 each |
dh-avatar | Digital-human video | 3.76 / second |
dh-lipsync | Lip sync · standard | 4.04 / second |
dh-lipsync-pro | Lip sync · HD | 8.09 / second |
dh-lipsync-max | Lip sync · UHD | 12.13 / second |
dh-motion | Motion transfer | fast 4.04 / standard 8.09 / max 12.13 per second |
clip-realman | Smart edit · talking head | 4.04 / second |
clip-mixcut | Smart edit · narration mixcut | 4.04 / second |
clip-news | Smart edit · news mixcut | 2.43 / second |
The companion voice endpoints (synthesis and cloning) are in the media APIs.
Async and timeout conventions#
- Avatar registration and video production are both async: submitting returns immediately and you poll the status endpoint afterwards. Polling itself is free.
- A production task's
video_urlis a time-limited link, withexpires_atin the response as its expiry — copy it somewhere of your own if you need it long-term. - Failed tasks (an upstream error, a timeout, expiry) are refunded in full automatically; you need do nothing.
- The avatar record is the refund's evidence: calling
DELETEwhile it'spendingreturns 400, so wait for a final state.
Common errors#
| HTTP | code | Meaning |
|---|---|---|
| 400 | invalid_request_error | The avatar or voice reference doesn't exist, belongs to another account, or isn't ready yet; duration is missing; name is too long; source_url isn't http(s) |
| 401 | authentication_error | The key is invalid or disabled |
| 402 | quota_exceeded | Insufficient account balance |
| 403 | model_not_allowed | This key's model allowlist doesn't include that SKU |
| 404 | model_not_found | The model id is wrong, or that SKU isn't available yet |
| 503 | no_channel_available | No upstream is currently available for that SKU; retry later |
The error body matches every other endpoint — see Error codes.