# Upload-Sessions | AudioDN Docs

> API-Endpunkte zum Erstellen sicherer Upload-Sessions. Ermöglichen authentifizierte, zeitlich begrenzte Audio-Datei-Uploads in Sammlungen.

Source: https://audiodeliverynetwork.com/de/docs/api/upload-sessions/

---

# Upload-Sessions

Upload-Sessions ermöglichen den Batch-Upload mehrerer Tracks in eine Sammlung. Optional können Sie beim Erstellen der Session ein verschachteltes `track`\-Objekt mitsenden, um diesen Track ebenfalls zu erstellen und seine Upload-URL in der Antwort zu erhalten.

Die aufgelöste `player_color` wird von zwei schreibgeschützten Begleitfeldern begleitet, `player_color_light` und `player_color_dark`, angepasst für Lesbarkeit auf hellen bzw. dunklen Hintergründen.

POST `/v1/upload_session`

Erstellt eine neue Upload-Session für den Batch-Upload von Tracks. Standardmäßig wird nur eine upload\_session\_id zurückgegeben — erstellen Sie Tracks über POST /v1/upload/:upload\_session\_id/track. Optional ein verschachteltes track-Objekt mitsenden, um diesen Track ebenfalls zu erstellen und die track-spezifische Upload-URL in dieser Antwort zu erhalten.

#### Parameter

| Name | Typ | Erforderlich | Beschreibung |
| --- | --- | --- | --- |
| `collection_id` | uuid | Erforderlich | Sammlungs-ID. Erforderlich, sofern der API-Key nicht auf eine Sammlung beschränkt ist. |
| `creator_id` | uuid | Optional | Creator-ID |
| `organization_index` | string | Optional | Organisations-Index (Session-Ebene) |
| `metadata` | object | Optional | Zusätzliche Metadaten (Session-Ebene) |
| `expires_in` | number | Optional | Session-Dauer in Sekunden (Standard: 3600, min: 60, max: 86400) |
| `track` Optionaler Track | object | Optional | Wenn vorhanden, erstellt auch diesen Track und fügt seine Upload-Felder zur Antwort hinzu. Verschachtelte Felder: file\_name, organization\_index, metadata. |
| `track.file_name` Optionaler Track | string | Erforderlich | Originaler Dateiname des Tracks. Erforderlich, wenn track vorhanden ist. |
| `track.organization_index` Optionaler Track | string | Optional | Organisations-Index für den Track (getrennt vom Session-Ebenen-Feld). |
| `track.metadata` Optionaler Track | object | Optional | Metadaten für den Track (getrennt vom Session-Ebenen-Feld). |

#### Beispielanfrage

    

```
curl -X POST "https://api.audiodelivery.net/v1/upload_session" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "collection_id": "COLLECTION_ID",
  "expires_in": 7200
}'
```

```
const payload = {
  "collection_id": "COLLECTION_ID",
  "expires_in": 7200
};

const response = await fetch('https://api.audiodelivery.net/v1/upload_session', {
  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/upload_session")!)
    request.httpMethod = "POST"
    request.setValue("Bearer YOUR_API_KEY", forHTTPHeaderField: "Authorization")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    let bodyJSON = """
{
  "collection_id": "COLLECTION_ID",
  "expires_in": 7200
}
"""
    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",
  "expires_in": 7200
}""".toRequestBody("application/json".toMediaType())
    val request = Request.Builder()
        .url("https://api.audiodelivery.net/v1/upload_session")
        .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/upload_session"),
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: jsonEncode({
  "collection_id": "COLLECTION_ID",
  "expires_in": 7200
}),
  );
  if (response.statusCode < 200 || response.statusCode >= 300) {
    throw Exception('Request failed: ${response.statusCode}');
  }
  return jsonDecode(response.body) as Map<String, dynamic>;
}
```

Beispiel mit optionalem verschachteltem `track`:

#### Beispielanfrage

    

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

```
const payload = {
  "collection_id": "COLLECTION_ID",
  "track": {
    "file_name": "track-1.mp3"
  }
};

const response = await fetch('https://api.audiodelivery.net/v1/upload_session', {
  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/upload_session")!)
    request.httpMethod = "POST"
    request.setValue("Bearer YOUR_API_KEY", forHTTPHeaderField: "Authorization")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    let bodyJSON = """
{
  "collection_id": "COLLECTION_ID",
  "track": {
    "file_name": "track-1.mp3"
  }
}
"""
    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",
  "track": {
    "file_name": "track-1.mp3"
  }
}""".toRequestBody("application/json".toMediaType())
    val request = Request.Builder()
        .url("https://api.audiodelivery.net/v1/upload_session")
        .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/upload_session"),
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: jsonEncode({
  "collection_id": "COLLECTION_ID",
  "track": {
    "file_name": "track-1.mp3"
  }
}),
  );
  if (response.statusCode < 200 || response.statusCode >= 300) {
    throw Exception('Request failed: ${response.statusCode}');
  }
  return jsonDecode(response.body) as Map<String, dynamic>;
}
```

#### Optionaler verschachtelter Track

Fügen Sie ein verschachteltes `track`\-Objekt hinzu, um diesen Track während der Session-Erstellung anzulegen — die Antwort ergänzt dieselben Upload-Handles wie der track-spezifische Endpunkt. Sie können später weiterhin weitere Tracks mit `POST /v1/upload/:upload_session_id/track` hinzufügen. Für reine Batch-Flows lassen Sie `track` weg und erstellen Sie jeden Track über diesen Endpunkt.

#### Antwort

