The EzStems API allows premium subscribers to programmatically upload audio files and generate stems using Spleeter technology. This API supports multiple audio formats and provides various endpoints for managing the stem separation process.
All API requests require authentication using an API key. Include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
/api/v1/keys.php endpointYou can list and manage your API keys using the following endpoints:
/api/v1/keys.php
Returns a list of your API keys and their status.
{
"success": true,
"data": [
{
"id": 1,
"api_key": "********abcd1234",
"is_active": 1,
"rate_limit": 100,
"calls_count": 50,
"created_at": "2025-11-08 12:00:00",
"last_used_at": "2025-11-08 12:30:00"
}
]
}
/api/v1/keys.php
Deactivates your current API key.
{
"success": true,
"message": "API key deactivated successfully"
}
/api/v1/keys.php
Generates a new API key for your account. Requires user to be logged in to the website.
{
"success": true,
"data": {
"api_key": "your-api-key-here",
"message": "Store this API key securely. It won't be shown again."
}
}
/api/v1/upload.php
Upload an audio file for stem separation.
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | File | Yes | Audio file (MP3, WAV, or M4A) |
| stems | Number | Yes | Number of stems to separate into |
| cutoff | String | No | Frequency cutoff setting |
| output | String | No | Output format preference |
| Subscription Level | Maximum File Size |
|---|---|
| Basic (Premium) | 30 MB |
| Premium | 40 MB |
| Pro | 75 MB |
| Custom Plans | Up to 300 MB |
{
"success": true,
"data": {
"id": "1699567234_2",
"filename": "1699567234_2_12345.mp3",
"status": "queued",
"stems": "2",
"check_status_endpoint": "/api/v1/status.php?id=1699567234_2"
}
}
/api/v1/status.php?id={processing_id}
Check the status of a stem separation process.
| Parameter | Type | Description |
|---|---|---|
| id | String | Processing ID received from upload endpoint (format: timestamp_stems) |
{
"success": true,
"data": {
"id": "1699567234_2",
"status": "completed",
"queue_position": 0,
"stems": 2,
"created_at": "2025-11-09 14:30:34",
"download_url": "/api/v1/download.php?id=1699567234_2"
}
}
| Status | Description |
|---|---|
| queued | File is in processing queue. Check queue_position for position. |
| processing | File is currently being processed. |
| completed | Processing finished, file ready for download. |
| failed | Processing failed, check error message for details. |
curl -X POST https://ezstems.com/api/v1/upload.php \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@song.mp3" \
-F "stems=4"
/api/v1/download.php?id={processing_id}
Download the processed stems as a ZIP file.
| Parameter | Type | Description |
|---|---|---|
| id | String | Processing ID received from upload endpoint (format: timestamp_stems) |
Returns a ZIP file containing the separated stems if processing is complete. Returns an error if processing is not finished.
curl -X GET "https://ezstems.com/api/v1/download.php?id=1699456789_4" \
-H "Authorization: Bearer YOUR_API_KEY" \
--output stems.zip
| Status Code | Description |
|---|---|
| 200 | Success |
| 400 | Bad Request (invalid parameters) |
| 401 | Unauthorized (invalid API key) |
| 403 | Forbidden (rate limit exceeded) |
| 404 | Not Found |
| 405 | Method Not Allowed |
| 500 | Internal Server Error |
Error responses include a JSON object with error details:
{
"error": "Error message here",
"message": "Additional error details when available"
}
import requests
API_KEY = 'your-api-key'
API_BASE = 'https://ezstems.com/api/v1'
# Upload file
with open('song.mp3', 'rb') as f:
response = requests.post(
f'{API_BASE}/upload.php',
headers={'Authorization': f'Bearer {API_KEY}'},
files={'file': f},
data={'stems': 4}
)
process_id = response.json()['data']['id']
# Check status
status_response = requests.get(
f'{API_BASE}/status.php',
headers={'Authorization': f'Bearer {API_KEY}'},
params={'id': process_id}
)
# Download when ready
if status_response.json()['data']['status'] == 'completed':
download_response = requests.get(
f'{API_BASE}/download.php',
headers={'Authorization': f'Bearer {API_KEY}'},
params={'id': process_id},
stream=True
)
with open('stems.zip', 'wb') as f:
for chunk in download_response.iter_content(chunk_size=8192):
f.write(chunk)
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const API_KEY = 'your-api-key';
const API_BASE = 'https://ezstems.com/api/v1';
async function processSong() {
try {
// Upload file
const form = new FormData();
form.append('file', fs.createReadStream('song.mp3'));
form.append('stems', '4');
const uploadResponse = await axios.post(`${API_BASE}/upload.php`, form, {
headers: {
...form.getHeaders(),
'Authorization': `Bearer ${API_KEY}`
}
});
const processId = uploadResponse.data.data.id;
// Check status
const statusResponse = await axios.get(`${API_BASE}/status.php`, {
params: { id: processId },
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
// Download when ready
if (statusResponse.data.data.status === 'completed') {
const writer = fs.createWriteStream('stems.zip');
const downloadResponse = await axios.get(`${API_BASE}/download.php`, {
params: { id: processId },
headers: { 'Authorization': `Bearer ${API_KEY}` },
responseType: 'stream'
});
downloadResponse.data.pipe(writer);
}
} catch (error) {
console.error('Error:', error.response?.data || error.message);
}
}
processSong();
For API support or questions, contact us at: