Skip to main content

Seedance 2.0 Material Library

The material library lets you prepare reusable images, videos, and audio files before submitting Seedance 2.0 video tasks. The API manages materials by UniAll.ai user: clients use only their UniAll.ai API key, a local mat_* material ID, and the returned asset:// URI.

This guide reflects the public contract updated on July 29, 2026.

Overview

The shortest integration flow is:

  1. Create a material with a public HTTP(S) URL and an Idempotency-Key.
  2. Poll the returned mat_* ID until status is available.
  3. Read the asset:// value from uri.
  4. Put that URI in a structured image, video, or audio field in the Seedance request.
  5. Delete the material when it is no longer needed, or let it expire automatically.

The first API version accepts public HTTP(S) URLs only. Direct file upload is not supported.

Base URL And Endpoints

All examples use this Base URL:

https://api.uniall.ai
OperationEndpointResult
Create a materialPOST /v1/materialsStarts processing and returns a local mat_* ID.
Get a materialGET /v1/materials/{material_id}Returns current status and the usable URI when available.
List materialsGET /v1/materialsReturns the current user's visible materials.
Delete a materialDELETE /v1/materials/{material_id}Cancels or deletes the material workflow.

Authentication And Idempotency

All material endpoints use the same UniAll.ai API key as video requests:

Authorization: Bearer sk-***
Content-Type: application/json

Material creation also requires an idempotency key:

Idempotency-Key: material-order-20260729-0001

The key must contain 1 to 200 visible ASCII characters, with no spaces or control characters.

  • Retrying the same normalized request with the same key returns the same local material workflow.
  • Reusing a key for a different request returns material_idempotency_conflict.
  • After a timeout or uncertain network result, retry with the original key. Do not generate a new key.
  • Use a new key when intentionally creating a new material.

Input URL Requirements

The source URL must:

  • use http:// or https://;
  • remain directly reachable while the material is processing;
  • work without login, cookies, browser state, custom headers, or private network access;
  • return media that matches the declared type;
  • remain accessible until the material reaches a terminal status.

Quick Start

1. Create A Material

curl -X POST "https://api.uniall.ai/v1/materials" \
-H "Authorization: Bearer sk-***" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: material-order-20260729-0001" \
-d '{
"url": "https://cdn.example.com/product.png",
"type": "image",
"name": "Product reference"
}'

The API returns HTTP 202 and a local material record:

{
"id": "mat_xxxxxxxxxxxxx",
"object": "material",
"name": "Product reference",
"type": "image",
"status": "processing",
"uri": null,
"preview_url": null,
"created_at": "2026-07-29T10:00:00Z",
"available_at": null,
"expires_at": null
}

2. Wait Until Available

curl "https://api.uniall.ai/v1/materials/mat_xxxxxxxxxxxxx" \
-H "Authorization: Bearer sk-***"

Poll every 3 to 5 seconds. Do not use uri until status is available:

{
"id": "mat_xxxxxxxxxxxxx",
"object": "material",
"name": "Product reference",
"type": "image",
"status": "available",
"uri": "asset://asset-xxxxxxxxxxxxx",
"preview_url": "https://example.com/short-lived-preview.jpg",
"created_at": "2026-07-29T10:00:00Z",
"available_at": "2026-07-29T10:01:00Z",
"expires_at": "2026-07-29T12:01:00Z"
}

3. Use The URI In Seedance

Copy the returned uri into the matching structured media field:

curl -X POST "https://api.uniall.ai/v1/videos" \
-H "Authorization: Bearer sk-***" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance2.0",
"resolution": "720p",
"duration": 6,
"content": [
{
"type": "text",
"text": "Keep the product appearance consistent and use a slow cinematic camera move."
},
{
"type": "image_url",
"image_url": {
"url": "asset://asset-xxxxxxxxxxxxx"
},
"role": "reference_image"
}
]
}'

Do not put an asset:// URI in prompt or another plain-text field. UniAll.ai checks ownership, status, and expiry before the media is submitted for generation. Unknown, expired, deleted, or another user's material is rejected. Regular HTTP(S) media inputs continue to work as documented in the series guide.

Create Materials

POST /v1/materials

Request Parameters

ParameterTypeRequiredDescription
urlstringYesPublic HTTP(S) image, video, or audio URL.
typestringYesimage, video, or audio.
namestringNoUser-facing material name.
real_personobjectNoRequired declaration and callback settings for a real-person image or video.
real_person.consent_confirmedbooleanYes with real_personMust be the JSON boolean true, confirming that separate consent was obtained.
real_person.callback_urlstringYes with real_personBrowser redirect after visual verification. Production URLs must use HTTPS.

Real-Person Materials

Real-person images and videos require an explicit consent declaration and browser-based liveness verification. Real-person audio is not supported.

curl -X POST "https://api.uniall.ai/v1/materials" \
-H "Authorization: Bearer sk-***" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: real-person-material-20260729-0001" \
-d '{
"url": "https://cdn.example.com/person.jpg",
"type": "image",
"name": "Authorized portrait",
"real_person": {
"consent_confirmed": true,
"callback_url": "https://client.example.com/material-complete"
}
}'

HTTP 202 can return verification_pending with a temporary verification_url:

