This is a client-side method to upload files using the signed URL obtained from the /upload/signed-url endpoint.
Pricing:
- API calls are free
- Storage fee: $0.001/1GB per day
Quick Start: Use the “Complete Example” section below to get a signed URL and upload a file in one go. Just replace the file path and run the code!
Workflow
- Get a signed URL and
asset_id from /upload/signed-url
- Use the signed URL to upload your file directly to storage
- Verify upload completion via
/get-metadata (poll until upload_status is SUCCESS)
Complete Example (Ready to Test)
Here’s a complete example that shows how to get a signed URL and use it for upload:
import requests
BASE_URL = "https://mavi-backend.memories.ai/serve/api/v2"
API_KEY = "sk-mai-this_a_test_string_please_use_your_generated_key_during_testing"
HEADERS = {
"Authorization": f"{API_KEY}"
}
# Step 1: Get signed URL from /upload/signed-url
def get_signed_url(original_filename: str) -> tuple[str, str]:
"""Get a signed URL and asset_id for file upload"""
url = f"{BASE_URL}/upload/signed-url"
data = {"original_filename": original_filename}
response = requests.post(url, json=data, headers=HEADERS)
result = response.json()
print(f"Signed URL response: {result}")
return result['data']['signed_url'], result['data']['asset_id']
# Step 2: Upload file using the signed URL
def upload_by_signed_url(signed_url: str, file_path: str) -> tuple[int, str]:
"""
Upload file using signed URL
Args:
signed_url: The signed URL obtained from /upload/signed-url
file_path: Path to the local file to upload
Returns:
Tuple of (status_code, response_text)
"""
with open(file_path, "rb") as f:
files = {"file": (file_path, f)}
resp = requests.post(signed_url, files=files)
return resp.status_code, resp.text
# Complete workflow - ready to test
if __name__ == "__main__":
# Replace with your actual file path
file_path = "path/to/your/video.mp4"
original_filename = "video.mp4"
# Get signed URL and asset_id
print("Step 1: Getting signed URL...")
signed_url, asset_id = get_signed_url(original_filename)
print(f"Asset ID: {asset_id}")
print(f"Signed URL: {signed_url[:100]}...")
# Upload file
print("\nStep 2: Uploading file...")
status, response = upload_by_signed_url(signed_url, file_path)
print(f"Upload status: {status}")
print(f"Upload response: {response}")
print(f"\nUse asset_id '{asset_id}' for subsequent API calls (e.g., /video/edit, /transcriptions)")
Code Examples (Using Existing Signed URL)
// Assuming you have the signed URL
const signedUrl = "https://storage.example.com/upload?signature=...";
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
const formData = new FormData();
formData.append('file', file);
const response = await fetch(signedUrl, {
method: 'POST',
body: formData
});
if (response.ok) {
console.log('Upload successful');
} else {
console.error('Upload failed:', response.status);
}
Parameters
| Parameter | Type | Required | Description |
|---|
| signed_url | string | Yes | The pre-signed URL obtained from /upload/signed-url |
| file | File/Blob | Yes | The file to upload |
Response
Returns HTTP status code and response text from the storage service.
Success Response (200):
Status: 200 OK
File uploaded successfully
Error Response (4xx/5xx):
Status: 400/500
Error message from storage service
Confirming Upload Completion
After uploading via the signed URL, the MAVI backend automatically detects the file. Use the Get Metadata endpoint with the asset_id (returned in Step 1) to verify the upload is complete:
# Step 3: Confirm upload is complete
metadata = get_metadata(asset_id)
status = metadata['data']['resource'][0]['upload_status']
print(f"Upload status: {status}") # Should be "SUCCESS"
| Status | Description |
|---|
WAITING | Upload request received, waiting to process |
UPLOADING | File is being uploaded and processed |
SUCCESS | Upload completed — asset is ready for use |
FAILED | Upload failed — retry the upload |
Only assets with upload_status: "SUCCESS" can be used in subsequent API calls (transcription, editing, etc.). Poll the Get Metadata endpoint until the status is SUCCESS before proceeding.
Notes
- This upload happens directly to cloud storage (e.g., GCS)
- No authentication headers needed — the URL contains the signature
- Signed URLs expire after the time specified in
expires_in (typically 26 hours)
- Make sure to upload the file before the URL expires
- Supports files up to 5 GB (for files under 500 MB, you can also use the simpler direct upload)