Skip to main content
By the end of this guide, you’ll have:
  • ✅ Created a webhook endpoint in your application
  • ✅ Registered it with Magic Hour
  • ✅ Tested it with a real API call
  • ✅ Verified webhook delivery works

How Webhooks Work

Webhooks let you receive real-time notifications when your API requests complete, instead of polling for status updates.

Step 1: Create Your Webhook Endpoint

First, let’s create a simple webhook handler that can receive and process events.
Using Jupyter/Colab? The server examples below are for standalone deployment. For notebook testing:
  1. Use webhook.site for instant webhook testing (no code needed). See the “webhook.site” tab in Step 2
  2. Or use the notebook-friendly code in the “Colab/Jupyter” tab below
from fastapi import FastAPI, Request
import json

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.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)

Step 2: Make Your Endpoint Publicly Accessible

Your webhook endpoint needs to be accessible from the internet. For testing, use one of these options:

Step 3: Register Your Webhook

1

Visit Developer Hub

Go to Magic Hour Developer Hub, and click Create WebhookWebhook Table
2

Configure webhook

Enter your webhook details:
  • Endpoint URL: Your public HTTPS URL (e.g., https://abc123.ngrok.io/webhook)
  • Events: Select the events you want to receive:
    • video.started - When video processing begins
    • video.completed - When video is ready for download
    • video.errored - When video processing fails
    • image.started - When image processing begins
    • image.completed - When image is ready for download
    • image.errored - When image processing fails
    • audio.started - When audio processing begins
    • audio.completed - When audio is ready for download
    • audio.errored - When audio processing fails Create webhook modal
Click Create Webhook
3

Save webhook secret

Important: Copy and save the webhook secret - you’ll need this for security verification.Webhook Secret
Store this secret securely! It’s used to verify that webhooks are actually from Magic Hour.

Step 4: Test Your Webhook End-to-End

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:
import magic_hour

client = magic_hour.Client(api_key="your-api-key")

# Create a simple AI image - this will trigger webhooks
result = client.v1.ai_image_generator.generate(
    prompt="A cute cat wearing sunglasses",
    width=512,
    height=512
)

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
3

Verify webhook delivery

Within seconds, you should see webhook events in your console:
Received event: image.completed
🖼️ Image processing completed
Payload: {
  "id": "clx7uu86w0a5qp55yxz315r6r",
  "status": "complete",
  "downloads": [
    {
      "url": "https://images.magichour.ai/id/output.png",
      "expires_at": "2024-10-19T05:16:19.027Z"
    }
  ]
}
Success! 🎉 Your webhook is working end-to-end.

Step 5: Download Your Result

Your webhook received the download URL. Let’s grab the generated image:
import requests

# Extract download URL from webhook payload
download_url = "https://images.magichour.ai/id/output.png"

# Download the image
response = requests.get(download_url)
with open("generated_image.png", "wb") as f:
    f.write(response.content)

print("✅ Image downloaded as generated_image.png")

🎉 Congratulations!

You’ve successfully:
  • ✅ Created a webhook endpoint
  • ✅ Registered it with Magic Hour
  • ✅ Tested it with a real API call
  • ✅ Received webhook notifications
  • ✅ Downloaded the generated content

Next Steps

Troubleshooting

Webhook not receiving events?
  • ✅ Check your endpoint URL is publicly accessible
  • ✅ Ensure your server returns HTTP 2xx status codes
  • ✅ Verify the webhook is enabled in Developer Hub
  • ✅ Check server logs for errors
Colab/Jupyter specific issues:
  • ✅ Install required packages: !pip install fastapi uvicorn nest-asyncio pyngrok
  • ✅ Make sure the server thread started successfully
  • ✅ Check if ngrok tunnel is active and accessible
  • ✅ Try webhook.site as an alternative for quick testing
AsyncIO errors in notebooks?
  • ✅ Make sure you’re using the Colab/Jupyter code version with nest_asyncio.apply()
  • ✅ Don’t run uvicorn.run() directly in notebooks - use the threading approach shown above
Need help? Contact support at [email protected]