Launch Sale: Creator and Business plans are discounted for a limited time. View pricing

Track File Webhook

The Track File webhook lets your application react to individual track files as they are produced. Each track file is the result of applying a variant (recipe) to a track. Instead of receiving the full files[] array on every track status change, this webhook delivers one track file at a time — which is easier to handle when a track has many variants.

Configured in the dashboard

The Track File webhook URL is set in your Settings → Webhook panel in the dashboard, not via the API. Once a URL is saved, every track file event for your organization is delivered to it. Leave it blank to disable it. This is independent of the Track Processing and Collection Sync webhooks — enable whichever you need.

When it fires

A track normally produces several track files (one per variant). This webhook fires once per track file rather than once per track. Every track file — whether it succeeds or fails — is recorded, so you always get exactly one event per file. Each payload carries a status (success or failed) and a matching event:

Outcome Event Status Meaning
Successfully created track_file.created success A track file finished processing and was stored. The upload to storage has already completed, so this event marks the file as available. The file object has file.is_success = true.
Failed track_file.failed failed A variant failed to process. A file row is still delivered so the mapping stays 1:1, but with file.is_success = false, no url, and the reason in message.
  • Sent as an HTTP POST with Content-Type: application/json.
  • Includes an X-ADN-Event header set to the event name (track_file.created or track_file.failed).
  • Branch on the top-level status (success / failed) or on file.is_success.
  • Delivery is fire-and-forget / at-least-once — design your handler to be idempotent (key on file_id, or on track_id + variant.index).
  • Event ordering is not guaranteed across files.
  • Requests are currently unsigned. Treat the webhook URL as a secret and, if needed, verify the track_id against the API.
  • Respond promptly with a 2xx status code to acknowledge receipt.

Track File vs Track Processing

Use the Track Processing webhook to react to a track's overall lifecycle (processingready). Use the Track File webhook when you care about each individual output file as it lands — for example, to unlock a purchased lossless download the moment it is ready, without waiting for the whole track to finish.

Payload schema

The file object matches a single entry of the files[] array delivered by the Track Processing webhook, including the nested variant (recipe) that produced it, plus is_success. Both success and failure deliver a file object. On failure, file.is_success is false, file.url is null (no object was stored), and the reason is in the top-level message (mirrored in file.status_text).

{
  "event": "track_file.created | track_file.failed",
  "status": "success | failed",
  "organization_id": "uuid",
  "creator_id": "uuid | null",
  "collection_id": "uuid",
  "track_id": "uuid",
  "file_id": "uuid",
  "message": "string | null",
  "file": {
    "id": "uuid",
    "path": "string",
    "url": "string | null",
    "size": "number | null",
    "content_type": "string | null",
    "file_name": "string",
    "is_public": "boolean",
    "is_success": "boolean",
    "status_text": "string | null",
    "data": "object | null",
    "props": "object | null",
    "variant": {
      "id": "uuid",
      "index": "string",
      "variant_type": {
        "id": "string",
        "viewer_id": "string",
        "title": "string"
      }
    }
  }
}

Read the variant that produced (or would have produced) the file from file.variant. On success, message is null and file.url points at the stored object. On failure, message holds the error, file.url is null, and file.size / file.content_type may be null.

Example payloads

Successfully created

Sent when a track file finishes processing and is stored.

{
  "event": "track_file.created",
  "status": "success",
  "organization_id": "11111111-1111-1111-1111-111111111111",
  "creator_id": null,
  "collection_id": "22222222-2222-2222-2222-222222222222",
  "track_id": "33333333-3333-3333-3333-333333333333",
  "file_id": "55555555-5555-5555-5555-555555555555",
  "message": null,
  "file": {
    "id": "55555555-5555-5555-5555-555555555555",
    "path": "org/collection/track/transcode.aac",
    "url": "https://cdn.audiodn.com/org/collection/track/transcode.aac",
    "size": 17012344,
    "content_type": "audio/aac",
    "file_name": "transcode.aac",
    "is_public": true,
    "is_success": true,
    "status_text": "OK",
    "data": null,
    "props": null,
    "variant": {
      "id": "66666666-6666-6666-6666-666666666666",
      "index": "transcode-default",
      "variant_type": {
        "id": "transcode",
        "viewer_id": "audio",
        "title": "Transcoded Audio"
      }
    }
  }
}

Failed (variant error)

Sent when a variant fails to process. A file row is still delivered (so the mapping stays 1:1), but with is_success: false, no url, and the reason in message.

{
  "event": "track_file.failed",
  "status": "failed",
  "organization_id": "11111111-1111-1111-1111-111111111111",
  "creator_id": null,
  "collection_id": "22222222-2222-2222-2222-222222222222",
  "track_id": "33333333-3333-3333-3333-333333333333",
  "file_id": "77777777-7777-7777-7777-777777777777",
  "message": "ffmpeg exited with code 1: unsupported sample format",
  "file": {
    "id": "77777777-7777-7777-7777-777777777777",
    "path": "org/collection/track/preview-30s.aac",
    "url": null,
    "size": null,
    "content_type": "audio/aac",
    "file_name": "preview-30s.aac",
    "is_public": false,
    "is_success": false,
    "status_text": "ffmpeg exited with code 1: unsupported sample format",
    "data": null,
    "props": null,
    "variant": {
      "id": "66666666-6666-6666-6666-666666666666",
      "index": "preview-30s",
      "variant_type": {
        "id": "preview",
        "viewer_id": "audio",
        "title": "Preview Clip"
      }
    }
  }
}

Verifying delivery

Each delivery attempt is logged on AudioDN's side, including the HTTP status code returned by your endpoint. If you stop receiving events, confirm your endpoint returns a 2xx response quickly and that the Track File webhook URL in Settings is correct.

Handling webhooks

Branch on status (or file.is_success). Because delivery is at-least-once and unordered, key your logic on file_id (or track_id + file.variant.index) rather than on receipt order.

app.post('/webhooks/audiodn/track-files', (req, res) => {
  // Acknowledge quickly, then process asynchronously.
  res.sendStatus(200)

  const { status, track_id, file, message } = req.body
  if (status === 'success') {
    // A single track file is ready — store or unlock it.
    saveTrackFile(track_id, file)
  } else {
    // A variant failed — file.is_success is false and file.url is null.
    flagVariantFailure(track_id, file.variant, message)
  }
})