Misar Webhooks
Receive real-time event notifications via HTTP callbacks when things happen across Misar products. No polling required.
Quick Start
Register a webhook endpoint in your product dashboard and start receiving events in minutes.
Register your endpoint
Go to your product dashboard → Settings → Webhooks and add your HTTPS endpoint.
# Or register via API
curl -X POST https://api.misar.io/mail/v1/webhooks \
-H "Authorization: Bearer msk_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/misar",
"events": ["email.delivered", "email.bounced"]
}'Handle the incoming request
// app/api/webhooks/misar/route.ts (Next.js)
import { NextRequest, NextResponse } from "next/server";
import crypto from "node:crypto";
export async function POST(req: NextRequest) {
const body = await req.text();
const sig = req.headers.get("x-misar-signature") ?? "";
const mac = crypto
.createHmac("sha256", process.env.MISAR_WEBHOOK_SECRET!)
.update(body)
.digest("hex");
if (`sha256=${mac}` !== sig) {
return NextResponse.json({ error: "Invalid signature" }, { status: 401 });
}
const event = JSON.parse(body);
switch (event.type) {
case "email.delivered":
await markEmailDelivered(event.data.id);
break;
case "email.bounced":
await handleBounce(event.data);
break;
}
return NextResponse.json({ received: true });
}Payload Schema
All Misar webhooks share a consistent envelope. The data field is event-specific.
Envelope
{
"id": "evt_01j9xyz...",
"type": "email.delivered",
"product": "mail",
"timestamp": "2025-01-01T00:00:00Z",
"api_version": "v1",
"data": {
"id": "msg_01j9abc...",
"to": "[email protected]",
"subject": "Welcome!",
"delivered_at": "2025-01-01T00:00:01Z"
}
}HTTP Headers
POST /webhooks/misar HTTP/1.1 Host: your-app.com Content-Type: application/json X-Misar-Signature: sha256=<hmac> X-Misar-Event: email.delivered X-Misar-Delivery: evt_01j9xyz... User-Agent: Misar-Webhook/1.0
TypeScript Types
interface MisarWebhookEvent<T = unknown> {
id: string; // evt_...
type: string; // "email.delivered" etc
product: string; // "mail" | "blog" | "reach" | "social" | "dev"
timestamp: string; // ISO 8601
api_version: string; // "v1"
data: T;
}
// Type-safe handler
function handleEvent(event: MisarWebhookEvent) {
if (event.type === "email.delivered") {
const data = event.data as EmailDeliveredData;
// ...
}
}Signature Verification
Every request is signed with HMAC-SHA256 using your webhook secret. Always verify before processing.
TypeScript / Node.js
import crypto from "node:crypto";
function verify(
body: string,
sig: string,
secret: string
): boolean {
const mac = crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
return `sha256=${mac}` === sig;
}Python
import hmac, hashlib
def verify(body: str, sig: str,
secret: str) -> bool:
mac = hmac.new(
secret.encode(),
body.encode(),
hashlib.sha256
).hexdigest()
return f"sha256={mac}" == sigGo
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
)
func verify(body, sig,
secret string) bool {
mac := hmac.New(
sha256.New,
[]byte(secret),
)
mac.Write([]byte(body))
exp := fmt.Sprintf(
"sha256=%x",
mac.Sum(nil),
)
return hmac.Equal(
[]byte(exp),
[]byte(sig),
)
}Events by Product
Subscribe to specific event types per product.
MisarMail
email.deliveredemail.bouncedemail.openedemail.clickedemail.unsubscribedcampaign.completed
Misar.Blog
article.publishedarticle.updatedarticle.deletedcomment.created
MisarReach
lead.foundcampaign.sentdeal.updatedcontact.replied
Misar.Dev
plugin.installedplugin.updatedplugin.uninstalledagent.run.completedagent.run.failed
MisarPost
post.publishedpost.scheduledpost.failedcampaign.completed
Misar.Ink
Misar.ai
project.createddeploy.succeededdeploy.failed
Best Practices
Respond quickly
Return a 2xx status within 10 seconds. If processing takes longer, acknowledge the event immediately and handle it asynchronously via a queue.
Handle retries idempotently
Misar retries failed deliveries with exponential backoff (up to 72 hours). Use the event `id` field as an idempotency key to avoid double-processing.
Always verify signatures
Never process a webhook payload without verifying the HMAC-SHA256 signature. Reject requests with invalid or missing signatures with 401.
Monitor failures
Check your webhook delivery logs in the dashboard. Endpoints that return 5xx for 3 consecutive days will be automatically disabled.
Ready to integrate webhooks?
Register your endpoint from the product dashboard or contact us for help setting up your integration.