Oferta de lanzamiento: Los planes Creator y Business tienen descuento por tiempo limitado. Ver precios

Webhook Collection Sync

El webhook Collection Sync permite que tu aplicación se mantenga sincronizada con tus colecciones de AudioDN. Cada vez que se crea, actualiza o elimina una colección, AudioDN envía una solicitud HTTP POST a la URL de webhook de colección configurada para tu organización. Esto es independiente del webhook Track Processing, que cubre los cambios de estado de las pistas.

Se configura en el panel

La URL del webhook de colección se establece en el panel Settings → Webhook del dashboard, no vía la API. Una vez guardada una URL, cada create/update/delete de colección de tu organización se entrega a ella. Déjala en blanco para desactivar los webhooks de colección.

Cuándo se dispara

Se entrega un webhook cada vez que una colección cambia de estado:

  • Se envía como un HTTP POST con Content-Type: application/json.
  • Incluye una cabecera X-ADN-Event con el nombre del evento (por ejemplo collection.updated).
  • La entrega es fire-and-forget / al menos una vez — diseña tu manejador para que sea idempotente.
  • No se garantiza el orden de eventos; usa el event y el campo updated_at de la colección en lugar de asumir el orden de llegada.
  • Las solicitudes actualmente no están firmadas. Trata la URL del webhook como un secreto y, si hace falta, verifica el collection_id contra la API.
  • Responde con prontitud con un código de estado 2xx para acusar recibo.

Eventos

EventoSignificado
collection.createdSe creó una nueva colección. Se envía una vez, cuando se inserta por primera vez la fila de la colección.
collection.updatedUna colección existente cambió — por ejemplo su título, metadatos, portada o ajustes del player.
collection.deletedSe eliminó una colección. Se envía cuando se quita la colección (sus pistas y archivos se eliminan con ella).

Esquema del payload

Cada evento entrega el mismo sobre. El objeto collection contiene los campos actuales de la colección; en un evento collection.deleted refleja la fila eliminada (con deleted_at establecido).

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

Imágenes de portada

Cuando una colección tiene arte de portada, collection.cover_image proporciona URLs listas para usar en cada tamaño disponible (y collection.cloudflare_image_id almacena el ID de imagen si lo necesitas). Ambos son null cuando no hay portada. Prefiere las URLs ya preparadas; si solo tienes el ID de imagen, construye cualquier tamaño tú mismo con el patrón de abajo, donde <variant> es icon (80x80), small (200x200), regular (400x400) o large (800x800):

https://imagedelivery.net/iVHDyjXAr_lt5UUJaLbk1Q/{cloudflare_image_id}/{variant}

Consulta Track Processing → Cover images para la referencia completa de variantes. El mismo esquema se usa en las respuestas cover_image de la API.

Ejemplos de payload

Creada

Se envía cuando se crea una nueva colección.

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

Actualizada

Se envía cuando cambian los campos de una colección.

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

Eliminada

Se envía cuando se elimina una colección. El campo deleted_at está poblado.

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

Verificar la entrega

Cada intento de entrega se registra en el lado de AudioDN, incluyendo el código de estado HTTP devuelto por tu endpoint. Si dejas de recibir eventos, confirma que tu endpoint responde con 2xx rápidamente y que la URL del webhook de colección en Settings es correcta.

Manejar webhooks

Un manejador mínimo lee el campo event y mantiene sincronizada tu copia local de la colección. Como la entrega es al menos una vez y sin orden garantizado, basa tu lógica en collection_id y el updated_at de la colección en lugar del orden de recepción.

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
}
})