Webhooks let you receive real-time notifications when your API requests complete, eliminating the need for polling. Instead of repeatedly checking job status, Magic Hour automatically notifies your application when jobs finish.Benefits:
First, create a simple webhook handler that can receive and process events.
Using Jupyter/Colab? See the “Colab/Jupyter” tab below for notebook-compatible code, or use
webhook.site for instant testing without any code.
from fastapi import FastAPI, Requestimport jsonapp = FastAPI()@app.post("/webhook")async def webhook_handler(request: Request): # Get the event data event = await request.json() # Log the event for testing print(f"Received event: {event['type']}") print(f"Payload: {json.dumps(event['payload'], indent=2)}") # Handle different event types match event['type']: case 'video.started': print('🎬 Video processing started') case 'video.completed': print('✅ Video processing completed') # Download URL available in event['payload']['downloads'] case 'video.errored': print('❌ Video processing failed') case 'image.completed': print('🖼️ Image processing completed') case 'image.errored': print('❌ Image processing failed') # Always return success return {"success": True}if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
const express = require("express");const app = express();app.use(express.json());app.post("/webhook", (req, res) => { const { type, payload } = req.body; // Log the event for testing console.log(`Received event: ${type}`); console.log(`Payload:`, JSON.stringify(payload, null, 2)); // Handle different event types switch (type) { case "video.started": console.log("🎬 Video processing started"); break; case "video.completed": console.log("✅ Video processing completed"); // Download URL available in payload.downloads break; case "video.errored": console.log("❌ Video processing failed"); break; case "image.completed": console.log("🖼️ Image processing completed"); break; case "image.errored": console.log("❌ Image processing failed"); break; } // Always return success res.status(200).json({ success: true });});const port = 8000;app.listen(port, () => { console.log(`🚀 Webhook server running on http://localhost:${port}`);});
# Notebook-friendly webhook serverfrom fastapi import FastAPI, Requestimport jsonimport nest_asyncioimport threadingimport uvicornimport time# Install required packages first:# !pip install fastapi uvicorn nest-asyncio pyngrok# Allow nested event loops (required for notebooks)nest_asyncio.apply()app = FastAPI()@app.post("/webhook")async def webhook_handler(request: Request): # Get the event data event = await request.json() # Log the event for testing print(f"Received event: {event['type']}") print(f"Payload: {json.dumps(event['payload'], indent=2)}") # Handle different event types match event['type']: case 'video.completed': print('✅ Video processing completed') case 'image.completed': print('🖼️ Image processing completed') case _: print(f'Event: {event["type"]}') return {"success": True}# Notebook-friendly server startupdef run_server(): uvicorn.run(app, host="0.0.0.0", port=8000, log_level="info")# Start server in background threadserver_thread = threading.Thread(target=run_server, daemon=True)server_thread.start()# Wait for server to starttime.sleep(2)print("🚀 Webhook server running on http://localhost:8000")# For Colab: Use ngrok to make it publictry: from pyngrok import ngrok public_url = ngrok.connect(8000) print(f"📡 Public URL: {public_url}") print(f"Use this URL in Magic Hour: {public_url}/webhook")except ImportError: print("💡 Install pyngrok for public URL: !pip install pyngrok") print("Or use webhook.site for easier testing")
Now let’s verify everything works by making a real API call and watching for the webhook.
1
Start monitoring your webhook
If using your own server: Watch the console logs
# Your server should show:🚀 Webhook server running on http://localhost:8000
If using Colab/Jupyter: Watch the cell output for webhook eventsIf using webhook.site: Keep the browser tab open to see incoming requests in real-time
2
Make a test API call
Create a simple image to trigger webhook events:
from magic_hour import Clientclient = Client(token="your-api-key")# Create a simple AI image - this will trigger webhooksresult = client.v1.ai_image_generator.generate( image_count=1, orientation="square", style={"prompt": "A cute cat wearing sunglasses", "tool": "ai-anime-generator"})print(f"Job created! ID: {result.id}")print("Watch your webhook endpoint for events...")# In Colab, you'll see the webhook events appear in the cell output above
# If using webhook.site, you don't need a server# Just make the API call and watch the webhook.site browser tabfrom magic_hour import Clientclient = Client(token="your-api-key")result = client.v1.ai_image_generator.generate( image_count=1, orientation="square", style={"prompt": "A cute cat wearing sunglasses", "tool": "ai-anime-generator"})print(f"Job created! ID: {result.id}")print("Check your webhook.site browser tab for the webhook delivery!")
3
Verify webhook delivery
Within seconds, you should see webhook events in your console or webhook.site: