# Pistas | Docs de AudioDN

> Endpoints de la API para subir, actualizar, listar y eliminar pistas de audio. Gestiona metadatos de pista, imágenes de portada y ajustes de visualización del player.

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

---

# Pistas

Las pistas son archivos de audio individuales dentro de colecciones. Gestiona metadatos de pista, subidas, información de reproducción y eliminación.

Las respuestas incluyen dos compañeros de solo lectura de `player_color`: `player_color_light` (ajustado para permanecer legible sobre un fondo claro) y `player_color_dark` (ajustado para un fondo oscuro). Se derivan de `player_color` desplazando el brillo hasta que cada uno cumple un contraste mínimo, para que siempre puedas renderizar el color del player en cualquiera de los temas. No se pueden establecer directamente.

GET `/v1/track/:track_id`

Devuelve detalles de una pista concreta

#### Parámetros

| Nombre | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `track_id` | uuid | Obligatorio | El ID de la pista a recuperar (parámetro de ruta) |

#### Ejemplo de solicitud

    

```
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.httpMethod = "GET"
    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>;
}
```

#### Respuesta

```
{
"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`

Devuelve una lista de pistas de una colección

#### Parámetros

| Nombre | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `collection_id` | uuid | Obligatorio | El ID de la colección (parámetro de ruta) |
| `limit` | number | Opcional | Número máximo de pistas a devolver |
| `offset` | number | Opcional | Número de pistas a omitir |

#### Respuesta

```
{
"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`

Crea una nueva pista

#### Parámetros

| Nombre | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `collection_id` | uuid | Obligatorio | ID de la colección a la que pertenece esta pista. Obligatorio salvo que la clave API tenga alcance a una colección. |
| `file_name` | string | Obligatorio | Nombre de archivo original de la pista |
| `creator_id` | uuid | Opcional | ID del creator |
| `organization_index` | string | Opcional | Identificador de organización de la pista |
| `metadata` | object | Opcional | Metadatos de organización de la pista |
| `is_cover_overridable` | boolean | Opcional | Si la portada de la pista se puede sobrescribir |
| `is_theme_overridable` | boolean | Opcional | Si los colores de imagen de la pista se pueden sobrescribir |
| `player_title` | string | Opcional | Título a mostrar en el player |
| `player_subtitle` | string | Opcional | Subtítulo a mostrar en el player |
| `player_color` | string | Opcional | Color a usar en el player (hex) |

#### Ejemplo de solicitud

    

```
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 payload = {
  "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(payload)
});

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 bodyJSON = """
{
  "collection_id": "COLLECTION_ID",
  "file_name": "my-audio-track.mp3",
  "player_title": "Track Title"
}
"""
    request.httpBody = bodyJSON.data(using: .utf8)
    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")
        .addHeader("Content-Type", "application/json")
        .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>;
}
```

#### Respuesta

```
{
"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`

Actualiza una pista existente

#### Parámetros

| Nombre | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `track_id` | uuid | Obligatorio | El ID de la pista a actualizar (parámetro de ruta) |
| `creator_id` | uuid | Opcional | ID del creator |
| `organization_index` | string | Opcional | Identificador de organización de la pista |
| `title` | string | Opcional | Título de la pista |
| `metadata` | object | Opcional | Metadatos de organización |
| `is_cover_overridable` | boolean | Opcional | Si la portada de la pista se puede sobrescribir |
| `is_theme_overridable` | boolean | Opcional | Si los colores de imagen de la pista se pueden sobrescribir |
| `player_title` | string | Opcional | Título a mostrar en el player |
| `player_subtitle` | string | Opcional | Subtítulo a mostrar en el player |
| `player_color` | string | Opcional | Color a usar en el player (hex) |

#### Respuesta

```
{
"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`

Elimina suavemente una pista y propaga a sus archivos y variantes

#### Parámetros

| Nombre | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `track_id` | uuid | Obligatorio | El ID de la pista a eliminar (parámetro de ruta) |

Eliminar una pista **propaga**: sus variantes y archivos también se eliminan suavemente, y los archivos eliminados se encolan para borrado del object storage.

#### Ejemplo de solicitud

    

```
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>;
}
```

#### Respuesta

```
{
"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"
}
}
```
