# Tracks | AudioDN Docs

> API endpoints for uploading, updating, listing, and deleting audio tracks. Manage track metadata, cover images, and player display settings.

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

---

# Tracks

Tracks are individual audio files within collections. Manage track metadata, uploads, playback information, and deletion.

Responses include two read-only companions to `player_color`: `player_color_light` (adjusted to stay legible on a light background) and `player_color_dark` (adjusted for a dark background). They are derived from `player_color` by shifting brightness until each meets a minimum contrast, so you can always render the player color on either theme. They cannot be set directly.

GET `/v1/track/:track_id`

Returns details about a specific track

#### Parameters

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

#### Example Request

    

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

```
const response = await fetch('https://api.audiodelivery.net/v1/track/TRACK_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/track/TRACK_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/track/TRACK_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/track/TRACK_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",
  "track_id": "uuid",
  "track": {
    "id": "uuid",
    "organization_id": "uuid",
    "collection_id": "uuid",
    "creator_id": "uuid | null",
    "index": "string",
    "duration": 0,
    "file_name": "string",
    "file_name_original": "string | null",
    "info": {},
    "organization_index": "string | null",
    "order": 0,
    "metadata": {},
    "player_title": "string | null",
    "player_subtitle": "string | null",
    "player_color": "string | null",
    "player_color_light": "string | null",
    "player_color_dark": "string | null",
    "theme": [],
    "track_status_id": "string"
  }
}
```

GET `/v1/collection/:collection_id/track`

Returns a list of tracks in a collection

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `collection_id` | uuid | Required | The ID of the collection (path parameter) |
| `limit` | number | Optional | Maximum number of tracks to return |
| `offset` | number | Optional | Number of tracks to skip |

#### Response

```
{
  "ok": true,
  "api_request_id": "uuid",
  "count": 0,
  "tracks": [
    {
      "id": "uuid",
      "organization_id": "uuid",
      "collection_id": "uuid",
      "index": "string",
      "duration": 0,
      "file_name": "string",
      "order": 0,
      "metadata": {},
      "player_title": "string | null",
      "player_subtitle": "string | null",
      "player_color": "string | null",
      "player_color_light": "string | null",
      "player_color_dark": "string | null",
      "theme": [],
      "track_status_id": "string"
    }
  ]
}
```

POST `/v1/track`

Creates a new track

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `collection_id` | uuid | Required | ID of the collection this track belongs to |
| `file_name` | string | Required | Original filename of the track |
| `creator_id` | uuid | Optional | ID of the creator |
| `organization_index` | string | Optional | Organization Identifier for the track |
| `metadata` | object | Optional | Organization metadata for the track |
| `is_cover_overridable` | boolean | Optional | Whether track cover can be overridden |
| `is_theme_overridable` | boolean | Optional | Whether track image colors can be overridden |
| `player_title` | string | Optional | Title to display in the player |
| `player_subtitle` | string | Optional | Subtitle to display in the player |
| `player_color` | string | Optional | Color to use in the player (hex) |

#### Example Request

    

```
curl -X POST "https://api.audiodelivery.net/v1/track" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"collection_id": "COLLECTION_ID", "file_name": "my-audio-track.mp3", "player_title": "Track Title"}'
```

```
const response = await fetch('https://api.audiodelivery.net/v1/track', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({"collection_id": "COLLECTION_ID", "file_name": "my-audio-track.mp3", "player_title": "Track Title"})
});

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

```
import Foundation

func performRequest() async throws {
    var request = URLRequest(url: URL(string: "https://api.audiodelivery.net/v1/track")!)
    request.httpMethod = "POST"
    request.setValue("Bearer YOUR_API_KEY", forHTTPHeaderField: "Authorization")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    let body = {"collection_id": "COLLECTION_ID", "file_name": "my-audio-track.mp3", "player_title": "Track Title"}
    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 = """{"collection_id": "COLLECTION_ID", "file_name": "my-audio-track.mp3", "player_title": "Track Title"}""".toRequestBody("application/json".toMediaType())
    val request = Request.Builder()
        .url("https://api.audiodelivery.net/v1/track")
        .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'),
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: jsonEncode({"collection_id": "COLLECTION_ID", "file_name": "my-audio-track.mp3", "player_title": "Track Title"}),
  );
  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",
  "track": {
    "id": "uuid",
    "organization_id": "uuid",
    "collection_id": "uuid",
    "index": "string",
    "duration": 0,
    "file_name": "string",
    "order": 0,
    "metadata": {},
    "player_title": "string | null",
    "player_subtitle": "string | null",
    "player_color": "string | null",
    "player_color_light": "string | null",
    "player_color_dark": "string | null",
    "theme": [],
    "track_status_id": "string"
  },
  "track_upload": {
    "method": "PUT",
    "upload_url": "string",
    "ttl": 3600,
    "expires_at": "string"
  },
  "track_cover_upload": {
    "method": "POST",
    "upload_url": "string",
    "ttl": 3600,
    "expires_at": "string"
  }
}
```

PUT `/v1/track/:track_id`

Updates an existing track

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `track_id` | uuid | Required | The ID of the track to update (path parameter) |
| `creator_id` | uuid | Optional | ID of the creator |
| `organization_index` | string | Optional | Organization Identifier for the track |
| `title` | string | Optional | Title of the track |
| `metadata` | object | Optional | Organization metadata |
| `is_cover_overridable` | boolean | Optional | Whether track cover can be overridden |
| `is_theme_overridable` | boolean | Optional | Whether track image colors can be overridden |
| `player_title` | string | Optional | Title to display in the player |
| `player_subtitle` | string | Optional | Subtitle to display in the player |
| `player_color` | string | Optional | Color to use in the player (hex) |

#### Response

```
{
  "ok": true,
  "api_request_id": "uuid",
  "track_id": "uuid",
  "track": {
    "id": "uuid",
    "organization_id": "uuid",
    "collection_id": "uuid",
    "index": "string",
    "duration": 0,
    "file_name": "string",
    "order": 0,
    "metadata": {},
    "player_title": "string | null",
    "player_subtitle": "string | null",
    "player_color": "string | null",
    "player_color_light": "string | null",
    "player_color_dark": "string | null",
    "theme": [],
    "track_status_id": "string"
  }
}
```

DELETE `/v1/track/:track_id`

Soft-deletes a track and cascades to its files and variants

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `track_id` | uuid | Required | The ID of the track to delete (path parameter) |

Deleting a track **cascades**: its variants and files are soft-deleted too, and the removed files are queued for deletion from R2 storage.

#### Example Request

    

```
curl -X DELETE "https://api.audiodelivery.net/v1/track/TRACK_ID" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```
const response = await fetch('https://api.audiodelivery.net/v1/track/TRACK_ID', {
  method: 'DELETE',
  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/track/TRACK_ID")!)
    request.httpMethod = "DELETE"
    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/track/TRACK_ID")
        .delete()
        .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.delete(
    Uri.parse('https://api.audiodelivery.net/v1/track/TRACK_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",
  "track_id": "uuid",
  "deleted_track": {
    "id": "uuid",
    "organization_id": "uuid",
    "collection_id": "uuid",
    "index": "string",
    "duration": 0,
    "file_name": "string",
    "order": 0,
    "metadata": {},
    "player_title": "string | null",
    "player_subtitle": "string | null",
    "player_color": "string | null",
    "player_color_light": "string | null",
    "player_color_dark": "string | null",
    "theme": [],
    "track_status_id": "string"
  }
}
```
