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
A Magic Hour account
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 ($15/mo), Pro ($39/mo), Business ($99/mo), or usage-based pricing
SDKs: Python, Node.js, 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 # Go go get -u github.com/magichourhq/magic-hour-go # Rust cargo add magic_hour
Option B: Direct HTTP Requests
Use cURL or your preferred HTTP library for full control:
curl -X POST https://api.magichour.ai/v1/ai-image-generator \ -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.generate( 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 via
/v1/files/upload-urlsUpload files using the provided URLs (PUT request)
Use the returned
file_pathin your API calls
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:
Code | Cause | Fix |
| No face detected in the input image | Use a clear face photo |
| File format not supported | Check supported formats above |
| File exceeds size limits for your plan | Check your plan's upload limit (200MB Basic, 2GB Creator, 5GB Pro, 10GB Business) |
| Content violates moderation policy | Adjust your prompt |
| 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.generate( 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 (2x = 50 credits, 4x = 200 credits)
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
AI Voice Cloner – Clone a voice and generate speech
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. Credit costs vary by tool — for example:
Background Remover: 5 credits per image
Face Swap Photo / Photo Colorizer / AI Meme Generator: 10 credits per image
AI Clothes Changer: 25 credits per image
AI GIF / AI Headshot Generator: 50 credits per image
AI Image Upscaler: 50 credits (2×) or 200 credits (4×)
Video: 24 credits per second (at base rate on subscription plans)
Voice / Audio: 0.05 credits per character
Check your remaining credits in the Magic Hour dashboard or the Developer Hub.
Pricing Options
Subscriptions: Fixed monthly costs with predictable credit amounts
Plan | Monthly | Annual (33% off) | Credits/month |
Creator | $15/mo | $10/mo | 10,000 |
Pro | $39/mo | $25/mo | 30,000 |
Business | $99/mo | $66/mo | 70,000 |
Credits never expire, even if you cancel your subscription.
Need more credits? Add-on credit packs are available: 1,000 credits for $3.00, with no expiration.
Usage-Based Pricing: Pay only for what you use
No monthly fee — billed automatically at the end of each month
Volume discounts up to 50% as usage scales
Tiers available: Starter ($0.90/1,000 credits), Creator ($1.20), Pro ($1.95), Business ($2.50)
Note: Usage-based billing is not yet self-serve. Contact [email protected] or use the in-app chat to get set up.
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.generate(...)
Job Cancellation
You can cancel video jobs from the web dashboard with a 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:
Language | Install |
Python |
|
Node.js |
|
Go |
|
Rust |
|
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.generate( 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
Authorizationheader 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 or Developer Hub
Purchase additional credit packs ($3.00 per 1,000 credits)
Upgrade to a higher subscription plan for more monthly credits
Set up usage-based billing for variable workloads
File Upload Failures
Problem: "Invalid file format" or upload timeout
Solution:
Verify file format is supported (see formats above)
Check file size is within your plan's limit:
Basic: 200MB
Creator: 2GB
Pro: 5GB
Business: 10GB
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
nsfw: adjust prompt to comply with content 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
Try the API Cookbook: Google Colab with sample code for all 22 APIs
Join the community: Magic Hour Discord
Check the changelog: Recent API updates and features
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 inquiries: [email protected]
For general questions: Join our Discord community
