Media Upload Guide
Learn how to upload audio tracks, videos, and images to Audibase using the REST API. The upload process uses presigned URLs for secure, direct uploads to cloud storage.
Overview
Uploading media to Audibase is a 3-step process:
- 1Get a presigned URL - Request a secure upload URL from the API
- 2Upload the file - PUT your file directly to the presigned URL
- 3Create the media record - Register the uploaded file with metadata
Authentication
All API requests require a Firebase ID token in the Authorization header:
Get your token by signing in with Firebase Authentication and calling user.getIdToken()
Step 1: Get Presigned Upload URL
/api/v1/me/storage/presignRequest a presigned URL that allows direct upload to cloud storage.
Request Body
{
"path": "users/{userId}/media",
"filename": "my-track.mp3",
"contentType": "audio/mpeg",
"size": 5242880
}Parameters
| Field | Type | Required | Description |
|---|---|---|---|
path | string | Yes | Upload path (see paths below) |
filename | string | Yes | Original filename with extension |
contentType | string | Yes | MIME type of the file |
size | number | Yes | File size in bytes |
Response
{
"success": true,
"data": {
"uploadUrl": "https://storage.example.com/...",
"key": "users/abc123/media/1706000000-a1b2c3d4.mp3",
"publicUrl": "https://cdn.audibase.com/users/abc123/media/1706000000-a1b2c3d4.mp3",
"isPrivate": false
}
}Upload Paths
Replace {userId} with your Firebase user ID.
| Path | Max Size | Allowed Types | Quota |
|---|---|---|---|
users/{userId}/media | 500 MB | Audio, Video, Images | Yes |
users/{userId}/profile | 10 MB | Images only | No |
users/{userId}/releases | 500 MB | Audio, Images | No |
users/{userId}/software | 500 MB | All types + ZIP | No |
Note: Media uploads count towards your storage quota (1GB free, 10GB pro, 100GB premium).
Step 2: Upload the File
Upload your file directly to the presigned URL using a PUT request. This upload goes directly to cloud storage, not through the API server.
cURL Example
curl -X PUT \ -H "Content-Type: audio/mpeg" \ --data-binary @my-track.mp3 \ "https://storage.example.com/presigned-url..."
JavaScript Example
const response = await fetch(presignedUrl, {
method: 'PUT',
headers: {
'Content-Type': file.type,
},
body: file,
});
if (!response.ok) {
throw new Error('Upload failed');
}Important: The Content-Type header must match the contentType you specified when requesting the presigned URL.
Step 3: Create Media Record
/api/v1/me/mediaAfter the file is uploaded, create a media record to make it accessible.
Request Body
{
"title": "My Awesome Track",
"description": "A chill lo-fi beat",
"genre": "Lo-Fi",
"bpm": 85,
"key": "Am",
"duration": 180,
"mediaUrl": "https://cdn.audibase.com/users/.../track.mp3",
"hlsUrl": "https://cdn.audibase.com/users/.../hls/master.m3u8",
"waveformUrl": "https://cdn.audibase.com/users/.../waveform.json",
"artworkUrl": "https://cdn.audibase.com/users/.../artwork.jpg",
"visibility": "public"
}Parameters
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Track title |
description | string | No | Track description |
genre | string | No | Music genre |
bpm | number | No | Beats per minute |
key | string | No | Musical key (e.g., "Am", "C") |
duration | number | No | Duration in seconds |
mediaUrl | string | No | Direct URL to audio file |
hlsUrl | string | No | HLS streaming playlist URL |
waveformUrl | string | No | Waveform data JSON URL |
artworkUrl | string | No | Cover artwork URL |
visibility | string | No | "public", "unlisted", or "private" |
Response
{
"success": true,
"data": {
"id": "abc123xyz",
"title": "My Awesome Track",
"slug": "my-awesome-track",
"media": {
"url": "https://cdn.audibase.com/.../master.m3u8",
"waveform": "https://cdn.audibase.com/.../waveform.json",
"artwork": "https://cdn.audibase.com/.../artwork.jpg"
},
"user": {
"id": "user123",
"username": "producer",
"displayName": "Producer Name",
"photo": "https://..."
},
"stats": {
"plays": 0,
"likes": 0,
"comments": 0
},
"visibility": "public",
"createdAt": "2024-01-23T12:00:00Z"
}
}Complete Example
Full JavaScript/TypeScript Example
async function uploadMedia(file: File, token: string) {
const API_URL = 'https://api.audibase.com/api/v1';
const userId = 'your-firebase-user-id';
// Step 1: Get presigned URL
const presignResponse = await fetch(`${API_URL}/me/storage/presign`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
path: `users/${userId}/media`,
filename: file.name,
contentType: file.type,
size: file.size,
}),
});
const { data: presign } = await presignResponse.json();
// Step 2: Upload to presigned URL
await fetch(presign.uploadUrl, {
method: 'PUT',
headers: {
'Content-Type': file.type,
},
body: file,
});
// Step 3: Create media record
const mediaResponse = await fetch(`${API_URL}/me/media`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'My Track',
mediaUrl: presign.publicUrl,
visibility: 'public',
}),
});
const { data: media } = await mediaResponse.json();
return media;
}Supported File Types
🎵 Audio
- MP3 (audio/mpeg)
- WAV (audio/wav)
- FLAC (audio/flac)
- AAC (audio/aac)
- M4A (audio/x-m4a)
- OGG (audio/ogg)
🖼️ Images
- JPEG (image/jpeg)
- PNG (image/png)
- GIF (image/gif)
- WebP (image/webp)
- HEIC (image/heic)
🎬 Video
- MP4 (video/mp4)
- QuickTime (video/quicktime)
- WebM (video/webm)
- AVI (video/x-msvideo)
📦 Archives
- ZIP (application/zip)
- * Only for software uploads
Error Codes
| Code | Error | Description |
|---|---|---|
400 | Invalid request | Missing or invalid parameters |
401 | Unauthorized | Missing or invalid auth token |
403 | Forbidden | Storage quota exceeded or wrong path |
413 | File too large | File exceeds maximum size limit |
503 | Storage not configured | Cloud storage is unavailable |