# Ark Global Billing Reference (USD)

Billing setup manual for downstream deployments. Covers three billing paths: Seedance **per-token**, Seedance **per-second**, and Seedream **per-image**.

Basis: **this site prices in USD (international pricing), not CNY**. Use the official USD price directly, with no exchange rate applied.

> **Every price below is in USD.** Enter the USD figure as-is; never enter the CNY equivalent. For a rough CNY reading, assume **≈ 6.7 CNY = 1 USD** — that conversion is a reference only, and the charge itself is the USD amount.

> The official overseas model names are written `dreamina-seedance-*`. This site and the plugin use `doubao-seedance-*`; they are the same models.

## Downstream setup steps

1. Install the `doubao` task plugin (`plugin.js` ships its own model list and usage facts; leave it unmodified).
2. Create a channel: type **New API (60)**, Base URL set to the upstream gateway, Key set to the upstream token. The plugin appends the `/doubao` prefix automatically.
3. Set prices: in the pricing editor, give every model you sell one expression line; copy the formulas below.
4. Verify billing: send one short video first and check that the bill matches "seconds × per-second unit price".

## Common rules

| Item | Description |
| --- | --- |
| Unit of the expression's return value | **USD**. The system then multiplies by `QuotaPerUnit` (default 500000 quota = 1 USD) to get quota |
| Priority | Plugin-level is checked first and wins on a hit; model-level applies only when nothing matched. **If you change both, keep them consistent**, or the old value stays in effect |
| When no expression is configured | That model falls back to the plain model ratio and the bill drifts. **Every model you sell must have one line** |

## 1. Seedance per-token billing

### Usage facts

The plugin reports three facts from the request and the upstream response:

| Fact | Value | Meaning |
| --- | --- | --- |
| `tokens` | number | Upstream `usage.completion_tokens`; estimated at submit time as `seconds × width × height × 24 ÷ 1024` |
| `resolution` | `480p` / `720p` / `1080p` / `4k` | Output tier; the unit price changes with it |
| `video_input` | `none` / `video` | Whether a reference video is attached; with video a lower unit price applies |

### Formula

```
cost (USD) = tokens × USD per million tokens for that tier ÷ 1,000,000
```

### USD per million tokens (official online-inference price)

| Model | 480p / 720p | 1080p | 4K |
| --- | --- | --- | --- |
| `doubao-seedance-2-0-260128` | 7.0 / 4.3 | 7.7 / 4.7 | 4.0 / 2.4 |
| `doubao-seedance-2-0-fast-260128` | 5.6 / 3.3 | — | — |
| `doubao-seedance-2-0-mini-260615` | 3.5 / 2.1 | — | — |
| `doubao-seedance-2-5-260628` | 10.7 / 6.4 | 11.7 / 7.0 | — |

Each cell is written "**no reference video / with reference video**". A row with a single value means both inputs cost the same.

Notes:

- `—` means the tier is not supported upstream.
- Seedance 1.0 (pro / pro fast / lite) and 1.5 pro are **no longer sold** and are not listed here; the plugin no longer declares them.
- The offline-inference prices on the official page do not apply to an online gateway; do not use them here.

### Ready-to-paste billing expressions

All figures in these formulas are **USD unit prices** — paste them unchanged and do not convert to CNY.

Every model lists "resolution × reference video" per tier, with the last branch as the fallback so no bare condition is left.

**`doubao-seedance-2-0-260128`**

```
u("resolution") == "480p" && u("video_input") == "none" ? tier("480p·none", u("tokens") * 7 / 1000000) : u("resolution") == "480p" && u("video_input") == "video" ? tier("480p·video", u("tokens") * 4.3 / 1000000) : u("resolution") == "720p" && u("video_input") == "none" ? tier("720p·none", u("tokens") * 7 / 1000000) : u("resolution") == "720p" && u("video_input") == "video" ? tier("720p·video", u("tokens") * 4.3 / 1000000) : u("resolution") == "1080p" && u("video_input") == "none" ? tier("1080p·none", u("tokens") * 7.7 / 1000000) : u("resolution") == "1080p" && u("video_input") == "video" ? tier("1080p·video", u("tokens") * 4.7 / 1000000) : u("resolution") == "4k" && u("video_input") == "none" ? tier("4k·none", u("tokens") * 4 / 1000000) : tier("4k·video", u("tokens") * 2.4 / 1000000)
```

**`doubao-seedance-2-0-fast-260128`**

```
u("resolution") == "480p" && u("video_input") == "none" ? tier("480p·none", u("tokens") * 5.6 / 1000000) : u("resolution") == "480p" && u("video_input") == "video" ? tier("480p·video", u("tokens") * 3.3 / 1000000) : u("resolution") == "720p" && u("video_input") == "none" ? tier("720p·none", u("tokens") * 5.6 / 1000000) : tier("720p·video", u("tokens") * 3.3 / 1000000)
```

