Daily brand monitor
Schedule a daily brand-rank check across all AI search surfaces. The webhook fires only when something changes — mention added, removed, rank shifted, or citation graph drifted — so you don't drown in noise.
Why it matters
Brand presence in AI answers shifts week-to-week as platforms re-index, model versions roll, and content updates. Polling once a day at 50¢/call (mode:all_live) across 6 surfaces gives you a daily delta on the cheapest possible cadence — a daily all_live watch costs you $15/month per query.
Create the watch
bash
curl https://api.mentionsapi.com/v1/watch \
-H "Authorization: Bearer lvk_live_..." \
-H "Content-Type: application/json" \
-d '{
"query": "best CRM for small business",
"brand": "HubSpot",
"mode": "all_live",
"interval": "daily",
"webhook_url": "https://your-app.com/api/mentions-webhook",
"webhook_secret": "whsec_at_least_16_chars",
"trigger_on": ["mention_added","mention_removed","rank_changed","citation_changed"]
}'Verify the webhook (Node)
MentionsAPI signs every webhook with HMAC-SHA256 of the raw body using your webhook_secret. Verify before processing.
javascript
// Verify HMAC + parse the diff in your webhook handler.
import crypto from "node:crypto";
import { createHmac, timingSafeEqual } from "node:crypto";
export default async function handler(req: Request) {
const sig = req.headers.get("x-mentionsapi-signature") ?? "";
const body = await req.text();
const computed = createHmac("sha256", process.env.MENTIONS_WEBHOOK_SECRET!)
.update(body)
.digest("hex");
if (!timingSafeEqual(Buffer.from(sig), Buffer.from(computed))) {
return new Response("bad signature", { status: 401 });
}
const { triggers_fired, watch_id, results } = JSON.parse(body);
if (triggers_fired.includes("rank_changed")) {
await postToSlack(`Brand rank changed on ${watch_id}: ${JSON.stringify(results)}`);
}
return new Response("ok");
}Trigger semantics
mention_added— your brand appeared on a surface where it wasn't before.mention_removed— your brand dropped off a surface that previously cited it.rank_changed— your rank moved on at least one surface (delta ≥ 1).citation_changed— the citation graph URLs changed on at least one surface.
See /docs/api/watch for the full webhook payload shape and retry semantics.