Skip to main content

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

Call GET /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:
Pre-signed URLs work when the URL itself grants access to the file. Magic Hour cannot forward your browser session, cookies, or custom authorization headers.

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 as https://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.
For saved library assets, use the durable 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:
  1. Request upload URLs - Tell Magic Hour what file types you’re uploading (specify extension and type)
  2. Upload files - PUT your files to the provided temporary URLs
  3. Use file paths - Reference the returned file_path in 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

Fields explained:
  • upload_url: Temporary pre-signed URL to upload the file to (send a PUT request)
  • expires_at: When the upload_url expires and a new one must be requested
  • file_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:
Upload Timing: Upload files just before using them in API calls. For permanent storage needs, contact support@magichour.ai.

Output Files

Download URLs

When a job completes successfully, the response includes download URLs:

Download URL Expiration

Temporary URLs: Download URLs are signed for 24 hours, but GET can return a still-valid cached URL. Use each download’s expires_at for its remaining validity. If a URL expires, retrieve the same completed project using GET for a current URL; do not create another generation.
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 a file_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.
Best practice: Reuse the same available 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’s expires_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
❌ Don’t:
  • 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
❌ Don’t:
  • 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
“File too large” error:
  • Check your subscription tier’s upload limit
  • Compress the file or upgrade your subscription
  • Split large videos into smaller segments
Upload timeout:
  • 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
Download fails or corrupts:
  • Implement retry logic with exponential backoff
  • Verify file integrity (check file size matches)
  • Use streaming downloads for large files
“404 Not Found” on download:
  • 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