StemSplit API Reference
Complete reference for all API endpoints.
https://stemsplit.io/api/v1Bearer tokenAuthentication
All endpoints require Bearer token authentication. Get your API key from Settings → API Keys.
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxJobs
Create a new job from an uploaded file (uploadKey) or remote URL (sourceUrl).
Request Body
Job creation parameters
{
"uploadKey": "uploads/api_xxx/input.mp3",
// OR: "sourceUrl": "https://example.com/song.mp3",
"outputType": "BOTH",
"quality": "BEST",
"outputFormat": "MP3"
}Response
Created job details
{
"id": "clxxx123...",
"status": "PENDING",
"progress": 0,
"creditsRequired": 180,
"input": {
"fileName": "song.mp3",
"durationSeconds": 180,
"fileSizeBytes": 4500000
},
"options": {
"outputType": "BOTH",
"quality": "BEST",
"outputFormat": "MP3"
}
}List all stem separation jobs for the authenticated user with pagination.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | No | Max results (default: 20, max: 100) |
offset | integer | No | Skip N results for pagination |
status | string | No | Filter by status (PENDING, PROCESSING, COMPLETED, FAILED) |
Response
Paginated list of jobs
{
"jobs": [
{
"id": "clxxx123...",
"status": "COMPLETED",
"progress": 100,
"createdAt": "2024-01-05T12:00:00Z",
"completedAt": "2024-01-05T12:02:30Z",
"input": { "fileName": "song.mp3", "durationSeconds": 180 },
"options": { "outputType": "BOTH", "quality": "BEST", "outputFormat": "MP3" },
"creditsCharged": 180
}
],
"pagination": {
"total": 42,
"limit": 20,
"offset": 0,
"hasMore": true
}
}Get status, progress, and download links for a specific job.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Job ID |
Response
Job details with download URLs (when completed)
{
"id": "clxxx123...",
"status": "COMPLETED",
"progress": 100,
"createdAt": "2024-01-05T12:00:00Z",
"completedAt": "2024-01-05T12:02:30Z",
"input": {
"fileName": "song.mp3",
"durationSeconds": 180,
"fileSizeBytes": 4500000
},
"options": {
"outputType": "BOTH",
"quality": "BEST",
"outputFormat": "MP3"
},
"audioMetadata": {
"bpm": 120.0,
"key": "Gm"
},
"outputs": {
"vocals": {
"url": "https://storage.example.com/vocals.mp3?sig=...",
"expiresAt": "2024-01-05T13:00:00Z"
},
"instrumental": {
"url": "https://storage.example.com/instrumental.mp3?sig=...",
"expiresAt": "2024-01-05T13:00:00Z"
}
},
"creditsCharged": 180
}Upload
Get a presigned URL for uploading an audio file. Use the returned uploadKey when creating a job.
Request Body
Upload request
{
"filename": "my-song.mp3",
"contentType": "audio/mpeg" // optional, auto-detected
}Response
Presigned upload URL and key
{
"uploadUrl": "https://storage.example.com/presigned-url...",
"uploadKey": "uploads/api_xxx/input.mp3",
"expiresAt": "2024-01-05T12:15:00Z",
"maxFileSizeBytes": 52428800,
"maxFileSizeMb": 50,
"contentType": "audio/mpeg",
"instructions": {
"step1": "PUT your file to the uploadUrl with Content-Type: audio/mpeg",
"step2": "Use the uploadKey when calling POST /api/v1/jobs",
"note": "The upload URL expires in 15 minutes"
}
}YouTube
Create a stem separation job from a YouTube video URL. Extracts vocals and instrumental.
Request Body
YouTube job request
{
"youtubeUrl": "https://youtube.com/watch?v=dQw4w9WgXcQ"
}Response
Created YouTube job
{
"id": "clxxx123...",
"status": "PENDING",
"videoId": "dQw4w9WgXcQ",
"videoTitle": "Rick Astley - Never Gonna Give You Up",
"videoDuration": 213,
"videoThumbnail": "https://i.ytimg.com/vi/...",
"channelName": "Rick Astley",
"creditsRequired": 213,
"outputs": ["vocals", "instrumental"],
"createdAt": "2024-01-05T12:00:00Z"
}List all YouTube stem separation jobs for the authenticated user.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | No | Max results (default: 20, max: 100) |
offset | integer | No | Skip N results for pagination |
status | string | No | Filter by status |
Response
Paginated list of YouTube jobs
{
"jobs": [
{
"id": "clxxx123...",
"status": "COMPLETED",
"videoId": "dQw4w9WgXcQ",
"videoTitle": "Rick Astley - Never Gonna Give You Up",
"videoDuration": 213,
"creditsCharged": 213,
"createdAt": "2024-01-05T12:00:00Z",
"completedAt": "2024-01-05T12:03:00Z"
}
],
"pagination": {
"total": 5,
"limit": 20,
"offset": 0,
"hasMore": false
}
}Get status, progress, and download links for a YouTube job.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Job ID |
Response
YouTube job with download URLs (when completed)
{
"id": "clxxx123...",
"status": "COMPLETED",
"progress": 100,
"videoId": "dQw4w9WgXcQ",
"videoTitle": "Rick Astley - Never Gonna Give You Up",
"videoDuration": 213,
"audioMetadata": {
"bpm": 113.0,
"key": "Am"
},
"outputs": {
"fullAudio": {
"url": "https://storage.example.com/full.mp3?sig=...",
"expiresAt": "2024-01-05T13:00:00Z"
},
"vocals": {
"url": "https://storage.example.com/vocals.mp3?sig=...",
"expiresAt": "2024-01-05T13:00:00Z"
},
"instrumental": {
"url": "https://storage.example.com/instrumental.mp3?sig=...",
"expiresAt": "2024-01-05T13:00:00Z"
}
},
"creditsCharged": 213
}Account
Get the current credit balance for the authenticated user.
Response
Credit balance
{
"balanceSeconds": 3600,
"balanceMinutes": 60,
"balanceFormatted": "60 minutes",
"updatedAt": "2024-01-05T12:00:00Z"
}Webhooks
Register a URL to receive job completion/failure notifications. The signing secret is only returned once.
Request Body
Webhook registration
{
"url": "https://your-server.com/webhook",
"events": ["job.completed", "job.failed"]
}Response
Created webhook with signing secret (shown once)
{
"id": "whk_xxx...",
"url": "https://your-server.com/webhook",
"events": ["job.completed", "job.failed"],
"secret": "whsec_xxxxxxxxxxxx",
"isActive": true,
"createdAt": "2024-01-05T12:00:00Z"
}List all registered webhooks. Note: secrets are not returned in this endpoint.
Response
List of webhooks
{
"webhooks": [
{
"id": "whk_xxx...",
"url": "https://your-server.com/webhook",
"events": ["job.completed", "job.failed"],
"isActive": true,
"failCount": 0,
"lastError": null,
"lastCalledAt": "2024-01-05T11:30:00Z",
"createdAt": "2024-01-05T10:00:00Z"
}
]
}Remove a registered webhook. You will no longer receive notifications at this URL.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Webhook ID |
Response
Deletion confirmation
{
"deleted": true
}Data Types
Job Status
PENDINGQueued for processingPROCESSINGCurrently being processedCOMPLETEDDone, outputs availableFAILEDError occurredEXPIREDOutputs have expiredOutput Type
VOCALSJust vocalsINSTRUMENTALBacking trackBOTHVocals + InstrumentalFOUR_STEMSVocals, Drums, Bass, OtherSIX_STEMSIncludes Piano, GuitarQuality
FAST~30% of realtimeBALANCED~60% of realtimeBESTHighest qualityOutput Format
MP3Compressed, smaller filesWAVUncompressed, losslessFLACCompressed, losslessRate Limits
Default rate limit is 60 requests per minute per API key. Rate limit headers are included in all responses.
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per minute |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when limit resets |
Retry-After | Seconds until you can retry (on 429) |
Webhook Events
Webhooks deliver real-time notifications when job status changes.
Headers
| Header | Description |
|---|---|
X-Webhook-Signature | HMAC-SHA256 signature (sha256=xxx) |
X-Webhook-Event | Event type (job.completed, job.failed) |
X-Webhook-Id | Webhook endpoint ID |
Payload Example (job.completed)
{
"event": "job.completed",
"timestamp": "2024-01-05T12:30:00Z",
"data": {
"jobId": "clxxx123...",
"status": "COMPLETED",
"input": {
"fileName": "song.mp3",
"durationSeconds": 180,
"fileSizeBytes": 4500000
},
"options": {
"outputType": "BOTH",
"quality": "BEST",
"outputFormat": "MP3"
},
"outputs": {
"vocals": {
"url": "https://storage.example.com/vocals.mp3?sig=...",
"expiresAt": "2024-01-05T13:30:00Z"
},
"instrumental": {
"url": "https://storage.example.com/instrumental.mp3?sig=...",
"expiresAt": "2024-01-05T13:30:00Z"
}
},
"creditsCharged": 180,
"createdAt": "2024-01-05T12:00:00Z",
"completedAt": "2024-01-05T12:02:30Z"
}
}