{
"id": "mat_xxxxxxxxxxxxx",
"object": "material",
"name": "Authorized portrait",
"type": "image",
"status": "verification_pending",
"uri": null,
"preview_url": null,
"verification_url": "https://example.com/temporary-h5-token",
"created_at": "2026-07-29T10:00:00Z",
"available_at": null,
"expires_at": null,
"verification_expires_at": "2026-07-29T10:30:00Z"
}

Have the person open verification_url in a browser and complete the H5 liveness flow. After successful verification, UniAll.ai submits the actual material automatically. Do not call POST /v1/materials again.

The browser then redirects to real_person.callback_url with only these query parameters:

material_id=mat_xxxxxxxxxxxxx&material_status=processing

The callback status can be creating, processing, available, or a verification failure status. The redirect confirms that the verification result was received; it does not guarantee that the material is already available. Continue querying the material record. Background recovery can continue the workflow if the browser callback is lost.

verification_url appears only in the create response or an idempotent replay of that response. Get, list, and delete responses never include it.

Get A Material

GET /v1/materials/{material_id}

Only the user associated with the current API key can retrieve the material. The response does not expose the original input URL, visual-verification identifiers, internal material identifiers, routing details, credentials, temporary H5 tokens, or callback verification state.

Materials are currently valid for two hours after becoming available. At expires_at, the record is archived as deleted; subsequent user detail requests return 404 material_not_found.

List Materials

GET /v1/materials
Query parameterRequiredDescription
typeNoimage, video, or audio.
statusNocreating, verification_pending, processing, available, or delete_pending.
limitNoPage size from 1 to 100. Default: 50.
afterNoOpaque cursor returned by the previous page.
curl "https://api.uniall.ai/v1/materials?type=image&status=available&limit=20" \
-H "Authorization: Bearer sk-***"
{
"object": "material.list",
"data": [
{
"id": "mat_xxxxxxxxxxxxx",
"object": "material",
"name": "Product reference",
"type": "image",
"status": "available",
"uri": "asset://asset-xxxxxxxxxxxxx",
"preview_url": "https://example.com/short-lived-preview.jpg",
"created_at": "2026-07-29T10:00:00Z",
"available_at": "2026-07-29T10:01:00Z",
"expires_at": "2026-07-29T12:01:00Z"
}
],
"has_more": true,
"next_cursor": "opaque-cursor-value"
}

Pass next_cursor unchanged as after to request the next page. Do not parse or construct cursor values.

The user list excludes failed, verification-failed, verification-expired, deleted, historical expired, and already expired records awaiting archival. These records can remain available to administrators for audit and troubleshooting.

Delete A Material

DELETE /v1/materials/{material_id}
curl -X DELETE "https://api.uniall.ai/v1/materials/mat_xxxxxxxxxxxxx" \
-H "Authorization: Bearer sk-***"
  • HTTP 200 with status=deleted means deletion is complete.
  • HTTP 202 with status=delete_pending means deletion was accepted and is still processing.
  • Deleting a material whose real-person verification is incomplete cancels the local workflow.
  • Delete is idempotent. A deleted material cannot be used for generation.

Both successful status codes return the full material object used by the detail endpoint.

Material Statuses

StatusMeaning
creatingUniAll.ai is initializing the material workflow.
verification_pendingWaiting for real-person H5 verification.
verification_failedVerification failed or the session creation result is uncertain.
verification_expiredThe verification session expired.
processingThe media was submitted and is being processed.
availableThe material can be used in a generation request.
failedMaterial creation or processing failed.
delete_pendingDeletion was submitted and is still processing.
deletedDeletion is complete. This status can appear in a delete response but not in get or list results.

verification_failed, verification_expired, and failed are terminal failure states. Replaying the original creation key returns the original failed workflow; use a new Idempotency-Key to create a new material.

Security And Lifecycle Notes

  • Treat verification_url as a secret because it contains a temporary H5 token. Do not write it to application logs, analytics events, support messages, or public pages.
  • Do not log complete real-person callback URLs, query parameters, or callback verification state.
  • preview_url is short-lived. Do not treat it as permanent storage or distribute it as a stable public link.
  • Do not depend on the original input URL being returned by get or list endpoints.
  • Use only the asset:// URI returned for a currently available material owned by the same user.

Common Errors

Errors use an OpenAI-compatible structure:

{
"error": {
"message": "The material is not available.",
"type": "invalid_request_error",
"code": "material_not_available"
}
}
Error codeMeaning
invalid_idempotency_keyIdempotency-Key is missing or invalid.
invalid_material_requestA URL, type, name, or query parameter is invalid.
invalid_material_cursorafter is not a cursor returned by this endpoint.
material_channel_unavailableThe material service is temporarily unavailable or the current model does not support material input.
material_idempotency_conflictThe same idempotency key was used for a different request.
material_not_foundThe material does not exist, belongs to another user, or has expired and been archived.
material_not_availableThe material is not available, has expired, or was deleted.
material_not_managedThe asset:// URI is not registered in the current user's UniAll.ai material library.
visual_verification_consent_requiredConsent was not explicitly confirmed for a real-person material.
invalid_visual_verification_requestThe real-person media type or callback URL is invalid.
visual_verification_create_outcome_uncertainThe first verification-session creation result is uncertain; a duplicate session is not created automatically.
material_create_outcome_uncertainThe material creation result is uncertain while UniAll.ai performs background reconciliation.

Error messages contain only public information and do not expose upstream errors, internal routing, or credentials.