# Variants | AudioDN Docs

> API endpoints for configuring audio variant types. Set up transcoding profiles, preview clips, waveform generation, and quality tiers.

Source: https://audiodeliverynetwork.com/docs/api/variants/

---

# Variants

A variant is a reusable recipe that defines an output to generate from every upload—a transcode, preview, waveform, or analysis—and each result is stored as a track file on the track. Organization-wide variants (applied to every upload) are created on the website. You can also add a **track-specific variant** to a single, already-processed track via the API—handy for generating an extra format or a preview clip on demand.

GET `/v1/variant`

Returns a list of variants for an organization

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | number | Optional | Maximum number of variants to return |
| `offset` | number | Optional | Number of variants to skip |

#### Example Request

    

```
curl -X GET "https://api.audiodelivery.net/v1/variant" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```
const response = await fetch('https://api.audiodelivery.net/v1/variant', {
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

const data = await response.json();
```

```
import Foundation

func performRequest() async throws {
    var request = URLRequest(url: URL(string: "https://api.audiodelivery.net/v1/variant")!)
    request.setValue("Bearer YOUR_API_KEY", forHTTPHeaderField: "Authorization")
    let (data, _) = try await URLSession.shared.data(for: request)
    let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
    // use json
}
```

```
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.*

val client = OkHttpClient()

suspend fun performRequest(): String = withContext(Dispatchers.IO) {
    val request = Request.Builder()
        .url("https://api.audiodelivery.net/v1/variant")
        .addHeader("Authorization", "Bearer YOUR_API_KEY")
        .build()
    val response = client.newCall(request).execute()
    response.body?.string() ?: error("Empty response body")
}
```

```
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<Map<String, dynamic>> performRequest() async {
  final response = await http.get(
    Uri.parse('https://api.audiodelivery.net/v1/variant'),
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
    },
  );
  if (response.statusCode < 200 || response.statusCode >= 300) {
    throw Exception('Request failed: ${response.statusCode}');
  }
  return jsonDecode(response.body) as Map<String, dynamic>;
}
```

#### Response

```
{
  "ok": true,
  "api_request_id": "uuid",
  "count": 0,
  "variants": [
    {
      "id": "uuid",
      "organization_id": "uuid",
      "variant_type_id": "string",
      "props": {}
    }
  ]
}
```

GET `/v1/variant/:variant_id`

Returns details about a specific variant

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `variant_id` | uuid | Required | The ID of the variant to retrieve (path parameter) |

#### Example Request

    

```
curl -X GET "https://api.audiodelivery.net/v1/variant/VARIANT_ID" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```
const response = await fetch('https://api.audiodelivery.net/v1/variant/VARIANT_ID', {
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY'
  }
});

const data = await response.json();
```

```
import Foundation

func performRequest() async throws {
    var request = URLRequest(url: URL(string: "https://api.audiodelivery.net/v1/variant/VARIANT_ID")!)
    request.setValue("Bearer YOUR_API_KEY", forHTTPHeaderField: "Authorization")
    let (data, _) = try await URLSession.shared.data(for: request)
    let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
    // use json
}
```

```
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.*

val client = OkHttpClient()

suspend fun performRequest(): String = withContext(Dispatchers.IO) {
    val request = Request.Builder()
        .url("https://api.audiodelivery.net/v1/variant/VARIANT_ID")
        .addHeader("Authorization", "Bearer YOUR_API_KEY")
        .build()
    val response = client.newCall(request).execute()
    response.body?.string() ?: error("Empty response body")
}
```

```
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<Map<String, dynamic>> performRequest() async {
  final response = await http.get(
    Uri.parse('https://api.audiodelivery.net/v1/variant/VARIANT_ID'),
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
    },
  );
  if (response.statusCode < 200 || response.statusCode >= 300) {
    throw Exception('Request failed: ${response.statusCode}');
  }
  return jsonDecode(response.body) as Map<String, dynamic>;
}
```

#### Response

```
{
  "ok": true,
  "api_request_id": "uuid",
  "variant_id": "uuid",
  "variant": {
    "id": "uuid",
    "organization_id": "uuid",
    "variant_type_id": "string",
    "props": {}
  }
}
```

POST `/v1/track/:track_id/variant`

Adds a track-specific variant to an already-processed track and queues processing for it

Appends a new track file to an existing track. The track is moved to `processing` while the new file is generated, then automatically returns to `ready`. Only `transcode` and `preview` are supported via this endpoint, and only lossy output codecs are allowed (`aac`, `mp3`, `ogg`, `opus`). Codec settings are optional and default to `aac` at `128` kbps.

#### Common parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `track_id` | uuid | Required | The track to append the variant to (path parameter) |
| `variant_type_id` | string | Required | 'transcode' (full-length file) or 'preview' (short clip). Determines which parameter set below applies |
| `index` | string | Required | Delivery name for the variant (2–64 chars, letters/numbers/\_/-). Must not collide with an existing organization or track variant |

#### When `variant_type_id` is `"transcode"`

Full-length alternate format. Example: `{ "variant_type_id": "transcode", "index": "mp3", "codec": "mp3", "bitrate": 192 }`.

#### Transcode parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `codec` | string | Optional | Output codec: aac (default), mp3, ogg, or opus. Lossless codecs (flac, alac) are not allowed |
| `bitrate` | number | Optional | Output bitrate in kbps, 12–320 (default 128). Only applies to codecs that use bitrate |
| `is_stereo` | boolean | Optional | Keep stereo output (default true). When false, output is mixed down to mono |
| `is_strip_tags` | boolean | Optional | Strip metadata tags from the output (default true) |
| `is_strip_cover` | boolean | Optional | Strip embedded cover art from the output (default true) |

#### When `variant_type_id` is `"preview"`

Short clip cut from the track. Also accepts the **Transcode parameters** above for the output audio (codec defaults to `aac` / `128`). Clip start is always a percentage of track duration (`preview_start_percent`).

#### Preview parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `preview_type` | string | Optional | 'seconds' (default) or 'percent' — how the clip length is measured |
| `preview_seconds` | number | Optional | When preview\_type is 'seconds': clip length in seconds (default 60) |
| `preview_min_percent` | number | Optional | When preview\_type is 'seconds': minimum clip length as a percent of duration, 0–100 (default 0) |
| `preview_max_percent` | number | Optional | When preview\_type is 'seconds': maximum clip length as a percent of duration, 0–100 (default 50) |
| `preview_percent` | number | Optional | When preview\_type is 'percent': clip length as a percent of duration, 0–100 (default 25) |
| `preview_min_seconds` | number | Optional | When preview\_type is 'percent': minimum clip length in seconds (default 0) |
| `preview_max_seconds` | number | Optional | When preview\_type is 'percent': maximum clip length in seconds (default 90) |
| `preview_start_percent` | number | Optional | Where the clip starts, as a percent of total duration, 0–100 (default 25). Always used regardless of preview\_type |

#### Example Request

    

```
curl -X POST "https://api.audiodelivery.net/v1/track/TRACK_ID/variant" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "variant_type_id": "preview",
  "index": "preview",
  "preview_type": "seconds",
  "preview_seconds": 3,
  "preview_min_percent": 0,
  "preview_max_percent": 100,
  "preview_start_percent": 25
}'
```

```
const response = await fetch('https://api.audiodelivery.net/v1/track/TRACK_ID/variant', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
  "variant_type_id": "preview",
  "index": "preview",
  "preview_type": "seconds",
  "preview_seconds": 3,
  "preview_min_percent": 0,
  "preview_max_percent": 100,
  "preview_start_percent": 25
})
});

const data = await response.json();
```

```
import Foundation

func performRequest() async throws {
    var request = URLRequest(url: URL(string: "https://api.audiodelivery.net/v1/track/TRACK_ID/variant")!)
    request.httpMethod = "POST"
    request.setValue("Bearer YOUR_API_KEY", forHTTPHeaderField: "Authorization")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    let body = {
  "variant_type_id": "preview",
  "index": "preview",
  "preview_type": "seconds",
  "preview_seconds": 3,
  "preview_min_percent": 0,
  "preview_max_percent": 100,
  "preview_start_percent": 25
}
    request.httpBody = try JSONSerialization.data(withJSONObject: body)
    let (data, _) = try await URLSession.shared.data(for: request)
    let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
    // use json
}
```

```
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody

val client = OkHttpClient()

suspend fun performRequest(): String = withContext(Dispatchers.IO) {
    val body = """{
  "variant_type_id": "preview",
  "index": "preview",
  "preview_type": "seconds",
  "preview_seconds": 3,
  "preview_min_percent": 0,
  "preview_max_percent": 100,
  "preview_start_percent": 25
}""".toRequestBody("application/json".toMediaType())
    val request = Request.Builder()
        .url("https://api.audiodelivery.net/v1/track/TRACK_ID/variant")
        .post(body)
        .addHeader("Authorization", "Bearer YOUR_API_KEY")
        .build()
    val response = client.newCall(request).execute()
    response.body?.string() ?: error("Empty response body")
}
```

```
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<Map<String, dynamic>> performRequest() async {
  final response = await http.post(
    Uri.parse('https://api.audiodelivery.net/v1/track/TRACK_ID/variant'),
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: jsonEncode({
  "variant_type_id": "preview",
  "index": "preview",
  "preview_type": "seconds",
  "preview_seconds": 3,
  "preview_min_percent": 0,
  "preview_max_percent": 100,
  "preview_start_percent": 25
}),
  );
  if (response.statusCode < 200 || response.statusCode >= 300) {
    throw Exception('Request failed: ${response.statusCode}');
  }
  return jsonDecode(response.body) as Map<String, dynamic>;
}
```

#### Response

```
{
  "ok": true,
  "api_request_id": "uuid",
  "track_id": "uuid",
  "variant_id": "uuid",
  "job_id": "uuid",
  "variant": {
    "id": "uuid",
    "organization_id": "uuid",
    "track_id": "uuid",
    "variant_type_id": "preview",
    "index": "preview",
    "props": {
      "preview_type": "seconds",
      "preview_seconds": 3,
      "preview_min_percent": 0,
      "preview_max_percent": 100,
      "preview_start_percent": 25,
      "codec": "aac",
      "bitrate": 128,
      "is_stereo": true,
      "is_strip_tags": true,
      "is_strip_cover": true
    }
  }
}
```
