Developer API
Subclip Enhance Voice API
Upload an audio or video file, run Subclip's Cleanvoice or Resemble AI enhancement pipeline, poll job status, and download the result.
Get your API key from Developer Portal. API jobs use the same AI credits as the app. Credits are deducted after successful processing. Outputs and input files are deleted 1 hour after completion to free storage quota.
Authentication
Pass your API key in either header:
Authorization: Bearer YOUR_SUBCLIP_API_KEY x-api-key: YOUR_SUBCLIP_API_KEY
Before you start
Check API key setup, storage quota, and AI credit status on the API overview.
1. Create an upload URL
This creates a Subclip project id. The same projectId is used for upload, job creation, status, and download.
Audio and video inputs are supported. Use the real contentType and fileSize for the file you will upload.
curl -X POST https://www.subclip.app/api/v1/enhance-video/uploads \
-H "Authorization: Bearer $SUBCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fileName": "interview.mp4",
"contentType": "video/mp4",
"fileSize": 52428800,
"projectName": "Interview cleanup"
}'{
"projectId": "veproj_...",
"uploadUrl": "https://...",
"objectKey": "user/voice-enhance/...",
"expiresIn": 900
}2. Upload the file
Content-Length must match the actual file size. curl --data-binary usually sets it automatically, but Node.js streamed uploads need it explicitly.
curl -X PUT "$UPLOAD_URL" \ -H "Content-Type: video/mp4" \ -H "Content-Length: 52428800" \ --data-binary "@interview.mp4"
3. Start enhancement
durationSeconds is optional. Subclip always detects the uploaded media duration server-side with ffprobe and uses the detected duration for the credit check. If you provide durationSeconds, Subclip verifies it against the uploaded file and rejects mismatches before processing starts.
provider is optional and defaults to cleanvoice. Use cleanvoice when you want an enhanced video output for video input. Use resemble for Resemble AI voice enhancement. For video inputs, Subclip muxes the enhanced Resemble audio back onto the original video and returns final video. For audio inputs, the result is enhanced audio.
backgroundMusicSeparationEnabled is optional and defaults to false. Enable it when you want Subclip to separate vocals before enhancement. This increases the estimated and final AI credits.
curl -X POST https://www.subclip.app/api/v1/enhance-video/jobs \
-H "Authorization: Bearer $SUBCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"projectId": "veproj_...",
"durationSeconds": 180,
"provider": "cleanvoice",
"backgroundMusicSeparationEnabled": false
}'4. Poll status
Poll every 5 seconds for normal videos. For longer videos, poll every 15 seconds. Do not poll in a tight loop; if you receive 429 rate_limited, wait until X-RateLimit-Reset before trying again.
curl https://www.subclip.app/api/v1/enhance-video/jobs/veproj_... \ -H "Authorization: Bearer $SUBCLIP_API_KEY"
{
"projectId": "veproj_...",
"status": "completed",
"provider": "cleanvoice",
"progress": 100,
"outputReady": true,
"outputMediaType": "video",
"creditsUsed": 19.47
}5. Download result
The Subclip API returns JSON with a short-lived signed download URL. Download that URL to get the enhanced bytes. Cleanvoice can return video for video inputs. Resemble returns final video for video inputs and enhanced audio for audio inputs.
DOWNLOAD_JSON=$(curl -s https://www.subclip.app/api/v1/enhance-video/jobs/veproj_.../download \ -H "Authorization: Bearer $SUBCLIP_API_KEY") DOWNLOAD_URL=$(echo "$DOWNLOAD_JSON" | jq -r '.downloadUrl') curl -L "$DOWNLOAD_URL" -o enhanced.mp4
{
"projectId": "veproj_...",
"downloadUrl": "https://...",
"expiresIn": 180,
"mediaType": "video",
"contentType": "video/mp4"
}Errors and limits
401: Missing or invalid API key.
403 FREE_TIER_QUOTA_EXCEEDED: Not enough AI credits. Add credits or upgrade, then retry.
404 upload_not_found: The video was not uploaded to the presigned URL.
400 duration_unavailable: Subclip could not determine the uploaded media duration.
400 duration_mismatch: The provided durationSeconds does not match the uploaded media duration.
409 output_not_ready: The job is still queued or processing.
429 rate_limited: Too many requests. Check X-RateLimit-Remaining and X-RateLimit-Reset.
507 storage_quota_exceeded: Not enough storage quota for the uploaded source video.