Skip to main content

Job Management

This document explains how to create, monitor, and manage results for high-quality music separation jobs using the GSEP-Music-HQ model. Jobs are processed asynchronously after creation, and you can check the status to confirm results.

Create a Job

POST
https://restapi.gaudiolab.io/developers/api/v1/gsep_music_hq_v1/jobs

Creates a job. When the job is successfully created, the response includes the job ID.

Request Body

FieldRequiredTypeDescription
audioUploadIdYesStringID of the uploaded media file. See File Upload Guide
typeYesStringComma-separated string of instrument types to separate.
You can freely combine one or more of the following options:
'vocal', 'drum', 'bass', 'electric_guitar', 'acoustic_piano'

Response Body

FieldTypeDescription
jobIdStringID of the created job

Example

Request

curl -X POST 'https://restapi.gaudiolab.io/developers/api/v1/gsep_music_hq_v1/jobs' \
-H 'Content-Type: application/json' \
-H 'x-ga-apikey: {API_KEY}' \
-d '{
"audioUploadId": "{UPLOAD_ID}",
"type": "vocal,drum"
}'

Response

{
'resultCode': 1000,
'resultData': {
'jobId': 'aaffd346-74fc-11f0-8de9-0242ac120002'
}
}

Get a Job

GET
https://restapi.gaudiolab.io/developers/api/v1/gsep_music_hq_v1/jobs/{jobId}

Retrieves the current status of the created job.

Path Parameters

ParameterRequiredDescription
jobIdYesID of the job to retrieve. See Create a Job

Response Body

FieldTypeDescription
jobIdStringID of the retrieved job.
statusStringCurrent status of the job. One of the following values:
- success: Job completed successfully
- running: The job is currently being processed. Processing time varies depending on the product, processing options, and input file.
- waiting: The job has passed validation and entered the queue. Processing time may be longer if there are many jobs waiting in the queue.
- failed: Job failed
expireAtStringExpiration time of the job result data.
Result files cannot be downloaded after this time.
downloadUrlObjectURL information for job result data.
Contains download URLs for result files based on the specified type in the request.
vocalObjectProvided when 'vocal' is included in type.
    └ mp3StringVocal MP3 file download URL
    └ wavStringVocal WAV file download URL
drumObjectProvided when 'drum' is included in type.
    └ mp3StringDrum MP3 file download URL
    └ wavStringDrum WAV file download URL
bassObjectProvided when 'bass' is included in type.
    └ mp3StringBass MP3 file download URL
    └ wavStringBass WAV file download URL
electric_guitarObjectProvided when 'electric_guitar' is included in type.
    └ mp3StringElectric guitar MP3 file download URL
    └ wavStringElectric guitar WAV file download URL
acoustic_pianoObjectProvided when 'acoustic_piano' is included in type.
    └ mp3StringAcoustic piano MP3 file download URL
    └ wavStringAcoustic piano WAV file download URL

Example

Request

curl -X GET "https://restapi.gaudiolab.io/developers/api/v1/gsep_music_hq_v1/jobs/{JOB_ID}" \
-H 'x-ga-apikey: {API_KEY}'

Response

{
'resultCode': 1000,
'resultData': {
'jobId': 'aaffd346-74fc-11f0-8de9-0242ac120002',
'status': 'success',
'errorMessage': null,
'expireAt': '2025-09-01T12:00:00Z',
'downloadUrl': {
'vocal': {
'mp3': 'https://cdn_url/input-filename_vocal.mp3',
'wav': 'https://cdn_url/input-filename_vocal.wav'
},
'drum': {
'mp3': 'https://cdn_url/input-filename_drum.mp3',
'wav': 'https://cdn_url/input-filename_drum.wav'
}
}
}
}

Sample Code

import os
import requests
import time
import json

SLEEP_INTERVAL = 10
SERVER = "https://restapi.gaudiolab.io/developers/api"

API_CREATE_UPLOAD = "/v1/files/upload-multipart/create"
API_COMPLETE_UPLOAD = "/v1/files/upload-multipart/complete"
API_CREATE_JOB = "/v1/gsep_music_hq_v1/jobs"
API_JOB_STATUS = "/v1/gsep_music_hq_v1/jobs/{}"

API_KEY = 'api_key_here'
INPUT_FILE = './test_file.wav'


