Skip to content

Visual liveness verification ​

Visual liveness verification creates a restricted asset group for media that must be bound to a specific real-person identity. It is a group-level verification flow, not a normal file upload. Completing verification does not create an asset_xxx immediately.

Flow ​

  1. Create a one-time session with POST /v1/visual-validate-sessions.
  2. Open the returned h5_link on the end user's device and complete the liveness flow.
  3. Poll POST /v1/visual-validate-results until the status is completed.
  4. Save the returned group_id. The verified group may initially contain zero assets; that is expected.
  5. Upload the image, video, or audio to that group with POST /v1/assets/uploads. The upload creates the MoonApiX asset_id and Asset://asset_xxx.
  6. Pass Asset://asset_xxx to a compatible generation request and check preparation for the target model.

Sessions expire after 30 minutes. h5_link is a one-time, short-lived link for the end user. Do not put it in logs, public pages, or long-lived business data.

1. Create a session ​

http
POST /v1/visual-validate-sessions
bash
curl https://moonapix.com/v1/visual-validate-sessions \
  -H "Authorization: Bearer <MOONAPIX_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2.0-sz",
    "callback_url": "https://client.example.com/visual-validate/callback"
  }'

Request fields ​

FieldTypeRequiredDescription
modelstringYesTarget model enabled for the current API key with an available liveness-compatible route. Session creation returns 503 if no such route is available.
callback_urlstringYesHTTPS callback URL. It is forwarded as a verification callback parameter; clients must still poll the result endpoint.

Response ​

json
{
  "object": "visual_validate_session",
  "session_id": "vvs_0123456789abcdefghijklmnopqrstuvwxyzabcd",
  "h5_link": "https://example.com/one-time-link",
  "expires_at": 1710001800
}

Keep the session_id and expires_at from the create response, and give h5_link to the end user. Pass the exact session_id back when polling; do not log the complete link.

Open h5_link in the user's browser or WebView. After the user completes the requested liveness actions, poll the result endpoint. Create a new session if the link expires, is reused, or the 30-minute session lifetime has elapsed.

3. Poll the result ​

http
POST /v1/visual-validate-results
bash
curl https://moonapix.com/v1/visual-validate-results \
  -H "Authorization: Bearer <MOONAPIX_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"session_id":"vvs_0123456789abcdefghijklmnopqrstuvwxyzabcd"}'

While processing:

json
{
  "object": "visual_validate_result",
  "session_id": "vvs_0123456789abcdefghijklmnopqrstuvwxyzabcd",
  "status": "pending"
}

When complete:

json
{
  "object": "visual_validate_result",
  "session_id": "vvs_0123456789abcdefghijklmnopqrstuvwxyzabcd",
  "status": "completed",
  "group_id": "group_xxx",
  "upstream": {
    "group_id": "group-official-example"
  }
}

The completed result is a MoonApiX group_id, not an asset_id. MoonApiX creates a private group first, so GET /v1/assets?group_id=group_xxx may legitimately return total=0. Repeating a completed result query returns the same group_id.

A completed result may also include upstream.group_id, the original official Volcengine group ID registered for this session. Upload and manage media using the top-level MoonApiX group_id and subsequent asset_id. To resolve the official group ID to your MoonApiX group, use asset ID resolution with the same public model used for the session. A pending result has no asset group; wait for the user to complete verification.

Sessions belong to the API user that created them. Missing, malformed, unknown, expired, or cross-user session IDs return 404. If the route pinned to a session is unavailable, the result query returns 409; temporary verification service failures return a service error.

4. Upload into the verified group ​

After verification, upload the media that the generation request will use. Include the target model and specify purpose and role where possible.

bash
curl https://moonapix.com/v1/assets/uploads \
  -H "Authorization: Bearer <MOONAPIX_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2.0-sz",
    "mode": "asset",
    "type": "image",
    "purpose": "reference_image",
    "role": "reference_image",
    "group_id": "group_xxx",
    "url": "https://example.com/your-reference.png"
  }'

The successful upload provides the public identities:

text
asset_id  = asset_xxx
asset_ref = Asset://asset_xxx
group_id  = group_xxx

Only media owned by the current user and accepted by the target model can be added. Use the group_id returned by this API; identifiers shown by the verification page or another API cannot replace it.

5. Use the asset in generation ​

Query the asset for the target model first. Confirm asset.status=ready, preparation.status is ready or not_required, and preparation.generation_ready=true. Then pass Asset://asset_xxx explicitly:

json
{
  "model": "seedance-2.0-sz",
  "prompt": "Have @person turn naturally while preserving the identity and clothing.",
  "references": [
    {
      "media_type": "image",
      "role": "reference_image",
      "url": "Asset://asset_xxx",
      "alias": "person"
    }
  ],
  "duration": 5,
  "size": "720p",
  "aspect_ratio": "16:9"
}

Ordinary image, video, and audio references do not need liveness verification; use normal asset upload. Verification does not bypass model capabilities or content-safety review.

Common errors ​

HTTP statuscodeMeaning
400invalid_json / model_required / invalid_callback_urlInvalid create body, model, or callback URL; invalid JSON on the result endpoint also returns this status.
403model_access_deniedThe API key cannot use the target model.
404session_not_foundThe result request has a missing, malformed, unknown, or expired session_id, or the session belongs to another API user.
409session_route_unavailableThe route or credential pinned to the session is no longer available.
500session_creation_failed / result_persist_failedThe server could not create or persist the required session or result state.
502—The verification service failed to create the session or query its result.
503session_store_unavailable / visual_validation_unavailableSession storage is unavailable, or no liveness-compatible route is available for the model.