Output Webhook
The Output webhook lets your application react to individual outputs as they are produced. Each output is the result of applying an output preset to a track. Instead of receiving the full files[] array on every track status change, this webhook delivers one output at a time — which is easier to handle when a track has many presets. Wire event names remain track_file.created and track_file.failed.
Configured in the dashboard
The Output webhook URL is set in your organization settings in the dashboard, not via the API. Once a URL is saved, every output 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 outputs (one per output preset). This webhook fires once per output rather than once per track. Every output — whether it succeeds or fails — is recorded as one logical result (one event type for that output). Delivery is still at-least-once, so handlers must be idempotent. Each payload carries a status (success or failed) and a matching event:
| Outcome | Event | Status | Meaning |
|---|---|---|---|
| Successfully created | track_file.created | success | An output finished processing and was stored. The upload to storage has already completed, so this event marks the output as available. The file object has file.is_success = true. Event name remains track_file.created. |
| Failed | track_file.failed | failed | An output 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. Event name remains track_file.failed. |
- Sent as an HTTP
POSTwithContent-Type: application/json. - Includes an
X-ADN-Eventheader set to the event name (track_file.createdortrack_file.failed). - Branch on the top-level
status(success/failed) or onfile.is_success. - Delivery is fire-and-forget / at-least-once — design your handler to be idempotent (key on
file_id, or ontrack_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_idagainst the API. - Respond promptly with a
2xxstatus code to acknowledge receipt.
Output webhook vs Track Processing
Use the Track Processing webhook to react to a track’s overall lifecycle (playback-ready, incomplete, error, or files complete). Use the Output webhook when you care about each individual output as it lands — for example, to unlock a purchased lossless download or a WebVTT caption file the moment it is ready. Track-level fields such as transcription are only on the Track Processing payload and the Tracks API — not on this per-output event. See also Voice & transcription.
Payload schema
The file object matches a single entry of the files[] array delivered by the Track Processing webhook, including the nested variant object (historical name for the output preset 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 an output 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 Output webhook URL in your organization 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 output 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)
}
})