> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sunra.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Seedance 2.0 Face Authentication

> Register and authenticate a reference asset (such as a person's face) so it can be used with Seedance 2.0, via Sunra's Ark Assets API.

# Seedance 2.0 Face Authentication

Some Seedance 2.0 use cases — for example driving a video with a specific person's face — require the reference asset to be **registered and authenticated** with the upstream provider before it can be used. Sunra exposes a small **Ark Assets API** that handles this for you: you submit the URL of an image (or video / audio), Sunra registers it upstream, and once it becomes `active` you can reference it in your Seedance 2.0 generation.

These endpoints do not run an inference pipeline — there is no prediction record, no queue, and no per-call inference billing. They are a thin management layer over the upstream asset registry.

## Authentication

Authentication is the same as the rest of the Sunra API — send your API key in the `Authorization` header:

```
Authorization: Bearer $SUNRA_API_KEY
```

All Ark Assets endpoints are scoped to your organization; you can only see and manage assets your organization created.

## Workflow

1. **Create** the asset from a source URL → returns an `ark_asset_id` with `status: "processing"`.
2. **Poll** the asset with *Get asset* until `status` becomes `active`.
3. **Use** `asset://<ark_asset_id>` as a reference in a Seedance 2.0 **relay** request (see [Using the asset](#using-the-asset-in-seedance-2-0) below).

Statuses: `processing` (registering upstream), `active` (ready to use), `failed` (registration failed).

## Create an asset

```
POST https://api.sunra.ai/v1/ark/assets
```

| Field        | Type                          | Required | Description                                                                                |
| ------------ | ----------------------------- | -------- | ------------------------------------------------------------------------------------------ |
| `source_url` | string                        | yes      | Publicly accessible URL of the asset (e.g. a face image). Must be reachable by the server. |
| `name`       | string                        | no       | Friendly name. Defaults to the filename inferred from `source_url`.                        |
| `asset_type` | `image` \| `video` \| `audio` | no       | Asset type. Inferred from the URL extension when omitted (defaults to `image`).            |

**Response** — the created asset:

```json theme={null}
{
  "id": "665f1c...",
  "ark_asset_id": "cgt-20260609-abc123",
  "name": "face.jpg",
  "asset_type": "image",
  "source_url": "https://example.com/face.jpg",
  "status": "processing",
  "created_at": "2026-06-09T15:00:00.000Z"
}
```

## Get an asset

Fetches a single asset and refreshes its status from upstream. When the asset is ready, the response includes `ark_url`.

```
GET https://api.sunra.ai/v1/ark/assets/{ark_asset_id}
```

```json theme={null}
{
  "id": "665f1c...",
  "ark_asset_id": "cgt-20260609-abc123",
  "name": "face.jpg",
  "asset_type": "image",
  "source_url": "https://example.com/face.jpg",
  "status": "active",
  "ark_url": "https://.../authenticated-asset",
  "created_at": "2026-06-09T15:00:00.000Z"
}
```

## List assets

```
POST https://api.sunra.ai/v1/ark/assets/list
```

| Field       | Type    | Default | Description                                              |
| ----------- | ------- | ------- | -------------------------------------------------------- |
| `status`    | string  | —       | Filter by status (`processing` \| `active` \| `failed`). |
| `page`      | integer | 1       | Page number.                                             |
| `page_size` | integer | 20      | Items per page.                                          |

**Response:**

```json theme={null}
{
  "items": [ { "ark_asset_id": "cgt-...", "status": "active", "asset_type": "image" } ],
  "total": 1,
  "page": 1,
  "page_size": 20
}
```

## Delete an asset

Soft-deletes the asset from your organization's list (the upstream registration is unaffected).

```
DELETE https://api.sunra.ai/v1/ark/assets/{ark_asset_id}
```

```json theme={null}
{ "deleted": true }
```

## Examples

<CodeGroup>
  ```bash cURL theme={null}
  # 1. Create
  curl -X POST "https://api.sunra.ai/v1/ark/assets" \
    -H "Authorization: Bearer $SUNRA_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"source_url":"https://example.com/face.jpg","asset_type":"image"}'

  # 2. Poll until active
  curl "https://api.sunra.ai/v1/ark/assets/cgt-20260609-abc123" \
    -H "Authorization: Bearer $SUNRA_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const base = "https://api.sunra.ai/v1/ark/assets";
  const headers = {
    Authorization: `Bearer ${process.env.SUNRA_API_KEY}`,
    "Content-Type": "application/json",
  };

  // 1. Create
  const created = await (
    await fetch(base, {
      method: "POST",
      headers,
      body: JSON.stringify({
        source_url: "https://example.com/face.jpg",
        asset_type: "image",
      }),
    })
  ).json();

  // 2. Poll until active
  let asset = created;
  while (asset.status === "processing") {
    await new Promise((r) => setTimeout(r, 3000));
    asset = await (
      await fetch(`${base}/${created.ark_asset_id}`, { headers })
    ).json();
  }
  console.log(asset.status, asset.ark_url);
  ```

  ```python Python theme={null}
  import os, time, requests

  base = "https://api.sunra.ai/v1/ark/assets"
  headers = {"Authorization": f"Bearer {os.environ['SUNRA_API_KEY']}"}

  # 1. Create
  asset = requests.post(
      base,
      headers=headers,
      json={"source_url": "https://example.com/face.jpg", "asset_type": "image"},
  ).json()

  # 2. Poll until active
  while asset["status"] == "processing":
      time.sleep(3)
      asset = requests.get(f"{base}/{asset['ark_asset_id']}", headers=headers).json()

  print(asset["status"], asset.get("ark_url"))
  ```
</CodeGroup>

## Using the asset in Seedance 2.0

Once the asset is `active`, reference it as **`asset://<ark_asset_id>`** inside `reference_images` (or `reference_videos` / `reference_audios`) of a Seedance 2.0 **relay** reference-to-video request, and mention it from the prompt with `@Image1` (first image = `@Image1`, second = `@Image2`, …).

> **Use the authenticated relay endpoint.** Face-authenticated (Ark) assets are only recognized on the relay models — `bytedance/seedance-2.0-relay` and `bytedance/seedance-2.0-fast-relay`. Pass the asset as `asset://<ark_asset_id>` (not a URL). The non-relay `bytedance/seedance-2.0(-fast)` models go straight to Volcengine and will reject `asset://` with `InvalidParameter`.

```
POST https://api.sunra.ai/v1/queue/bytedance/seedance-2.0-fast-relay/reference-to-video
```

| Field              | Type                        | Description                                        |
| ------------------ | --------------------------- | -------------------------------------------------- |
| `prompt`           | string                      | Prompt; reference the asset with `@Image1`.        |
| `reference_images` | string\[]                   | 0–9 references. Put `asset://<ark_asset_id>` here. |
| `resolution`       | `480p` \| `720p` \| `1080p` | Output resolution (default `720p`).                |
| `ratio`            | string                      | Aspect ratio; `adaptive` auto-selects.             |
| `duration`         | integer                     | Seconds, 4–15 (or `-1` for auto).                  |
| `generate_audio`   | boolean                     | Generate synchronized audio (default `true`).      |

(Also available without the `-fast` suffix: `bytedance/seedance-2.0-relay/reference-to-video`.)

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.sunra.ai/v1/queue/bytedance/seedance-2.0-fast-relay/reference-to-video" \
    -H "Authorization: Bearer $SUNRA_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "prompt": "the person in @Image1 is talking to the camera",
      "reference_images": ["asset://<ARK_ASSET_ID>"],
      "resolution": "720p",
      "ratio": "adaptive",
      "duration": 5,
      "generate_audio": true
    }'
  ```

  ```python Python theme={null}
  import os, requests

  asset_id = asset["ark_asset_id"]  # from create/get, once status == "active"

  resp = requests.post(
      "https://api.sunra.ai/v1/queue/bytedance/seedance-2.0-fast-relay/reference-to-video",
      headers={"Authorization": f"Bearer {os.environ['SUNRA_API_KEY']}"},
      json={
          "prompt": "the person in @Image1 is talking to the camera",
          "reference_images": [f"asset://{asset_id}"],
          "resolution": "720p",
          "ratio": "adaptive",
          "duration": 5,
          "generate_audio": True,
      },
  )
  print(resp.json()["request_id"])
  ```
</CodeGroup>

Then poll the returned `status_url` until the prediction finishes (see [Queue](/multimodal/queue)). If the upstream model's content moderation rejects the input, the prediction completes with `success: false` and an `unsafe_content` error — revise the prompt or reference image and retry. (Real faces combined with minor-implying prompts are a common trigger.)
