How to Upload Files
Upload a local image, video, or audio file and use the returned URL as a WaveSpeedAI model input.
Recommended methods
SDK or CLI
The official clients handle the secure direct-upload flow automatically and still return a single URL:
wavespeed upload ./input.pngimport wavespeed
url = wavespeed.upload("./input.png")import { upload } from 'wavespeed';
const url = await upload('./input.png');url, err := client.Upload("./input.png")String url = client.upload("./input.png");The WaveSpeed ComfyUI nodes use the same direct-upload flow automatically for local images, video, and audio inputs.
HTTP
For raw HTTP integrations, first request a short-lived upload ticket, then PUT the file to its URL. File bytes go directly to storage instead of passing through the API gateway.
FILE="./input.png"
FILE_SIZE=$(wc -c < "$FILE" | tr -d ' ')
TICKET=$(curl --fail-with-body --silent --show-error \
-X POST "https://api.wavespeed.ai/api/v3/media/uploads" \
-H "Authorization: Bearer $WAVESPEED_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg filename "$(basename "$FILE")" --argjson size "$FILE_SIZE" \
'{filename: $filename, size: $size}')")
UPLOAD_URL=$(printf '%s' "$TICKET" | jq -r '.data.upload.url')
UPLOAD_HEADERS=()
while IFS= read -r header; do
UPLOAD_HEADERS+=(-H "$header")
done < <(printf '%s' "$TICKET" | jq -r \
'.data.upload.headers | to_entries[] | "\(.key): \(.value)"')
curl --fail-with-body -X PUT "$UPLOAD_URL" "${UPLOAD_HEADERS[@]}" --upload-file "$FILE"
printf '%s' "$TICKET" | jq -r '.data.download_url'filename and the exact byte size are required; the example calculates both. content_type is optional and is inferred from the filename when omitted. The maximum file size is 200 MiB.
Never send your WaveSpeedAI API key to the returned upload URL. The URL is a temporary credential, so do not log, persist, or share it.
Treat the returned upload.url as opaque. Its hostname and storage provider may change between uploads or as WaveSpeedAI infrastructure evolves. Always use the complete URL returned by the current ticket; do not hardcode, construct, replace, or rewrite its hostname.
Using the uploaded file
Pass download_url to the exact media field in the selected model’s schema:
{
"prompt": "A cat walking",
"image": "https://...your-uploaded-image..."
}Supported formats
Common image, video, and audio formats are supported, including JPG, PNG, WebP, GIF, MP4, MOV, WebM, MP3, WAV, AAC, FLAC, M4A, and Opus.
Retention and acceptable use
Uploaded files are stored for 7 days and then automatically deleted. The service is only for WaveSpeedAI inference inputs, not general-purpose storage, distribution, or inputs to other AI platforms. Excessive upload traffic without corresponding inference may be rate limited or rejected.
Upload availability uses rolling safeguards that take account status and recent inference activity into account. Paid accounts may receive limited recovery capacity after reaching their normal allowance. Limits are adaptive and may change, so clients should handle quota responses and retry later instead of depending on fixed thresholds.
Legacy compatibility
Existing integrations that require a single-request upload may continue using the legacy endpoint. It remains supported for compatibility, and existing services do not need to migrate immediately:
curl --fail-with-body --request POST \
"https://api.wavespeed.ai/api/v3/media/upload/binary" \
-H "Authorization: Bearer $WAVESPEED_API_KEY" \
-F "file=@./input.png"The response contains data.download_url, which can be passed to model inputs in the same way as the URL returned by the recommended direct-upload flow. The legacy endpoint uses the same supported formats, 200 MiB single-file limit, retention policy, and upload quota rules.
The legacy flow sends file bytes through the WaveSpeedAI API gateway and completes in one request. The recommended /api/v3/media/uploads flow uses a short-lived upload URL and a separate PUT, which can provide better upload performance. The legacy endpoint also supports a raw binary request body when the request provides a specific Content-Type and a filename through the file header or ext query parameter; see the API upload guide for complete examples.
API reference
See How to Upload Files (API) for response fields, complete HTTP examples, errors, and the legacy compatibility endpoint.