Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/purple-experts-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@audius/sdk": patch
---

Fix UploadsApi to make start() a function
43 changes: 0 additions & 43 deletions docs/docs/developers/sdk/advanced-options.mdx

This file was deleted.

505 changes: 379 additions & 126 deletions docs/docs/developers/sdk/tracks.mdx

Large diffs are not rendered by default.

214 changes: 214 additions & 0 deletions docs/docs/developers/sdk/uploads.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
---
id: uploads
title: Uploads
pagination_label: Uploads
sidebar_label: Uploads
description: Audius Protocol Documentation
---

import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'

---

The Uploads API provides methods for uploading audio and image files to Audius storage nodes. These
methods return CIDs (Content Identifiers) that you then pass to write methods like
[`createTrack`](/developers/sdk/tracks#createtrack) or
[`updateTrack`](/developers/sdk/tracks#updatetrack).

:::tip

File uploads are a separate step from track/playlist creation. You first upload your files using the
Uploads API to get CIDs, then pass those CIDs as metadata when creating or updating content.

:::

---

## createAudioUpload

> #### createAudioUpload(`params`)

Upload an audio file to a storage node. Returns the resulting CIDs and audio analysis metadata
(duration, BPM, musical key).

<Tabs
block={true}
defaultValue="request"
values={[
{ label: 'Params', value: 'request' },
{ label: 'Example', value: 'example' },
{ label: 'Response', value: 'response' },
]}
>
<TabItem value="request">

Create an object with the following fields and pass it as the first argument.

| Name | Type | Description | Required? |
| :-------------------- | :---------------------------------------- | :--------------------------------------------------- | :----------- |
| `file` | `File` | The audio file to upload | **Required** |
| `onProgress` | `(loaded: number, total: number) => void` | A callback for tracking upload progress | _Optional_ |
| `previewStartSeconds` | `number` | Start time in seconds for generating a preview clip | _Optional_ |
| `placementHosts` | `string[]` | A list of storage node hosts to prefer for placement | _Optional_ |

</TabItem>
<TabItem value="example">

```ts
import fs from 'fs'

const trackBuffer = fs.readFileSync('path/to/track.mp3')

const upload = audiusSdk.uploads.createAudioUpload({
file: {
buffer: Buffer.from(trackBuffer),
name: 'track.mp3',
type: 'audio/mpeg',
},
onProgress: (loaded, total) => {
console.log(`Upload progress: ${Math.round((loaded / total) * 100)}%`)
},
previewStartSeconds: 30,
})

const result = await upload.start()
console.log(result)
```

</TabItem>
<TabItem value="response">

The method returns an object with:

- `abort` — a function you can call to cancel the upload.
- `start()` — a function that begins the upload and returns a `Promise` that resolves with the
upload result once complete.

The resolved value of `start()` contains:

```ts
{
trackCid: string // CID of the transcoded 320kbps audio
previewCid?: string // CID of the preview clip (if previewStartSeconds was provided)
origFileCid: string // CID of the original uploaded file
origFilename: string // Original filename
duration: number // Duration in seconds
bpm?: number // Detected BPM (beats per minute)
musicalKey?: string // Detected musical key
}
```

</TabItem>
</Tabs>

---

## createImageUpload

> #### createImageUpload(`params`)

Upload an image file (e.g. cover art or profile picture) to a storage node. Returns the resulting
CID.

<Tabs
block={true}
defaultValue="request"
values={[
{ label: 'Params', value: 'request' },
{ label: 'Example', value: 'example' },
{ label: 'Response', value: 'response' },
]}
>
<TabItem value="request">

Create an object with the following fields and pass it as the first argument.

| Name | Type | Description | Required? |
| :--------------- | :---------------------------------------- | :---------------------------------------------------------------------------- | :----------- |
| `file` | `File` | The image file to upload | **Required** |
| `onProgress` | `(loaded: number, total: number) => void` | A callback for tracking upload progress | _Optional_ |
| `isBackdrop` | `boolean` | Set to `true` for wide/banner images (e.g. profile banners). Default: `false` | _Optional_ |
| `placementHosts` | `string[]` | A list of storage node hosts to prefer for placement | _Optional_ |

</TabItem>
<TabItem value="example">

```ts
import fs from 'fs'

const coverArtBuffer = fs.readFileSync('path/to/cover-art.png')

const upload = audiusSdk.uploads.createImageUpload({
file: {
buffer: Buffer.from(coverArtBuffer),
name: 'cover-art.png',
type: 'image/png',
},
})

const coverArtCid = await upload.start()
console.log(coverArtCid) // CID string
```

</TabItem>
<TabItem value="response">

The method returns an object with:

- `abort` — a function you can call to cancel the upload.
- `start()` — a function that begins the upload and returns a `Promise` resolving with the CID of
the uploaded image (`string`).

</TabItem>
</Tabs>

---

## Full Example: Upload and Create a Track

This example demonstrates the full workflow of uploading files via the Uploads API and then creating
a track with the returned CIDs.

```ts
import { Mood, Genre } from '@audius/sdk'
import fs from 'fs'

// Step 1: Upload the audio file
const trackBuffer = fs.readFileSync('path/to/track.mp3')
const audioUpload = audiusSdk.uploads.createAudioUpload({
file: {
buffer: Buffer.from(trackBuffer),
name: 'track.mp3',
type: 'audio/mpeg',
},
previewStartSeconds: 30,
})
const audioResult = await audioUpload.start()

// Step 2: Upload cover art
const coverArtBuffer = fs.readFileSync('path/to/cover-art.png')
const imageUpload = audiusSdk.uploads.createImageUpload({
file: {
buffer: Buffer.from(coverArtBuffer),
name: 'cover-art.png',
type: 'image/png',
},
})
const coverArtCid = await imageUpload.start()

// Step 3: Create the track using the CIDs from the uploads.
// The audio upload result fields (trackCid, previewCid, origFileCid, etc.)
// match the metadata field names, so you can spread them directly.
const { data } = await audiusSdk.tracks.createTrack({
userId: '7eP5n',
metadata: {
title: 'Monstera',
description: 'Dedicated to my favorite plant',
genre: Genre.METAL,
mood: Mood.AGGRESSIVE,
...audioResult,
coverArtCid: coverArtCid,
},
})
```
Loading
Loading