**`doubao-seedance-2-0-mini-260615`**

```
u("resolution") == "480p" && u("video_input") == "none" ? tier("480p·none", u("tokens") * 3.5 / 1000000) : u("resolution") == "480p" && u("video_input") == "video" ? tier("480p·video", u("tokens") * 2.1 / 1000000) : u("resolution") == "720p" && u("video_input") == "none" ? tier("720p·none", u("tokens") * 3.5 / 1000000) : tier("720p·video", u("tokens") * 2.1 / 1000000)
```

**`doubao-seedance-2-5-260628`**

```
u("resolution") == "480p" && u("video_input") == "none" ? tier("480p·none", u("tokens") * 10.7 / 1000000) : u("resolution") == "480p" && u("video_input") == "video" ? tier("480p·video", u("tokens") * 6.4 / 1000000) : u("resolution") == "720p" && u("video_input") == "none" ? tier("720p·none", u("tokens") * 10.7 / 1000000) : u("resolution") == "720p" && u("video_input") == "video" ? tier("720p·video", u("tokens") * 6.4 / 1000000) : u("resolution") == "1080p" && u("video_input") == "none" ? tier("1080p·none", u("tokens") * 11.7 / 1000000) : tier("1080p·video", u("tokens") * 7 / 1000000)
```

## 2. Seedance per-second billing

Per-second billing is a layer of **plan names**, distinct from upstream model names. The `model` a client sends is one of the four below, and the channel's `model_mapping` maps it to the real Volcengine Ark endpoint:

`seedance-2.0`, `seedance-2.0-fast`, `seedance-2.0-mini`, `seedance-2.5`

### Usage facts

| Fact | Value | Meaning |
| --- | --- | --- |
| `seconds` | number | The **reference video duration plus the generated duration**, combined |
| `resolution` | a tier the plan supports | Output tier; the per-second unit price changes with it |
| `video_input` | `none` / `video` | Whether a reference video is attached |

Per-second models have **no `tokens`** in their usage. Writing `u("tokens")` in an expression throws `invalid operation: <nil> * float64` at evaluation time.

### Formula

```
cost (USD) = seconds × USD per second for that tier
```

`seconds` is derived from the billing tokens Ark returns, not from the requested duration:

```
seconds = usage.completion_tokens ÷ tokens per second of that tier
```

`tokens per second` comes from the maximum 16:9 pixels via the official formula `width × height × 24 ÷ 1024`:

| Tier | 16:9 pixels | tokens/second |
| --- | --- | --- |
| 480p (2.0 / fast / mini) | 864 × 496 | 10044 |
| 480p (2.5) | 854 × 480 | 9607.5 |
| 720p | 1280 × 720 | 21600 |
| 1080p | 1920 × 1080 | 48600 |
| 4K | 3840 × 2160 | 194400 |

### USD per second

```
per-second price = tokens/second of that tier × USD per million tokens of that tier ÷ 1,000,000
```

Round the result **to four decimal places, rounding up**. Each cell is written "**no reference video / with reference video**":

| Plan | 480p | 720p | 1080p | 4K |
| --- | --- | --- | --- | --- |
| `seedance-2.0` | 0.0704 / 0.0432 | 0.1512 / 0.0929 | 0.3743 / 0.2285 | 0.7776 / 0.4666 |
| `seedance-2.0-fast` | 0.0563 / 0.0332 | 0.1210 / 0.0713 | — | — |
| `seedance-2.0-mini` | 0.0352 / 0.0211 | 0.0756 / 0.0454 | — | — |
| `seedance-2.5` | 0.1029 / 0.0615 | 0.2312 / 0.1383 | 0.5687 / 0.3402 | — |

### Ready-to-paste billing expressions

All figures in these formulas are **USD unit prices** — paste them unchanged and do not convert to CNY.

**`seedance-2.0`**

```
u("resolution") == "480p" && u("video_input") == "none" ? tier("480p·none", u("seconds") * 0.0704) : u("resolution") == "480p" && u("video_input") == "video" ? tier("480p·video", u("seconds") * 0.0432) : u("resolution") == "720p" && u("video_input") == "none" ? tier("720p·none", u("seconds") * 0.1512) : u("resolution") == "720p" && u("video_input") == "video" ? tier("720p·video", u("seconds") * 0.0929) : u("resolution") == "1080p" && u("video_input") == "none" ? tier("1080p·none", u("seconds") * 0.3743) : u("resolution") == "1080p" && u("video_input") == "video" ? tier("1080p·video", u("seconds") * 0.2285) : u("resolution") == "4k" && u("video_input") == "none" ? tier("4k·none", u("seconds") * 0.7776) : tier("4k·video", u("seconds") * 0.4666)
```

**`seedance-2.0-fast`**