def send_request(method, api, payload):
headers = {
'x-ga-apikey': API_KEY
}
if method == "POST":
return requests.post(SERVER + api, headers=headers, json=payload)
elif method == "GET":
return requests.get(SERVER + api, headers=headers)
else:
raise ValueError(f"Invalid method: {method}")

def read_in_chunks(file_object, chunk_size):
while True:
data = file_object.read(chunk_size)
if not data:
break
yield data


def main():
print("\n[STEP] Create Upload URL")
print("-" * 40)
file_size = os.path.getsize(INPUT_FILE)
payload = {
'fileName': os.path.basename(INPUT_FILE),
'fileSize': file_size
}
create_resp = send_request("POST", API_CREATE_UPLOAD, payload)
if create_resp.status_code != 200:
print(f" ERROR) Request failed: status_code {create_resp.status_code}, {create_resp.text}")
return

result_code = create_resp.json().get('resultCode')
if result_code != 1000:
result_message = create_resp.json().get('resultMessage')
print(f" ERROR) Create upload url failed: resultCode {result_code}, resultMessage {result_message}")
return

result_data = create_resp.json()['resultData']
upload_id = result_data['uploadId']
chunk_size = result_data['chunkSize']
urls = result_data['preSignedUrl']
print(f" SUCCESS) uploadId: {upload_id}")
print(f" SUCCESS) chunkSize: {chunk_size} bytes")
print(f" SUCCESS) chunks: {len(urls)}")


print("\n[STEP] Upload File")
print("-" * 40)
parts = []
with open(INPUT_FILE, 'rb') as f:
print(f" INFO) Uploading {len(urls)} chunk(s)")
for i, chunk in enumerate(read_in_chunks(f, chunk_size)):
resp = requests.put(urls[i], data=chunk)
etag = resp.headers.get('ETag', '').replace('"', '')
parts.append({'awsETag': etag, 'partNumber': i + 1})
print(f" PROGRESS) chunk {i + 1}/{len(urls)} uploaded")


print("\n[STEP] Complete Upload")
print("-" * 40)
complete_payload = {'uploadId': upload_id, 'parts': parts}
complete_resp = send_request("POST", API_COMPLETE_UPLOAD, complete_payload)
if complete_resp.status_code != 200:
print(f" ERROR) Request failed: status_code {complete_resp.status_code}, {complete_resp.text}")
return

result_code = complete_resp.json().get('resultCode')
if result_code != 1000:
result_message = complete_resp.json().get('resultMessage')
print(f" ERROR) Upload complete failed: resultCode {result_code}, resultMessage {result_message}")
return

print(" SUCCESS) Upload completed successfully")


print("\n[STEP] Create Job")
print("-" * 40)
job_payload = {'audioUploadId': upload_id, 'type': 'vocal,drum'}
job_resp = send_request("POST", API_CREATE_JOB, job_payload)
if job_resp.status_code != 200:
print(f" ERROR) Request failed: status_code {job_resp.status_code}, {job_resp.text}")
return

result_code = job_resp.json().get('resultCode')
if result_code != 1000:
result_message = job_resp.json().get('resultMessage')
print(f" ERROR) Create job failed: resultCode {result_code}, resultMessage {result_message}")
return

result_data = job_resp.json()['resultData']
job_id = result_data['jobId']
print(f" SUCCESS) jobId: {job_id}")


print("\n[STEP] Check Job Status")
print("-" * 40)
while True:
print(f" PROGRESS) Checking job status...")
status_resp = send_request("GET", API_JOB_STATUS.format(job_id), {})
if status_resp.status_code != 200:
print(f" ERROR) Request failed: status_code {status_resp.status_code}, {status_resp.text}")
break

result_code = status_resp.json().get('resultCode')
if result_code != 1000:
result_message = status_resp.json().get('resultMessage')
print(f" ERROR) Status check failed: resultCode {result_code}, resultMessage {result_message}")
break

result_data = status_resp.json()['resultData']
status = result_data['status']

if status == 'success':
download_url = result_data.get('downloadUrl')
print(" SUCCESS) Job completed!")
print(" Download URLs:")
print(json.dumps(download_url, indent=2))
break

print(f" PROGRESS) Status: {status}")
print(f" PROGRESS) Retrying in {SLEEP_INTERVAL} seconds...")
time.sleep(SLEEP_INTERVAL)

if __name__ == '__main__':
main()