Overview
Most Magic Hour APIs use a file-based workflow: you provide input files (images, videos, audio), the API processes them, and returns generated output files. Some APIs like AI Image Generator or Text-to-Video work with text prompts instead. This guide covers both sides of file handling: getting your files to Magic Hour and retrieving the results.Input Files
How to Provide Input Files
Choose the input route that fits where your media is stored:Reuse saved assets
CallGET /v1/saved-items to list characters, references,
voices, moodboards, and brand kits owned by the account behind your API key. Filter with type
when you need one saved-item category.
Each item contains an assets array. Match an asset’s media_kind to the endpoint’s required
input type, and pass its returned file_path to a compatible asset field without uploading again.
Use the asset path rather than the saved item’s id. This reuses the file; it does not apply the
web app’s saved-character, moodboard, or brand-kit prompt binding automatically.
Asset url values are temporary preview/download links; use url_expires_at to check expiry.
The saved asset’s file_path is durable. To continue listing, pass the response’s non-null
next_cursor as cursor.
For example, an image asset can be supplied to
Image Editor, and an audio asset can be supplied
to Voice Cloner, subject to those endpoints’ input
and model requirements.
Option 1: Using Public URLs
The simplest method if your files are already hosted somewhere publicly accessible:URL Requirements
- Must use a public or pre-signed URL that returns file bytes without a login page
- Must include the file extension in the URL
- Should use HTTPS for security
- Files must be in supported formats
Option 2: Reusing Completed Outputs
A My Library URL such ashttps://magichour.ai/my-library?videoId=... opens a dashboard page. Do not pass it as video_file_path, image_file_path, or audio_file_path.
Retrieve the existing project with Get video details, Get image details, or Get audio details, using the same account’s API key. Wait until status is complete, then use the matching downloads[].url as the input for another compatible endpoint.
Using Completed Outputs in API Calls
Use your initialized SDK client and replace the project ID variables below with your own video and image project IDs. These lookups reuse existing projects; the Face Swap call creates a new generation and uses credits.Download URLs are temporary. Check
expires_at and retrieve project details again for a fresh URL when needed. Keep the complete signed URL, including its query parameters. Reusing a file still requires a compatible media type and supported endpoint inputs.assets[].file_path returned by List saved items, as described above.
Option 3: Uploading to Magic Hour Storage
For local files or files that aren’t publicly hosted, upload them to Magic Hour’s storage:Upload Process
The upload workflow has three steps:- Request upload URLs - Tell Magic Hour what file types you’re uploading (specify extension and type)
- Upload files - PUT your files to the provided temporary URLs
- Use file paths - Reference the returned
file_pathin your API calls
SDK Upload (Simplified)
Python and Node.js SDKs provide a helper function:SDK Version Required: Python SDK v0.36.0+ or Node SDK v0.37.0+ Go and Rust SDKs: Manual upload
process (shown below)
Manual Upload Process
For Go, Rust, or custom implementations:Upload Response Format
upload_url: Temporary pre-signed URL to upload the file to (send aPUTrequest)expires_at: When theupload_urlexpires and a new one must be requestedfile_path: Reference to pass in API calls (e.g.image_file_path,video_file_path,audio_file_path)
Uploading Multiple Files
Request multiple upload URLs in a single call:Output Files
Download URLs
When a job completes successfully, the response includes download URLs:Download URL Expiration
To get fresh download URLs for an existing project:Streaming Downloads
The Python example streams response chunks. The Node.js example buffers the complete file in memory before writing; it is not a memory-efficient streaming implementation.Handling Multiple Output Files
Some APIs generate multiple files (e.g., multiple images):Automatic Downloads with generate()
The SDK’s generate() function can download files automatically:
File Specifications
Supported File Formats
Video
mp4, m4v, mov, webm
Image
png, jpg, jpeg, jfif, heic, heif, webp, avif, jp2, tiff, tif, bmp
Audio
mp3, wav, aac, flac, webm, weba, m4a, opus, ogg, oga, aiff, amr
gif extension is only supported by face swap API’s video_file_path field.File Size Limits
Different subscription tiers have different upload limits:Upgrade for Larger Files: If you need to process files larger than your current limit, upgrade
your subscription tier.
Retention & Storage Policies
Uploaded Files (Inputs)
Temporary Storage: Upload files shortly before use and keep source copies in your own storage. Reuse afile_path only while the file remains available. The upload URL’s expires_at is the deadline for uploading, not a deletion deadline. Retention varies by feature and storage path; see Trust & Privacy for current data handling and deletion options.
file_path for multiple API calls to avoid duplicate uploads.
Generated Files (Outputs)
Output Storage: Download completed outputs you want to retain and keep your own copies. Availability depends on the feature and whether the project or file has been deleted. Download URL Expiration: Use each download’sexpires_at; retrieving a project does not guarantee another full 24 hours. If a URL expires, retrieve that same available, completed project for current URLs rather than generating again.
Web Dashboard: All generated content appears in your magichour.ai/my-library dashboard.
Getting Fresh Download URLs
If a download URL expires while the completed project and file remain available, retrieve that project for current URLs:Best Practices
For Uploads
✅ Do:- Validate file formats before uploading
- Use the SDK upload helpers when available
- Reuse uploaded files while they remain available
- Compress large files to save upload time
- Upload the same file repeatedly (reuse the
file_path) - Exceed your tier’s file size limits
- Assume uploaded files remain available indefinitely
For Downloads
✅ Do:- Download files immediately after job completion
- Implement retry logic with exponential backoff
- Stream large files to avoid memory issues
- Store files in your own storage for permanent access
- Verify file integrity after download
- Rely on download URLs after their returned
expires_at - Download the same file multiple times unnecessarily
- Ignore download errors without retry logic
Troubleshooting
Upload Issues
“Invalid file format” error:- Check that your file extension is in the supported list
- Verify the file isn’t corrupted
- Ensure the file type matches the extension
- Check your subscription tier’s upload limit
- Compress the file or upgrade your subscription
- Split large videos into smaller segments
- Check your internet connection
- Try uploading during off-peak hours
- Consider using a CDN for faster uploads
Download Issues
“URL expired” error:- Retrieve the available, completed project using the GET endpoint for current download URLs
- Download files before each URL’s returned
expires_at - Store files in your own storage for permanent access
- Implement retry logic with exponential backoff
- Verify file integrity (check file size matches)
- Use streaming downloads for large files
- Verify the job ID is correct
- Ensure the job status is “complete”
- Check that the project hasn’t been deleted
Next Steps
First Integration
Build your first integration step-by-step
Development & Testing
Test without using credits
API Reference
Complete upload API documentation
Webhooks
Set up webhooks for production apps
Questions? Join our Discord community or email support@magichour.ai