Recipes

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.