# Server-Side Integration | AudioDN Docs

> Use AudioDN

Source: https://audiodeliverynetwork.com/docs/integration/server-side/

---

# Server-Side Integration

Use ADN's API directly to store tracks and manage playback. Build fully custom experiences without ADN components.

#### Best For

Custom platforms, enterprise, and teams needing full API control. Setup takes 1-2 hours.

## Playing Tracks

Create play sessions and fetch track URLs from your server.

Use ADN's API directly from your server to create play sessions and fetch track URLs. Build completely custom playback experiences — no ADN web components involved.

### 1\. Create an API Key

Go to **Settings → API Keys** and create an **API Access** key.

### 2\. Create a Play Session

```
const response = await fetch('https://api.audiodelivery.net/v1/play_session/collection', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    collection_id,
    variants: ['preview'],
    is_downloadable: false,
    expires_in: 3600 // session duration in seconds (default: 3600, min: 60, max: 86400)
  })
});

const { play_session_id, tracks } = await response.json();
```

This is where you apply business logic — check subscriptions, verify purchases, or enforce access rules before creating the session.

### 3\. Fetch Track Data

```
const { id: track_id } = tracks[0];

// No auth needed - the session ID acts as a bearer token
const response = await fetch(`https://api.audiodelivery.net/v1/play/${play_session_id}/${track_id}`);

const { variants } = await response.json();
const preview = variants.find(v => v.variant.index === 'preview');
console.log(`Play Audio File: ${preview.url}`);
```

### 4\. Custom Playback

Use the returned URL in your own audio player implementation. Works with any player library or native mobile audio APIs.

#### Waveform Data

ADN generates normalized RMS waveform data (320 samples) for every track automatically. The `levels` field in the track response contains the data — use it to render waveforms in your own player, or generate custom waveforms via the Audio Analysis variant type.

#### Cover Images & Theme Colors

ADN scans every uploaded track for embedded cover art and makes it available as `cover_image` in the track response (in icon/small/regular/large sizes). You can also upload a cover image separately via the API. When a cover image is present, ADN extracts a palette of colors and selects a primary `player_color` — use these to style your player UI. Alongside it, responses include `player_color_light` and `player_color_dark`, contrast-adjusted variants for drawing the color on light and dark backgrounds respectively. The full `theme` array contains all extracted colors with hex values, area, lightness, and saturation data.

#### Public tracks? Skip the session

For publicly available tracks, you can sign delivery URLs on your own server with a URL Signing key and skip play sessions entirely — no per-listener API round trip. See the [Signed Delivery](/docs/integration/signed-delivery) fast track and the [Signing Keys API](/docs/api/signing-keys).

## Uploading Tracks

Use ADN's API to manage the entire upload flow from your server.

Use ADN's API directly from your server to create upload sessions, store tracks, and manage the entire upload flow. Build fully custom upload interfaces — no ADN web components involved.

### 1\. Create an API Key

Go to **Settings → API Keys** and create an **API Access** key.

### 2\. Create an Upload Session

```
const response = await fetch('https://api.audiodelivery.net/v1/upload_session', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    collection_id: 'COLLECTION-ID',
    expires_in: 3600 // session duration in seconds (default: 3600, min: 60, max: 86400)
  })
});

const { upload_session } = await response.json();
```

### 3\. Create Tracks Within the Session

```
const { id: upload_session_id } = upload_session;

// One request per file. No Authorization header needed here — the
// upload session ID authorizes track creation.
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, expires_at } = track_upload;
```

### 4\. Upload Files

```
const file = document.querySelector('input[type="file"]').files[0];

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

Repeat steps 3 and 4 for each file you want to add to the session — every track needs its own `POST /v1/upload/:upload_session_id/track` request and its own signed upload URL.

### 5\. Wait Until the Track Is Ready

Processing starts automatically once the file lands in storage. Wait until the track's status is `ready` before creating a play session or signing delivery URLs — either by polling or with a webhook.

```
// Processing runs automatically after the upload. Poll the track until it is
// ready, or configure a webhook (below) to be notified instead of polling.
let track;
do {
  await new Promise((r) => setTimeout(r, 5000));
  const res = await fetch(`https://api.audiodelivery.net/v1/track/${track_id}`, {
    headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
  });
  ({ track } = await res.json());
} while (track.track_status_id !== 'ready');

// The track is now ready — create a play session or sign a delivery URL.
```

### 6\. Optional: Webhooks

Instead of polling, enable a webhook under **Settings → Webhook** to be notified when a track reaches a terminal outcome (`ready`, `incomplete`, `error`, or `init_error`) and when its full file set is complete. See the [Track Processing webhook](/docs/webhooks/track-processing) docs.

#### Cover Images

ADN automatically scans uploaded tracks for embedded cover art. You can also upload a cover image separately via the Covers API. When an image is present, ADN extracts colors (available as `theme`) that can be used to style your player UI.

## Generating Keys

Mint scoped Client-Side keys from your server.

Once you have an **API Access** key, you can generate `player` and `uploader` keys programmatically — for example, a per-customer player key scoped to a single collection. **Inline Share** and **URL Signing** keys are not created through the API; provision them from **Settings → API Keys** in the dashboard. See the [API Keys](/docs/api/api-keys) reference for all parameters.

### Create a Scoped Key

```
// Use your API Access key to mint a scoped Client-Side Player key.
const response = await fetch('https://api.audiodelivery.net/v1/api_key', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_ACCESS_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    title: 'Customer Player Key',
    api_key_type_id: 'player',   // 'player' | 'uploader' (share & signing keys are dashboard-only)
    collection_id: 'COLLECTION_ID' // optional: limit the key to one collection
    // expires_at is optional via the API — omit for a key that never expires
  })
});

// The full key is returned once — store it securely, it cannot be retrieved again.
const { api_key } = await response.json();
```

Via the API, `expires_at` is optional for both key types — omit it for a key that never expires by time. API Access, Inline Share, and URL Signing keys must be created in the dashboard.
