Webhooks
Real-time notifications for lead magnet events and status updates
Overview
Webhooks allow your application to receive real-time notifications when events occur in Magnetite. Instead of polling our API for updates, we'll send HTTP POST requests to your specified endpoint whenever important events happen, such as lead magnet generation completion or failures.
Configure Webhooks
Webhook Secret
whsec_
).This secret is only shown once during webhook creation - make sure to copy and store it securely as you'll need it to verify webhook signatures.Event Types
Magnetite supports the following webhook events:
Sent immediately when a new lead magnet generation request is received and queued for processing.
Fired when the research agent starts gathering data for lead personalization.
Sent when research data collection is complete and content generation is about to begin.
Triggered when the research phase fails due to tool errors, API limits, or other issues.
Sent when the AI has successfully generated the personalized lead magnet content.
Final event when the lead magnet is completely processed and available for viewing.
Triggered when lead magnet generation fails permanently after all retry attempts.
Sent when a recipient opens and views the generated lead magnet.
Security & Verification
All webhook requests are signed using HMAC-SHA256 to ensure they're from Magnetite. The signature is included in the X-Magnetite-Signature
header. You'll need the webhook secret (provided when you created the webhook) to verify these signatures.
Verifying Webhook Signatures
Node.js (Express)
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
const receivedSignature = signature.replace('sha256=', '');
return crypto.timingSafeEqual(
Buffer.from(expectedSignature, 'hex'),
Buffer.from(receivedSignature, 'hex')
);
}
// In your webhook handler
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-magnetite-signature'];
const payload = req.body;
const secret = process.env.WEBHOOK_SECRET;
if (!verifyWebhookSignature(payload, signature, secret)) {
return res.status(401).send('Unauthorized');
}
// Process the webhook
const event = JSON.parse(payload);
console.log('Received event:', event.event);
res.status(200).send('OK');
});
Python (Flask)
import hmac
import hashlib
from flask import Flask, request, abort
def verify_webhook_signature(payload, signature, secret):
expected_signature = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
received_signature = signature.replace('sha256=', '')
return hmac.compare_digest(expected_signature, received_signature)
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-Magnetite-Signature')
payload = request.get_data()
secret = os.environ['WEBHOOK_SECRET']
if not verify_webhook_signature(payload, signature, secret):
abort(401)
# Process the webhook
event = request.get_json()
print(f"Received event: {event['event']}")
return 'OK', 200
Webhook Headers
Every webhook request includes these headers:
Content-Type
application/jsonUser-Agent
Magnetite-Webhooks/1.0X-Magnetite-Signature
sha256=[signature]X-Magnetite-Event
Event type (e.g., lead.completed)X-Magnetite-Timestamp
Unix timestamp when event occurredPayload Structure
All webhook payloads follow this consistent structure:
{
"event": "lead.completed",
"timestamp": 1703123456789,
"organization_id": "org_123abc",
"project_id": "proj_456def",
"lead_id": "lead_789ghi",
"data": {
// Event-specific data
}
}
Event-Specific Data Examples
lead.created
{
"event": "lead.created",
"timestamp": 1703123456789,
"organization_id": "org_123abc",
"project_id": "proj_456def",
"lead_id": "lead_789ghi",
"data": {
"lead_id": "lead_789ghi",
"input_data": {
"fullName": "John Smith",
"company": "Acme Corp",
"email": "john@acme.com"
},
"status": "processing",
"created_at": 1703123456789
}
}
lead.completed
{
"event": "lead.completed",
"timestamp": 1703123756789,
"organization_id": "org_123abc",
"project_id": "proj_456def",
"lead_id": "lead_789ghi",
"data": {
"lead_id": "lead_789ghi",
"status": "completed",
"research_results": {
"company_info": "...",
"industry_insights": "..."
},
"generated_content": {
"contentLength": 4521
},
"completed_at": 1703123756789
}
}
magnet.viewed
{
"event": "magnet.viewed",
"timestamp": 1703124056789,
"organization_id": "org_123abc",
"project_id": "proj_456def",
"lead_id": "lead_789ghi",
"data": {
"lead_id": "lead_789ghi",
"viewer_ip": "203.0.113.42",
"user_agent": "Mozilla/5.0...",
"viewed_at": 1703124056789
}
}
Retry Behavior
Magnetite implements exponential backoff retry logic for failed webhook deliveries:
Success Criteria
Best Practices
Respond Quickly
Return a 200 status code as soon as possible. Process webhook data asynchronously if needed.
Verify Signatures
Always verify the HMAC signature to ensure requests are from Magnetite.
Handle Duplicates
Use the event timestamp and lead_id to detect and ignore duplicate deliveries.
Log Events
Keep detailed logs of webhook deliveries for debugging and monitoring.
Testing Webhooks
Use these tools and techniques to test your webhook implementation:
1. Local Development with ngrok
# Install ngrok
npm install -g ngrok
# Expose your local server
ngrok http 3000
# Use the https URL as your webhook endpoint
# https://abc123.ngrok.io/webhook
2. Webhook Testing Services
- webhook.site - Instant webhook URLs for testing
- RequestCatcher - Capture and inspect HTTP requests
- smee.io - Forward webhooks to localhost
3. Manual Testing
Trigger webhooks by generating test lead magnets in your dashboard.
Troubleshooting
Common Issues
Webhook timeouts
Ensure your endpoint responds within 30 seconds. Move heavy processing to background jobs.
SSL certificate errors
Your webhook endpoint must use a valid SSL certificate. Self-signed certificates are not supported.
Missing events
Check your event subscriptions in the webhook configuration. Enable specific events you want to receive.
Need Help?
If you're having trouble with webhooks, check our troubleshooting guide or contact support.