Quickstart
Upload an asset, create a job, wait, download. Every model on the platform follows this same shape — get your first result in about five minutes, then pick a guide for the model you actually want.
Before you start
You need an API key from the dashboard. Send it on every request as the x-api-key header. See Authentication.
1. Upload your media
Uploading starts at POST /assets. The server looks at fileSize and tells you whether to do a single-shot upload (files up to 100 MiB) or a resumable multipart upload (files over 100 MiB). Either way you get back an assetId. The maximum file size is 6 GB; a larger fileSize is rejected with 413 FILE_TOO_LARGE. See Audio formats for supported source files and output format values.
# 1. Create an asset — start the upload
curl -X POST "https://api.dev.developers.gaudiolab.io/v1/assets" \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "fileName": "movie_reel_01.wav", "fileSize": 18400000 }'
# Response (small file → single-shot upload):
# {
# "assetId": "as_7f3a9c",
# "status": "awaiting_upload",
# "upload": { "mode": "single", "url": "https://upload..." }
# }# 2. Upload the bytes to the pre-signed URL
curl -X PUT "https://upload..." \
--upload-file movie_reel_01.wav2. Create a job
A job names the asset and a list of targets. Each target is one model, referenced by its alias from Models, and each runs independently — so a job can ask for several results at once and they can finish at different times.
What else a target carries depends on the model. Separation models take an optional processing tier; a text_sync model takes a second asset and its own parameters. Follow Separation or Text Sync once this flow works.
# Create a job — one target here; a job can carry several
curl -X POST "https://api.dev.developers.gaudiolab.io/v1/jobs" \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"assetId": "as_7f3a9c",
"targets": [
{ "model": "stem_vocal_v1", "formats": ["wav"] }
],
"webhookUrl": "https://my.app/hooks/jobs"
}'
# Response: { "jobId": "job_91b2e0", "status": "processing", "targets": [...] }3. Collect the results
In production, set a webhookUrl to be notified as each target finishes. If you poll instead, call GET /jobs/{jobId} about every 10 seconds until the status is completed or failed.
# 4. Poll for results (if you're not using a webhook; ~every 10s)
curl "https://api.dev.developers.gaudiolab.io/v1/jobs/job_91b2e0" \
-H "x-api-key: $API_KEY"
# When complete:
# {
# "jobId": "job_91b2e0",
# "status": "completed",
# "linksExpireAt": "2026-06-10T12:00:00Z",
# "targets": [
# { "model": "stem_vocal_v1", "status": "completed",
# "output": { "vocal": { "wav": "https://cdn/.../vocal.wav" } } }
# ]
# }Download links expire
Output links are valid for 48 hours. Re-fetching the job refreshes them, but we recommend downloading and storing the files in your own storage as soon as a target completes.
Full example (Python)
import os, time, requests
BASE = "https://api.dev.developers.gaudiolab.io/v1"
HEADERS = {"x-api-key": os.environ["API_KEY"]}
# 1) Create the asset
size = os.path.getsize("movie.wav")
asset = requests.post(f"{BASE}/assets", headers=HEADERS,
json={"fileName": "movie.wav", "fileSize": size}).json()
# 2) Upload the bytes (single mode shown)
with open("movie.wav", "rb") as f:
requests.put(asset["upload"]["url"], data=f)
# 3) Create the job
job = requests.post(f"{BASE}/jobs", headers=HEADERS, json={
"assetId": asset["assetId"],
"targets": [{"model": "stem_vocal_v1", "formats": ["wav"]}],
}).json()
# 4) Poll until done
while True:
result = requests.get(f"{BASE}/jobs/{job['jobId']}", headers=HEADERS).json()
if result["status"] in ("completed", "failed"):
break
time.sleep(10)
for t in result["targets"]:
print(t["model"], t["status"], t.get("output"))