```
u("resolution") == "480p" && u("video_input") == "none" ? tier("480p·none", u("seconds") * 0.0563) : u("resolution") == "480p" && u("video_input") == "video" ? tier("480p·video", u("seconds") * 0.0332) : u("resolution") == "720p" && u("video_input") == "none" ? tier("720p·none", u("seconds") * 0.121) : tier("720p·video", u("seconds") * 0.0713)
```

**`seedance-2.0-mini`**

```
u("resolution") == "480p" && u("video_input") == "none" ? tier("480p·none", u("seconds") * 0.0352) : u("resolution") == "480p" && u("video_input") == "video" ? tier("480p·video", u("seconds") * 0.0211) : u("resolution") == "720p" && u("video_input") == "none" ? tier("720p·none", u("seconds") * 0.0756) : tier("720p·video", u("seconds") * 0.0454)
```

**`seedance-2.5`**

```
u("resolution") == "480p" && u("video_input") == "none" ? tier("480p·none", u("seconds") * 0.1029) : u("resolution") == "480p" && u("video_input") == "video" ? tier("480p·video", u("seconds") * 0.0615) : u("resolution") == "720p" && u("video_input") == "none" ? tier("720p·none", u("seconds") * 0.2312) : u("resolution") == "720p" && u("video_input") == "video" ? tier("720p·video", u("seconds") * 0.1383) : u("resolution") == "1080p" && u("video_input") == "none" ? tier("1080p·none", u("seconds") * 0.5687) : tier("1080p·video", u("seconds") * 0.3402)
```

### Verification

Send a `seedance-2.0` 720p request with a 5-second reference video generating 5 seconds:

| Item | Expected |
| --- | --- |
| `seconds` in the log | 10 |
| Bill | 10 × 0.0929 = $0.929 |

If `seconds` reads 5, the reference video was not recognized: check that the `role` of the `video_url` item in `content` is `reference_video`.

## 3. Seedream per-image billing

### Usage facts

Image tasks are priced by **the number of successfully delivered images**; failed members of a group are not billed. Four facts:

| Fact | Type | Meaning |
| --- | --- | --- |
| `images_up_to_1_5k` | number | Outputs with a pixel area ≤ 2610000 (1K / 1.5K and below) |
| `images_above_1_5k` | number | Outputs with a pixel area > 2610000 (2K and above) |
| `input_images` | number | Number of reference images, from the upstream `usage.input_images` |
| `layer_decomposition` | boolean | Whether layer decomposition is enabled |

The boundary `2610000` pixels corresponds to the official "2.61 megapixel" line; 1K and 1.5K cost the same. Each image is classified by its own pixel area, and every layer that layer decomposition produces is priced on its own.

Reference images are charged per image, including the first one. The official price list says "the first image is free"; this site deliberately does not apply that discount: making the first one free requires `max(input_images - 1, 0)`, and the price-table expander only understands linear terms, so that form would degrade the model details page into a "custom billing expression". The difference is an extra 0.003 per order that carries a reference image. To be updated once new-api supports it.

### Formula

```
cost (USD) = images_up_to_1_5k × low-tier price
           + images_above_1_5k × high-tier price
           + input_images × reference-image price
```

### USD prices

| Model | `images_up_to_1_5k` | `images_above_1_5k` | `input_images` |
| --- | --- | --- | --- |
| `doubao-seedream-5-0-pro-260628` | 0.045 | 0.09 | 0.003 |
| `doubao-seedream-5-0-flash-260915` | 0.018 | 0.018 | 0 |

Key points:

- **flash prices 1.5K and 2K the same** (0.018), and reference images are not charged separately.
- **pro's high-tier price is twice the low tier** (0.09 / 0.045); reference images cost 0.003 each, including the first.

### Ready-to-paste billing expressions

All figures in these formulas are **USD unit prices** — paste them unchanged and do not convert to CNY.

**`doubao-seedream-5-0-pro-260628`**

```
tier("base", u("images_above_1_5k") * 0.09 + u("images_up_to_1_5k") * 0.045 + u("input_images") * 0.003)
```

**`doubao-seedream-5-0-flash-260915`**

```
tier("base", u("images_above_1_5k") * 0.018 + u("images_up_to_1_5k") * 0.018 + u("input_images") * 0)
```

Layer decomposition needs no surcharge: each layer it produces is itself an output and is already counted in `images_*`.

## Notes

- The prices above are **the official list price at zero margin**. For a model discount, apply a group multiplier to the token price; the per-token, per-second and per-image paths are adjusted independently and do not affect each other.
- When no resolution is given, the plugin reserves billing at 720p, the vendor's own default (2.0 / 2.5 / fast / mini alike), and writes that tier into the request body, so Ark renders at that tier and the reservation matches the actual output.
- The reference video's duration is already included in the billing tokens Ark returns and is converted to seconds by the completion callback; no extra duration needs to be added.
- Per-second models keep `seconds` as a decimal rather than rounding to an integer, otherwise every short video would lose up to half a second.