```
{
"ok": true,
"upload_session_id": "uuid",
"upload_session": {
  "id": "uuid",
  "creator_id": "uuid | null",
  "collection_id": "uuid",
  "organization_index": "string | null",
  "metadata": {},
  "expires_at": "string"
},
"player_color": "string | null",
"player_color_light": "string | null",
"player_color_dark": "string | null",
"expires_at": "string"
}
```

#### Antwort, wenn Sie `track` mitsenden

```
{
"ok": true,
"upload_session_id": "uuid",
"upload_session": {
  "id": "uuid",
  "creator_id": "uuid | null",
  "collection_id": "uuid",
  "organization_index": "string | null",
  "metadata": {},
  "expires_at": "string"
},
"player_color": "string | null",
"player_color_light": "string | null",
"player_color_dark": "string | null",
"expires_at": "string",
"track_id": "uuid",
"track": {
  "id": "uuid",
  "index": "string",
  "path": "string",
  "upload_url": "string"
},
"track_upload": {
  "method": "PUT",
  "upload_url": "string",
  "ttl": 0,
  "expires_at": "string"
},
"track_cover_upload": {
  "method": "POST",
  "upload_url": "string",
  "ttl": 0,
  "expires_at": "string"
}
}
```

GET `/v1/upload_session/:upload_session_id`

Ruft Details einer Upload-Session ab. Keine Authentifizierung erforderlich — die Session-ID dient als Berechtigungsnachweis.

#### Parameter

| Name | Typ | Erforderlich | Beschreibung |
| --- | --- | --- | --- |
| `upload_session_id` | uuid | Erforderlich | Die ID der Upload-Session (Pfadparameter) |

#### Beispielanfrage

    

```
curl -X GET "https://api.audiodelivery.net/v1/upload_session/SESSION_ID"
```

```
const response = await fetch('https://api.audiodelivery.net/v1/upload_session/SESSION_ID');

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

```
import Foundation

func performRequest() async throws {
    var request = URLRequest(url: URL(string: "https://api.audiodelivery.net/v1/upload_session/SESSION_ID")!)
    request.httpMethod = "GET"

    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/upload_session/SESSION_ID")

        .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/upload_session/SESSION_ID"));
  if (response.statusCode < 200 || response.statusCode >= 300) {
    throw Exception('Request failed: ${response.statusCode}');
  }
  return jsonDecode(response.body) as Map<String, dynamic>;
}
```

#### Antwort

```
{
"ok": true,
"upload_session_id": "uuid",
"upload_session": {
  "id": "uuid",
  "creator_id": "uuid | null",
  "collection_id": "uuid",
  "organization_index": "string | null",
  "metadata": {},
  "expires_at": "string"
},
"player_color": "string | null",
"player_color_light": "string | null",
"player_color_dark": "string | null",
"expires_at": "string"
}
```

POST `/v1/upload/:upload_session_id/track`

Erstellt einen neuen Track in einer Upload-Session und gibt seine track-spezifische Upload-URL zurück. Rufen Sie dies einmal pro Datei auf (einschließlich jeder weiteren Datei nach einem optionalen verschachtelten Track bei der Session-Erstellung). Keine Authentifizierung erforderlich — die Session-ID dient als Berechtigungsnachweis.

#### Parameter

| Name | Typ | Erforderlich | Beschreibung |
| --- | --- | --- | --- |
| `upload_session_id` | uuid | Erforderlich | Die ID der Upload-Session (Pfadparameter) |
| `file_name` | string | Erforderlich | Originaler Dateiname des Tracks |
| `organization_index` | string | Optional | Organisations-Index |
| `metadata` | object | Optional | Zusätzliche Metadaten |

#### Beispielanfrage

    

```
curl -X POST "https://api.audiodelivery.net/v1/upload/SESSION_ID/track" \
  -H "Content-Type: application/json" \
  -d '{
  "file_name": "track-1.mp3"
}'
```

```
const payload = {
  "file_name": "track-1.mp3"
};

const response = await fetch('https://api.audiodelivery.net/v1/upload/SESSION_ID/track', {
  method: 'POST',
  headers: {
    '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/upload/SESSION_ID/track")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    let bodyJSON = """
{
  "file_name": "track-1.mp3"
}
"""
    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 = """{
  "file_name": "track-1.mp3"
}""".toRequestBody("application/json".toMediaType())
    val request = Request.Builder()
        .url("https://api.audiodelivery.net/v1/upload/SESSION_ID/track")
        .post(body)
        .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/upload/SESSION_ID/track"),
    headers: {
      "Content-Type": "application/json",
    },
    body: jsonEncode({
  "file_name": "track-1.mp3"
}),
  );
  if (response.statusCode < 200 || response.statusCode >= 300) {
    throw Exception('Request failed: ${response.statusCode}');
  }
  return jsonDecode(response.body) as Map<String, dynamic>;
}
```

#### Antwort

```
{
"ok": true,
"api_request_id": "uuid",
"upload_session_id": "uuid",
"track_id": "uuid",
"track": {
  "id": "uuid",
  "index": "string",
  "path": "string",
  "upload_url": "string"
},
"upload_session": {
  "id": "uuid",
  "creator_id": "uuid | null",
  "collection_id": "uuid",
  "organization_index": "string | null",
  "metadata": {},
  "expires_at": "string"
},
"track_upload": {
  "method": "PUT",
  "upload_url": "string",
  "ttl": 0,
  "expires_at": "string"
},
"track_cover_upload": {
  "method": "POST",
  "upload_url": "string",
  "ttl": 0,
  "expires_at": "string"
}
}
```
