Uploading tracks

Choose who creates or authorizes the upload session, then — if your server creates it — how files are transferred. Playback is a separate decision; see Playing and accessing tracks.

Per-file upload lifecycle

An upload session may authorize many files, but each file needs its own track and upload URL. Create the session, then for each file call POST /v1/upload/{upload_session_id}/track and PUT the bytes to track_upload.upload_url. Optionally include a nested track on session create for the first file. Full reference: Upload Sessions.

Téléverser des tracks

Choisissez qui crée l’upload session, puis — si nécessaire — comment les fichiers sont transférés. Les choix d’upload et de lecture sont indépendants.

Qui doit créer ou autoriser l’upload session ?
Comment l’utilisateur doit-il transférer les fichiers ?

AudioDN Uploader or (voice) Recorder web components with a Client-Side Upload key

Fastest setup. Drop-in web components with a scoped Client-Side Upload key; they create the session and upload each file. The (voice) Recorder captures from the microphone.

1

Create a Client-Side Upload key

In the dashboard go to Settings → API Keys and create a Client-Side Upload key. Optionally scope it to a collection. This key can only create upload sessions — not read or delete tracks.

2

Install the web component

npm install @audiodn/components

Uploader:

import '@audiodn/components/uploader'

Or (voice) Recorder:

import '@audiodn/components/recorder'

CDN alternatives:

<script type="module" src="https://unpkg.com/@audiodn/components@latest/dist/uploader.js"></script>
<script type="module" src="https://unpkg.com/@audiodn/components@latest/dist/recorder.js"></script>
3

Render the web component

<audiodn-uploader
  api-key="CLIENT-SIDE-UPLOAD-KEY"
  collection-id="COLLECTION-ID"
  accent-color="#ff00ff"
></audiodn-uploader>
<audiodn-recorder
  api-key="CLIENT-SIDE-UPLOAD-KEY"
  collection-id="COLLECTION-ID"
  accent-color="#ff00ff"
></audiodn-recorder>

If the key is scoped to a collection, you can omit collection-id. Never set both api-key and upload-session-id. The (voice) Recorder uses the microphone to capture audio in the browser.

4

What the web component does

For each file, the web component creates (or reuses) an upload session, calls POST /v1/upload/:upload_session_id/track, and uploads the bytes to track_upload.upload_url. AudioDN then processes your configured output presets.

Optional: configure a track-processing webhook to learn when a track is ready.

Custom client upload with a Client-Side Upload key

Your browser or native app creates the upload session and uploads each file. You build the interface.

1

Create a Client-Side Upload key

Create a scoped Client-Side Upload key in the dashboard. Safe to embed in the app. Never use an API Access key in client code.

2

Create an upload session

const response = await fetch('https://api.audiodelivery.net/v1/upload_session', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer CLIENT-SIDE-UPLOAD-KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ collection_id: 'COLLECTION-ID', expires_in: 3600 })
});
const { upload_session_id } = await response.json();
3

Create a track for each file

const response = await fetch(
  `https://api.audiodelivery.net/v1/upload/${upload_session_id}/track`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ file_name: 'song.wav' })
  }
);
const { track_id, track_upload } = await response.json();
const { method, upload_url } = track_upload;

You can also include a nested track object on session create for the first file, then use this step for additional files. The upload URL is at track_upload.upload_url (not on the track object).

4

Upload the bytes

await fetch(upload_url, {
  method,
  headers: { 'Content-Type': file.type },
  body: file
});
5

Wait for processing

Poll GET /v1/track/{track_id} until track.track_status_id is ready (requires an API Access key or dashboard), or use a webhook. Client-Side Upload keys cannot read track status — prefer webhooks or a server poll for readiness.

Server-created upload session with the AudioDN Uploader or (voice) Recorder web components

Your server authorizes the upload, creates a short-lived session, and passes it to the Uploader or (voice) Recorder web component.

1

Keep an API Access key on your server

Create an API Access key in the dashboard. Never send it to the browser or mobile app.

2

Authorize, then create an upload session

Apply your own checks (login, quota, permissions), then:

const response = await fetch('https://api.audiodelivery.net/v1/upload_session', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_ACCESS_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    collection_id: 'COLLECTION-ID',
    expires_in: 3600
    // Optional: track: { file_name: 'song.wav' } to also create the first track
  })
});

const { upload_session_id, upload_session } = await response.json();
// Pass upload_session_id to the client (Uploader) or continue with per-track create.
3

Pass the session to the web component

npm install @audiodn/components
import '@audiodn/components/uploader'
<audiodn-uploader
  upload-session-id="UPLOAD-SESSION-ID"
  accent-color="#ff00ff"
></audiodn-uploader>
<audiodn-recorder
  upload-session-id="UPLOAD-SESSION-ID"
  accent-color="#ff00ff"
></audiodn-recorder>

Use upload-session-id only — do not also set api-key.

4

Web component uploads

The Uploader or (voice) Recorder web component performs per-track create and byte upload for you. Optional: webhook for readiness.

Server-created upload session with a custom interface

Your server creates the session; your custom web or native UI creates tracks and uploads files.

1

Keep an API Access key on your server

Create an API Access key. Server only.

2

Create an upload session on the server

const response = await fetch('https://api.audiodelivery.net/v1/upload_session', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_ACCESS_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    collection_id: 'COLLECTION-ID',
    expires_in: 3600
    // Optional: track: { file_name: 'song.wav' } to also create the first track
  })
});

const { upload_session_id, upload_session } = await response.json();
// Pass upload_session_id to the client (Uploader) or continue with per-track create.

Return upload_session_id to the client. Do not return the API Access key.

3

Create a track for each file (client or server)

const response = await fetch(
  `https://api.audiodelivery.net/v1/upload/${upload_session_id}/track`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ file_name: 'song.wav' })
  }
);
const { track_id, track_upload } = await response.json();
const { method, upload_url } = track_upload;
4

Upload the bytes

await fetch(upload_url, {
  method,
  headers: { 'Content-Type': file.type },
  body: file
});
5

Wait until ready

// Processing starts automatically. Prefer webhooks when you can.
// ready = playback-ready (required playable output succeeded). Optional outputs
// such as transcription may still be running until files_completed_at is set.
const terminal = new Set(['ready', 'incomplete', 'error', 'init_error']);
const deadline = Date.now() + 10 * 60 * 1000; // 10-minute timeout
let track;
do {
  if (Date.now() > deadline) throw new Error('Timed out waiting for processing');
  await new Promise((r) => setTimeout(r, 5000));
  const res = await fetch(`https://api.audiodelivery.net/v1/track/${track_id}`, {
    headers: { 'Authorization': 'Bearer YOUR_API_ACCESS_KEY' }
  });
  ({ track } = await res.json());
} while (!terminal.has(track.track_status_id));

if (track.track_status_id === 'error' || track.track_status_id === 'init_error') {
  throw new Error(`Processing failed: ${track.track_status_id}`);
}
// ready or incomplete — a playable file may already be available.
// For per-output state (including optional transcription), see
// GET /v1/track/{track_id}/processing or the Output webhook.

Or use the track-processing webhook instead of polling.

Related references