Webhook Collection Sync
Le webhook Collection Sync permet à votre application de rester synchronisée avec vos collections AudioDN. Chaque fois qu’une collection est créée, mise à jour ou supprimée, AudioDN envoie une requête HTTP POST à l’URL de webhook de collection configurée pour votre organisation. Ceci est distinct du webhook Track Processing, qui couvre les changements de statut de piste.
Configuré dans le tableau de bord
L’URL du webhook de collection est définie dans votre panneau Settings → Webhook du tableau de bord, pas via l’API. Une fois qu’une URL est enregistrée, chaque création/mise à jour/suppression de collection pour votre organisation y est livrée. Laissez-la vide pour désactiver les webhooks de collection.
Quand il se déclenche
Un webhook est livré chaque fois qu’une collection change d’état :
- Envoyé comme un HTTP
POSTavecContent-Type: application/json. - Inclut un en-tête
X-ADN-Eventdéfini au nom de l’événement (par exemplecollection.updated). - La livraison est fire-and-forget / au moins une fois — concevez votre gestionnaire pour être idempotent.
- L’ordre des événements n’est pas garanti ; utilisez le
eventet le champupdated_atde la collection plutôt que d’assumer l’ordre d’arrivée. - Les requêtes sont actuellement non signées. Traitez l’URL du webhook comme un secret et, si besoin, vérifiez le
collection_idauprès de l’API. - Répondez rapidement avec un code de statut
2xxpour accuser réception.
Événements
| Événement | Signification |
|---|---|
| collection.created | Une nouvelle collection a été créée. Envoyé une fois, lorsque la ligne de collection est d'abord insérée. |
| collection.updated | Une collection existante a changé — par exemple son titre, ses métadonnées, sa couverture ou ses paramètres de lecteur. |
| collection.deleted | Une collection a été supprimée. Envoyé lorsque la collection est retirée (ses pistes et fichiers sont retirés avec elle). |
Schéma du payload
Chaque événement livre la même enveloppe. L’objet collection contient les champs actuels de la collection ; sur un événement collection.deleted il reflète la ligne supprimée (avec deleted_at défini).
{
"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"
}
} Images de couverture
Lorsqu’une collection a une pochette, collection.cover_image fournit des URL prêtes à l’emploi à chaque taille disponible (et collection.cloudflare_image_id stocke l’identifiant d’image si vous en avez besoin). Les deux sont null lorsqu’il n’y a pas de couverture. Préférez les URL toutes faites ; si vous n’avez que l’identifiant d’image, construisez n’importe quelle taille vous-même avec le modèle ci-dessous, où <variant> est icon (80x80), small (200x200), regular (400x400), ou large (800x800) :
https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/{cloudflare_image_id}/{variant} Voir Track Processing → Images de couverture pour la référence complète des variantes. Le même schéma est utilisé dans les réponses cover_image de l’API.
Exemples de payloads
Créée
Envoyé lorsqu’une nouvelle collection est créée.
{
"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
}
} Mise à jour
Envoyé lorsque les champs d’une collection changent.
{
"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
}
} Supprimée
Envoyé lorsqu’une collection est supprimée. Le champ deleted_at est renseigné.
{
"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"
}
} Vérification de la livraison
Chaque tentative de livraison est journalisée côté AudioDN, y compris le code de statut HTTP renvoyé par votre point de terminaison. Si vous cessez de recevoir des événements, confirmez que votre point de terminaison renvoie rapidement une réponse 2xx et que l’URL du webhook de collection dans Settings est correcte.
Gestion des webhooks
Un gestionnaire minimal lit le champ event et garde votre copie locale de la collection synchronisée. Parce que la livraison est au moins une fois et non ordonnée, cléz votre logique sur collection_id et le updated_at de la collection plutôt que sur l’ordre de réception.
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
}
})