Collection-Sync-Webhook
Der Collection-Sync-Webhook hält Ihre Anwendung mit Ihren AudioDN-Sammlungen synchron. Jedes Mal, wenn eine Sammlung erstellt, aktualisiert oder gelöscht wird, sendet AudioDN eine HTTP-POST-Anfrage an die für Ihre Organisation konfigurierte Sammlungs-Webhook-URL. Dies ist unabhängig vom Track-Processing-Webhook, der Track-Statuswechsel abdeckt.
Im Dashboard konfiguriert
Die Sammlungs-Webhook-URL wird in Ihrem Settings → Webhook-Bereich im Dashboard festgelegt, nicht über die API. Sobald eine URL gespeichert ist, wird jedes Erstellen/Aktualisieren/Löschen einer Sammlung Ihrer Organisation an sie ausgeliefert. Lassen Sie das Feld leer, um Sammlungs-Webhooks zu deaktivieren.
Wann er ausgelöst wird
Ein Webhook wird immer dann zugestellt, wenn sich der Zustand einer Sammlung ändert:
- Wird als HTTP-
POSTmitContent-Type: application/jsongesendet. - Enthält einen
X-ADN-Event-Header, gesetzt auf den Ereignisnamen (zum Beispielcollection.updated). - Die Zustellung erfolgt nach dem Prinzip „fire-and-forget“ / mindestens einmal — gestalten Sie Ihren Handler idempotent.
- Die Reihenfolge der Ereignisse ist nicht garantiert; verlassen Sie sich auf das Feld
eventund dasupdated_at-Feld der Sammlung statt auf die Ankunftsreihenfolge. - Anfragen sind derzeit unsigniert. Behandeln Sie die Webhook-URL als Geheimnis und prüfen Sie bei Bedarf die
collection_idgegen die API. - Antworten Sie zeitnah mit einem
2xx-Statuscode, um den Empfang zu bestätigen.
Ereignisse
| Ereignis | Bedeutung |
|---|---|
| collection.created | Eine neue Sammlung wurde erstellt. Wird einmal gesendet, wenn die Sammlungszeile erstmals eingefügt wird. |
| collection.updated | Eine bestehende Sammlung hat sich geändert — zum Beispiel Titel, Metadaten, Cover oder Player-Einstellungen. |
| collection.deleted | Eine Sammlung wurde gelöscht. Wird gesendet, wenn die Sammlung entfernt wird (ihre Tracks und Dateien werden mit ihr entfernt). |
Payload-Schema
Jedes Ereignis liefert die gleiche Umschlagstruktur. Das collection-Objekt enthält die aktuellen Felder der Sammlung; bei einem collection.deleted-Ereignis spiegelt es die gelöschte Zeile wider (mit gesetztem deleted_at).
{
"event": "collection.created | collection.updated | collection.deleted",
"organization_id": "uuid",
"creator_id": "uuid | null",
"collection_id": "uuid",
"collection": {
"id": "uuid",
"organization_id": "uuid",
"creator_id": "uuid | null",
"title": "string | null",
"organization_index": "string | null",
"metadata": "object | null",
"theme": "array | null",
"player_color": "string | null",
"player_color_light": "string | null",
"player_color_dark": "string | null",
"player_subtitle": "string | null",
"is_cover_overridable": "boolean",
"is_theme_overridable": "boolean",
"cloudflare_image_id": "uuid | null",
"cover_image": {
"icon": { "type": "icon", "width": 80, "height": 80, "url": "string" },
"small": { "type": "small", "width": 200, "height": 200, "url": "string" },
"regular": { "type": "regular", "width": 400, "height": 400, "url": "string" },
"large": { "type": "large", "width": 800, "height": 800, "url": "string" }
},
"created_at": "string",
"updated_at": "string",
"deleted_at": "string | null"
}
} Coverbilder
Wenn eine Sammlung Cover-Artwork besitzt, liefert collection.cover_image gebrauchsfertige URLs für jede verfügbare Größe (und collection.cloudflare_image_id speichert die Bild-ID, falls Sie sie benötigen). Beide sind null, wenn kein Cover vorhanden ist. Bevorzugen Sie die vorgefertigten URLs; falls Sie nur die Bild-ID haben, können Sie jede Größe selbst nach dem folgenden Muster erzeugen, wobei <variant> für icon (80x80), small (200x200), regular (400x400) oder large (800x800) steht:
https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/{cloudflare_image_id}/{variant} Die vollständige Übersicht der Varianten finden Sie unter Track Processing → Coverbilder. Dasselbe Schema wird in den cover_image-Antworten der gesamten API verwendet.
Beispiel-Payloads
Erstellt
Wird gesendet, wenn eine neue Sammlung erstellt wird.
{
"event": "collection.created",
"organization_id": "11111111-1111-1111-1111-111111111111",
"creator_id": null,
"collection_id": "22222222-2222-2222-2222-222222222222",
"collection": {
"id": "22222222-2222-2222-2222-222222222222",
"organization_id": "11111111-1111-1111-1111-111111111111",
"creator_id": null,
"title": "Season 1",
"organization_index": "your-collection-id-001",
"metadata": null,
"theme": null,
"player_color": "#1DB954",
"player_color_light": "#1BAA4D",
"player_color_dark": "#1DB954",
"player_subtitle": "Acme Media",
"is_cover_overridable": true,
"is_theme_overridable": true,
"cloudflare_image_id": null,
"cover_image": null,
"created_at": "2026-07-02T10:00:00.000Z",
"updated_at": "2026-07-02T10:00:00.000Z",
"deleted_at": null
}
} Aktualisiert
Wird gesendet, wenn sich Felder einer Sammlung ändern.
{
"event": "collection.updated",
"organization_id": "11111111-1111-1111-1111-111111111111",
"creator_id": null,
"collection_id": "22222222-2222-2222-2222-222222222222",
"collection": {
"id": "22222222-2222-2222-2222-222222222222",
"organization_id": "11111111-1111-1111-1111-111111111111",
"creator_id": null,
"title": "Season 1 (Remastered)",
"organization_index": "your-collection-id-001",
"metadata": { "genre": "podcast" },
"theme": null,
"player_color": "#1DB954",
"player_color_light": "#1BAA4D",
"player_color_dark": "#1DB954",
"player_subtitle": "Acme Media",
"is_cover_overridable": true,
"is_theme_overridable": true,
"cloudflare_image_id": "99999999-9999-9999-9999-999999999999",
"cover_image": {
"icon": { "type": "icon", "width": 80, "height": 80, "url": "https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/99999999-9999-9999-9999-999999999999/icon" },
"small": { "type": "small", "width": 200, "height": 200, "url": "https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/99999999-9999-9999-9999-999999999999/small" },
"regular": { "type": "regular", "width": 400, "height": 400, "url": "https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/99999999-9999-9999-9999-999999999999/regular" },
"large": { "type": "large", "width": 800, "height": 800, "url": "https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/99999999-9999-9999-9999-999999999999/large" }
},
"created_at": "2026-07-02T10:00:00.000Z",
"updated_at": "2026-07-02T12:30:00.000Z",
"deleted_at": null
}
} Gelöscht
Wird gesendet, wenn eine Sammlung gelöscht wird. Das Feld deleted_at ist dann gesetzt.
{
"event": "collection.deleted",
"organization_id": "11111111-1111-1111-1111-111111111111",
"creator_id": null,
"collection_id": "22222222-2222-2222-2222-222222222222",
"collection": {
"id": "22222222-2222-2222-2222-222222222222",
"organization_id": "11111111-1111-1111-1111-111111111111",
"creator_id": null,
"title": "Season 1 (Remastered)",
"organization_index": "your-collection-id-001",
"metadata": { "genre": "podcast" },
"theme": null,
"player_color": "#1DB954",
"player_color_light": "#1BAA4D",
"player_color_dark": "#1DB954",
"player_subtitle": "Acme Media",
"is_cover_overridable": true,
"is_theme_overridable": true,
"cloudflare_image_id": "99999999-9999-9999-9999-999999999999",
"cover_image": {
"icon": { "type": "icon", "width": 80, "height": 80, "url": "https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/99999999-9999-9999-9999-999999999999/icon" },
"small": { "type": "small", "width": 200, "height": 200, "url": "https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/99999999-9999-9999-9999-999999999999/small" },
"regular": { "type": "regular", "width": 400, "height": 400, "url": "https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/99999999-9999-9999-9999-999999999999/regular" },
"large": { "type": "large", "width": 800, "height": 800, "url": "https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/99999999-9999-9999-9999-999999999999/large" }
},
"created_at": "2026-07-02T10:00:00.000Z",
"updated_at": "2026-07-02T13:00:00.000Z",
"deleted_at": "2026-07-02T13:00:00.000Z"
}
} Zustellung überprüfen
Jeder Zustellversuch wird auf Seiten von AudioDN protokolliert, einschließlich des von Ihrem Endpunkt zurückgegebenen HTTP-Statuscodes. Wenn Sie keine Ereignisse mehr erhalten, prüfen Sie, ob Ihr Endpunkt zügig eine 2xx-Antwort zurückgibt und ob die Sammlungs-Webhook-URL in den Settings korrekt ist.
Webhooks verarbeiten
Ein minimaler Handler liest das Feld event und hält Ihre lokale Kopie der Sammlung synchron. Da die Zustellung mindestens einmal und ungeordnet erfolgt, sollten Sie Ihre Logik auf collection_id und das updated_at-Feld der Sammlung stützen statt auf die Empfangsreihenfolge.
app.post('/webhooks/audiodn/collections', (req, res) => {
// Acknowledge quickly, then process asynchronously.
res.sendStatus(200)
const { event, collection_id, collection } = req.body
switch (event) {
case 'collection.created':
case 'collection.updated':
// Upsert your local copy of the collection.
upsertCollection(collection_id, collection)
break
case 'collection.deleted':
// Remove your local copy.
removeCollection(collection_id)
break
}
})