Upload File
curl --request POST \
--url https://api.muvi.video/v1/uploads/presign \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"filename": "<string>",
"contentType": "<string>"
}
'import requests
url = "https://api.muvi.video/v1/uploads/presign"
payload = {
"filename": "<string>",
"contentType": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({filename: '<string>', contentType: '<string>'})
};
fetch('https://api.muvi.video/v1/uploads/presign', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"uploadUrl": "<string>",
"fileUrl": "<string>",
"fileId": "<string>",
"expiresAt": "<string>",
"maxSize": 123
}File Uploads
Upload File
Generate a presigned URL to upload a temporary file. Files are automatically deleted after 60 minutes.
POST
/
v1
/
uploads
/
presign
Upload File
curl --request POST \
--url https://api.muvi.video/v1/uploads/presign \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"filename": "<string>",
"contentType": "<string>"
}
'import requests
url = "https://api.muvi.video/v1/uploads/presign"
payload = {
"filename": "<string>",
"contentType": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({filename: '<string>', contentType: '<string>'})
};
fetch('https://api.muvi.video/v1/uploads/presign', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"uploadUrl": "<string>",
"fileUrl": "<string>",
"fileId": "<string>",
"expiresAt": "<string>",
"maxSize": 123
}Authentication
This endpoint requires an API key.Authorization: Bearer YOUR_API_KEY
Request Body
string
required
Name of the file to upload. Example:
"my-image.png"string
required
MIME type of the file. Allowed types:
image/jpeg, image/png, image/webp, image/gif, video/mp4, video/webm, audio/mpeg, audio/wav.Response
string
Presigned PUT URL. Upload your file here with a PUT request within 15 minutes.
string
CDN URL where the file will be accessible after upload. Use this URL in job inputs.
string
Unique identifier for the upload. Use to check status.
string
ISO 8601 timestamp when the file will be automatically deleted (60 minutes from creation).
number
Maximum allowed file size in bytes. Images: 10MB, Videos: 100MB, Audio: 50MB.
How It Works
- Call this endpoint to get a presigned upload URL
- Upload your file via PUT to the
uploadUrl(includeContent-Typeheader) - Use the
fileUrlin your job submission input - File is automatically deleted after 60 minutes
Error Codes
| Code | Description |
|---|---|
VALIDATION_ERROR | Missing or invalid filename/contentType. |
INVALID_CONTENT_TYPE | Content type not in the allowed list. |
Examples
# Step 1: Get presigned URL
curl -X POST https://api.muvi.video/v1/uploads/presign \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filename": "my-image.png",
"contentType": "image/png"
}'
# Step 2: Upload file to the presigned URL
curl -X PUT "UPLOAD_URL_FROM_RESPONSE" \
-H "Content-Type: image/png" \
--data-binary "@my-image.png"
# Step 3: Use fileUrl in job submission
curl -X POST https://api.muvi.video/v1/jobs/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "google/nano-banana-pro/edit-image",
"input": {
"image": "FILE_URL_FROM_RESPONSE",
"prompt": "Add a sunset background"
}
}'
import requests
# Step 1: Get presigned URL
response = requests.post(
"https://api.muvi.video/v1/uploads/presign",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
json={
"filename": "my-image.png",
"contentType": "image/png"
}
)
data = response.json()["data"]
print(f"File URL: {data['fileUrl']}")
print(f"Expires at: {data['expiresAt']}")
# Step 2: Upload file
with open("my-image.png", "rb") as f:
requests.put(
data["uploadUrl"],
headers={"Content-Type": "image/png"},
data=f
)
# Step 3: Use in job submission
job = requests.post(
"https://api.muvi.video/v1/jobs/submit",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
json={
"model": "google/nano-banana-pro/edit-image",
"input": {
"image": data["fileUrl"],
"prompt": "Add a sunset background"
}
}
)
// Step 1: Get presigned URL
const response = await fetch("https://api.muvi.video/v1/uploads/presign", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
filename: "my-image.png",
contentType: "image/png"
})
});
const { data } = await response.json();
console.log(`File URL: ${data.fileUrl}`);
// Step 2: Upload file
const file = await fs.readFile("my-image.png");
await fetch(data.uploadUrl, {
method: "PUT",
headers: { "Content-Type": "image/png" },
body: file
});
// Step 3: Use in job submission
const job = await fetch("https://api.muvi.video/v1/jobs/submit", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "google/nano-banana-pro/edit-image",
input: {
image: data.fileUrl,
prompt: "Add a sunset background"
}
})
});
Example Response
{
"success": true,
"data": {
"uploadUrl": "https://storage.muvi.video/temp/...",
"fileUrl": "https://assetsv1.cdn.muvi.video/temp/user_abc123/uuid_my-image.png",
"fileId": "3f44e3c6-acd9-4cc3-a91b-e63ec517b383",
"expiresAt": "2026-02-25T11:42:21.949Z",
"maxSize": 10485760
},
"requestId": "req_abc123"
}
