Overview
The Magic Hour API enables developers to integrate AI-powered video and image generation directly into their applications. This guide provides a roadmap to the complete API ecosystem, helping you integrate Magic Hour's capabilities for enterprise-scale automation and custom workflows.
All Magic Hour API documentation is hosted at docs.magichour.ai. This guide is a companion reference for getting started and common integration patterns.
Prerequisites
An active subscription or pay-as-you-go plan
Access to the Developer Hub to create and manage API keys
Familiarity with REST APIs and JSON
One of: Python, Node.js, Go, Rust, or cURL for making API calls
Before You Begin
Security critical: Never expose your API key in client-side code, public repositories, or version control. Always keep API keys secure on your backend server to prevent unauthorized usage and credit depletion.
Compatibility
Product: Magic Hour API v1
Plans: Creator ($10/mo), Pro ($49/mo), Business ($249/mo), or usage-based pricing
SDKs: Python (v0.36.0+), Node.js (v0.37.0+), Go, Rust
REST API: Available via HTTP/cURL
Getting Started in 3 Steps
1. Create an API Key
Visit the Developer Hub API Keys page.
Click Create API Key.
Name your key (e.g., "Production App" or "Development").
Click Create key.
Copy and save the key in a secure location (e.g., environment variable).
Your API key is now ready. You'll use it as a Bearer token in the Authorization header for all API requests.
2. Choose Your Integration Method
Option A: Use an SDK (Recommended)
SDKs reduce boilerplate and handle error handling automatically.
# Python pip install magic_hour # Node.js npm install magic-hour-sdk
Option B: Direct HTTP Requests
Use cURL or your preferred HTTP library for full control:
curl -X POST https://api.magichour.ai/v1/image-projects/ai-images \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"style": {"prompt": "your prompt"}}'
3. Make Your First Request
Generate an Image (Python SDK)
from magic_hour import Client client = Client(token="YOUR_API_KEY") result = client.v1.ai_image_generator.generate( image_count=1, orientation="landscape", style={"prompt": "Epic anime art of a wizard"}, wait_for_completion=True, download_outputs=True, download_directory="outputs" ) print(f"Image created: {result.id}") print(f"Credits spent: {result.credits_charged}") print(f"Saved to: {result.downloaded_paths}")
Face Swap in a Video (Python SDK)
from magic_hour import Client import time client = Client(token="YOUR_API_KEY") # Create the job job = client.v1.face_swap.create( name="My face swap", assets={ "image_file_path": "https://example.com/face.jpg", "video_file_path": "https://example.com/video.mp4", "video_source": "file" }, start_seconds=0.0, end_seconds=10.0 ) print(f"Job ID: {job.id}")
Core API Architecture
Three-Step Workflow
All Magic Hour API jobs follow this pattern:
Create: Submit your generation request with parameters
Monitor: Poll status or use webhooks for real-time updates
Download: Retrieve your completed asset
Understanding Job Status
Status | Description | Action |
| Job waiting for available server capacity | β³ Keep polling |
| Job currently processing | β³ Keep polling |
| Job finished successfully | β Download result |
| Job failed during processing | β Handle error |
| Job was manually canceled | π Job stopped |
File Input Options
Supported Formats
Images: PNG, JPG, JPEG, WEBP, AVIF, JP2, TIFF, BMP
Videos: MP4, MOV, WEBM, M4V
Audio: MP3, MPEG, WAV, AAC, AIFF, FLAC
GIF format is only supported for the face swap video API's video_file_path field.
Option 1: URL References (Simplest)
Pass a URL to your hosted file directly:
{ "assets": { "image_file_path": "https://cdn.yoursite.com/face.jpg", "video_file_path": "https://cdn.yoursite.com/video.mp4" } } URLs can be authenticated as long as the file extension is supported.
Option 2: Upload to Magic Hour Storage
For files without public hosting, upload directly to Magic Hour:
Request upload URLs for your files
Upload files using the provided URLs (PUT request)
Use the returned
file_pathin your API calls
Upload Example (Python SDK)
from magic_hour import Client client = Client(token="YOUR_API_KEY") # Upload a file file_path = client.v1.files.upload_file("/path/to/your/image.jpg") # Use in API call result = client.v1.face_swap.create( assets={ "image_file_path": file_path, "video_file_path": "https://example.com/video.mp4" } ) Uploaded files are automatically cleaned up after 7 days. You can reference a file path in multiple API calls before it expires. For permanent storage needs, contact [email protected].
Status Monitoring Strategies
Option 1: Webhooks (Recommended for Production)
Best for:
Production applications
Long-running video processes (2-5 minutes)
Multiple concurrent jobs
Efficient server resource usage
Set up webhooks to receive real-time notifications when jobs complete. See Webhook Reference for complete setup instructions.
Option 2: Polling (Simple Use Cases)
Best for:
Simple integrations
Single job processing
Quick image generation
Polling Intervals:
Images: Check every 2-3 seconds (typically complete in 30-60 seconds)
Videos: Check every 5-10 seconds (typically complete in 2-5 minutes)
Polling Example (Python SDK)
import time from magic_hour import Client client = Client(token="YOUR_API_KEY") # Create job job = client.v1.ai_image_generator.create( image_count=1, style={"prompt": "Epic wizard"} ) # Poll for completion while True: status = client.v1.image_projects.get(id=job.id) if status.status == "complete": print(f"β
Done! Downloads: {status.downloads}") break elif status.status == "error": print(f"β Error: {status.error}") break else: print(f"Status: {status.status}") time.sleep(3) Downloading Results
When a job completes, you receive a time-limited download URL valid for 24 hours:
{ "status": "complete", "downloads": [ { "url": "https://video.magichour.ai/id/output.mp4?auth-token=abc123", "expires_at": "2024-10-19T05:16:19.027Z" } ] } Download URLs expire after 24 hours. Always download files immediately after job completion.
Download Example (Python)
import requests from pathlib import Path def download_result(download_url, output_path="result.mp4"): response = requests.get(download_url, stream=True, timeout=60) response.raise_for_status() with open(output_path, "wb") as f: for chunk in response.iter_content(chunk_size=8192): if chunk: f.write(chunk) file_size = Path(output_path).stat().st_size print(f"β
Downloaded: {output_path} ({file_size} bytes)") # Usage download_result("https://video.magichour.ai/id/output.mp4?auth-token=abc123") Error Handling
When a job fails, the response includes detailed error information:
{ "status": "error", "error": { "code": "no_source_face", "message": "Please use an image with a detectable face" } } Common Error Codes:
no_source_faceβ No face detected in the input image. Use a clear face photo.invalid_file_formatβ File format not supported. Check supported formats above.file_too_largeβ File exceeds size limits. Videos max 100MB (free tier) or 3GB (Business tier).content_moderation_failedβ Content violates moderation policy. Adjust your prompt.unknown_errorβ Unexpected error. Contact [email protected] with your project ID.
Error Handling Example (Python SDK)
import time from magic_hour import Client client = Client(token="YOUR_API_KEY") try: job = client.v1.face_swap.create( assets={ "image_file_path": "https://example.com/face.jpg", "video_file_path": "https://example.com/video.mp4" } ) while True: status = client.v1.video_projects.get(id=job.id) if status.status == "complete": print("β
Job complete") break elif status.status == "error": error_code = status.error.get("code", "unknown") error_msg = status.error.get("message", "Unknown error") if error_code == "no_source_face": print("β No face detected. Use a different image.") else: print(f"β Error ({error_code}): {error_msg}") break time.sleep(5) except Exception as e: print(f"β Request failed: {e}") Available Tools
Video Tools
Text-to-Video β Generate videos from text prompts
Image-to-Video β Animate static images into videos
Video-to-Video β Transform existing videos with style changes
Face Swap (Video) β Replace faces in videos
Lip Sync β Synchronize lip movements to audio
Talking Photo β Animate portraits to speak
Animation β Create audio-reactive animations
Auto Subtitle Generator β Generate and embed subtitles
Image Tools
AI Images β Generate images from text prompts
Face Swap (Photo) β Replace faces in images
AI Headshots β Generate professional headshot portraits
AI Image Editor β Edit images with AI assistance
AI Image Upscaler β Increase image resolution up to 4K
AI Clothes Changer β Change clothing in photos
AI Face Editor β Modify facial features
Photo Colorizer β Restore color to black & white photos
Image Background Remover β Remove or change backgrounds
AI GIFs β Generate animated GIFs
AI QR Code β Create artistic QR codes
AI Meme Generator β Create memes from images
Audio Tools
AI Voice Generator β Generate speech from text
For detailed parameters and response formats for each tool, see the complete API Reference.
Billing and Credits
Credit System
All generations consume credits based on the tool and output specifications. For example:
1 image generation = ~1 credit
1 second of video = variable (higher for 4K)
Check your remaining credits in the Magic Hour dashboard or programmatically via the API.
Pricing Options
Subscriptions: Fixed monthly costs with locked-in credit amounts
Creator: $10/mo
Pro: $49/mo
Business: $249/mo
Yearly discount: 2 months free
Usage-Based Pricing: Pay only for what you use with automatic volume discounts
No monthly fee
Save up to 50% as usage scales
Perfect for variable workloads
For high-volume enterprise needs, contact [email protected] for custom pricing.
Development and Testing
Mock Server for Free Testing
Avoid credit charges during development using the mock API server:
from magic_hour import Client from magic_hour.environment import Environment # Development/testing (no credits charged) client = Client( token="YOUR_API_KEY", environment=Environment.MOCK_SERVER ) # All calls return realistic mock data result = client.v1.face_swap.create(...)
Job Cancellation
You can cancel video jobs from the web dashboard with full credit refund:
Visit your library:
https://magichour.ai/my-library?videoId={project_id}Click the video to open details
Click Cancel Render
Confirm cancellation
Image jobs cannot be cancelled (they complete too quickly). Only video jobs support cancellation with full credit refund.
File Management
Cleaning Up Storage
Delete completed jobs to manage storage:
from magic_hour import Client client = Client(token="YOUR_API_KEY") # Delete a video project client.v1.video_projects.delete(id="project_id") # Delete an image project client.v1.image_projects.delete(id="project_id")
Deletion is permanent and cannot be undone. Only delete after confirming successful download of your files.
SDKs and Languages
Magic Hour provides official SDKs to simplify integration:
Python β
pip install magic_hourNode.js β
npm install magic-hour-sdkGo β Official SDK available
Rust β Official SDK available
For HTTP/REST API calls without SDKs, use cURL or your preferred HTTP library.
Common Integration Patterns
Batch Processing (Bulk Face Swaps)
Process multiple files by looping through API calls:
from magic_hour import Client client = Client(token="YOUR_API_KEY") face_url = "https://example.com/face.jpg" video_urls = [ "https://example.com/video1.mp4", "https://example.com/video2.mp4", "https://example.com/video3.mp4" ] jobs = [] for video_url in video_urls: job = client.v1.face_swap.create( assets={ "image_file_path": face_url, "video_file_path": video_url } ) jobs.append(job) print(f"Started batch job: {job.id}") You can submit unlimited concurrent generation jobs. The queue will process them based on available server capacity.
Serverless / Webhook-Driven Workflow
For scalable production apps, use webhooks to avoid polling:
Submit a generation request
Store the job ID in your database
Magic Hour POSTs to your webhook endpoint when complete
Download and process the result in your webhook handler
See Webhook Reference for complete setup.
Troubleshooting
Authentication Issues
Problem: 401 Unauthorized
Solution:
Verify API key is valid (check Developer Hub)
Ensure Authorization header format:
Bearer YOUR_API_KEYNever use API key as a query parameter
Check that API key hasn't been revoked
Credit Exhaustion
Problem: API returns "Insufficient credits" error
Solution:
Check remaining credits in dashboard
Purchase additional credits or upgrade your plan
For free tier, upgrade to Creator plan or use usage-based pricing
File Upload Failures
Problem: "Invalid file format" or upload timeout
Solution:
Verify file format is supported (see formats above)
Check file size is within tier limit (100MB free, 3GB Business)
Ensure file is publicly accessible (for URL-based uploads)
Try uploading to Magic Hour storage instead of URL references
Generation Failures
Problem: Job returns error status with specific error code
Solution:
Review error code in response (see Error Handling section)
For
no_source_face: use a clearer face imageFor
content_moderation: adjust prompt to comply with policyFor
unknown_error: contact [email protected] with project ID
What's Next
Read the full API Reference: Complete endpoint documentation
Set up webhooks: Webhook integration guide
Join the community: Magic Hour Discord
Check the changelog: Recent API updates and features
Explore tool specifics: Video tools documentation and Image tools documentation
Getting Help
For technical support: Email [email protected] with:
Your project ID
API endpoint you were calling
Request/response payloads
Timestamp of the error
Steps to reproduce
For sales and enterprise: Email [email protected]
For general questions: Join our Discord community
