Blog

Social listening webhooks: real-time mentions, comments, DMs, and reviews

Erwan Prost

Erwan Prost

· 12 min read · Updated

Social listening webhooks are HTTPS POST callbacks that fire the moment a new mention, comment, DM, or review hits one of your connected social accounts. Instead of polling Instagram, Facebook, TikTok, LinkedIn, Google Business Profile, or YouTube every few minutes to check for new engagement, your server gets a signed JSON payload pushed to it in near real-time. With SocialAPI.ai you register one HTTPS endpoint, subscribe to the six event types (comment.received, dm.received, dm.sent, dm.referral, review.received, mention.received), verify the HMAC-SHA256 signature on each request, respond with a 2xx within 10 seconds, and you have a working social listening pipeline across every platform you have connected.

What are social listening webhooks?

A social listening webhook is a server-to-server HTTP callback your application registers with a social media API. When something happens on a connected account (someone comments on your post, sends a DM, leaves a Google review, mentions your handle on Threads or X), the API immediately POSTs a JSON payload describing the event to your endpoint. The webhook is the inverse of polling: the API tells you when there is something new, instead of your code asking on a schedule.

The job webhooks solve is response time. In 2025, the Sprout Social Index found that 73 percent of consumers will buy from a competitor if a brand does not respond on social, and nearly three-quarters expect a response within 24 hours (Sprout Social Index 2025). Hitting those SLAs by polling means querying every connected account every minute or two, which burns through platform rate limits fast and still leaves a 1-2 minute floor on detection latency. A webhook reduces that floor to seconds.

There is a second job: cost. Polling N accounts every M minutes is N/M API calls per minute whether or not anything happened. Webhooks are zero-cost when nothing is happening, and proportional to actual engagement when it is. For most B2B brands and indie products, the inbox is quiet 95% of the time, which is exactly when polling is most wasteful.

Polling vs webhooks: when each one wins

DimensionPollingWebhooks
Detection latency1-15 minutes (depends on poll interval)Seconds
API calls when idleConstant (every interval)Zero
Rate limit pressureHigh, scales with account countLow, scales with actual events
InfrastructureCron, queue, state trackingHTTPS endpoint, signature verify, retry handling
Missed eventsPossible if interval too longPossible if endpoint down (mitigated by retries)
Setup complexitySimple in v1, complex at scaleModerate up front, simpler at scale
Right forBackfill, historical sync, low-event accountsReal-time mention tracking, customer support, brand monitoring

The pattern most production systems land on: webhooks for real-time inbound (mentions, comments, DMs, reviews) and scheduled polling for periodic refresh of metrics and historical backfill. SocialAPI.ai supports both. Webhooks push interaction events; periodic syncs refresh post-level metrics like reach, impressions, and saves on a cron.

Which event types should you subscribe to?

SocialAPI.ai exposes six webhook event types. You can subscribe to any subset, but most social listening use cases want all six because that is what gives you a complete view of inbound engagement across platforms.

EventFires whenPlatforms
comment.receivedA new comment arrives on a post on any connected accountInstagram, Facebook, Threads, LinkedIn, YouTube, Google
dm.receivedA new direct message arrives in an inbox you controlInstagram, Facebook, Threads, TikTok
dm.sentEcho confirmation that your account sent a DM (useful for audit trails)Instagram, Facebook
dm.referralA user clicked an ad or CTM/CTD referral link without sending a messageInstagram, Facebook
review.receivedA new review is left on your business profileGoogle Business Profile
mention.receivedYour account is mentioned in a post or comment on a supported platformInstagram, Facebook, Threads, X/Twitter

For brand monitoring and PR work, mention.received and review.received are the two non-negotiable subscriptions. For customer support, dm.received and comment.received. For ad-attribution and conversion tracking on click-to-message campaigns, dm.referral gives you the ad_id and ads_context_data (ad title, photo URL) that ties an incoming conversation back to a specific creative. Subscribe to all six and filter on the consumer side if you are unsure.

How to set up social listening webhooks with SocialAPI.ai

End-to-end setup takes about 15 minutes if your endpoint is already running. Five steps: connect the social accounts you want to listen to, register one HTTPS webhook endpoint with the events you care about, store the returned secret, implement signature verification on your handler, and respond with a 2xx fast.

1. Register the endpoint

Register your endpoint once. The url must be HTTPS (HTTP is rejected with a 400). SocialAPI.ai sends a verification ping immediately after registration; your server must respond with a 2xx or the endpoint is not saved. The secret in the response is shown exactly once. Store it in your environment immediately.

bash
curl -X POST https://api.social-api.ai/v1/webhooks \
  -H "Authorization: Bearer $SOCAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://app.example.com/webhooks/socapi",
    "events": [
      "comment.received",
      "dm.received",
      "dm.sent",
      "dm.referral",
      "review.received",
      "mention.received"
    ]
  }'
json
{
  "id": "wh_01HZ9X3Q4R5M6N7P8V2K0W1J",
  "url": "https://app.example.com/webhooks/socapi",
  "events": ["comment.received", "dm.received", "dm.sent", "dm.referral", "review.received", "mention.received"],
  "secret": "a3f8c2e1b9d4f7a6c5e0b3d2f1a8e7c4b9d6f3a2e5c8b1d4f7a0e3c6b9d2f5a8",
  "message": "Store the secret securely. It will not be shown again."
}

2. Verify the signature on every request

Every webhook POST includes an X-SocialAPI-Signature header containing sha256=<hmac-hex>, computed as HMAC-SHA256 of the raw request body using the endpoint secret as the key. Always use a constant-time comparison (timingSafeEqual, compare_digest, hmac.Equal). A simple string equality check leaks information through timing differences. Reject any request that fails verification with a 401, do not process the payload.

javascript
import crypto from "crypto";
import express from "express";

const app = express();

function verifySignature(secret, rawBody, signatureHeader) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader)
  );
}

app.post(
  "/webhooks/socapi",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const sig = req.headers["x-socialapi-signature"];
    if (!verifySignature(process.env.SOCAPI_WEBHOOK_SECRET, req.body, sig)) {
      return res.status(401).send("Invalid signature");
    }
    res.sendStatus(200);
    const event = JSON.parse(req.body);
    queue.push(event);
  }
);

3. Respond fast, process async

Your endpoint has 10 seconds to return a 2xx. Anything slower is treated as a failed delivery and queues a retry. Anything heavier than "parse + enqueue" should run after you have responded. The pattern in the example above (res.sendStatus(200) before queue.push) is the safe default: acknowledge first, do real work later. This matters because the same event id will arrive again on retry, so your handler also needs to be idempotent.

4. Deduplicate using the interaction id

Every payload includes a stable interaction id of the form sapi_cmt_<hash>, sapi_dm_<hash>, sapi_rev_<hash>, or sapi_mnt_<hash>. The prefix encodes the interaction type so you can dispatch without a database lookup (Interaction IDs guide). Treat this id as the primary key for deduplication. If you have already processed it, return 200 and move on. Retries on a 5-attempt backoff (immediate, ~30s, ~5m, ~30m, ~3h) mean the same event can arrive up to 5 times before SocialAPI.ai gives up.

Retry schedule for failed webhook deliveries (SocialAPI.ai)
Attempt 1 (immediate)Immediate
Attempt 2 (~30s)30s
Attempt 3 (~5m)5m
Attempt 4 (~30m)30m
Attempt 5 (~3h)3h

Each failed delivery is retried up to 5 times with exponential backoff. After attempt 5 the delivery is marked failed and no further retries occur.

5. Monitor deliveries and replay failures

Every delivery is recorded with its HTTP status, response code, and duration. The GET /v1/webhooks/{id}/deliveries endpoint lists recent deliveries filterable by status and event_type. GET /v1/webhooks/{id}/deliveries/{did} returns the full payload and every retry attempt. POST /v1/webhooks/{id}/deliveries/{did}/retry re-enqueues a failed delivery once your endpoint is fixed. POST /v1/webhooks/{id}/test sends a synthetic payload so you can confirm the pipe end-to-end before any real traffic. These four endpoints turn webhook debugging from "guess what went wrong" into a normal logged surface.

Sample payload: dm.received with referral metadata

When a DM originates from an Instagram CTD or Facebook CTM ad click, the interaction includes the referring ad in metadata.referral. This is the field that lets you attribute social conversations back to specific campaigns, which is one of the highest-value applications of social listening webhooks for performance marketers.

json
{
  "event": "dm.received",
  "data": {
    "id": "sapi_dm_aW5zdGFncmFtOm1pZC5yZWYx",
    "type": "dm",
    "platform": "instagram",
    "account_id": "acc_01HZ9X3Q4R5M6N7P8V2K0W1J",
    "author": { "id": "17846744073097661" },
    "content": { "text": "I saw your ad!" },
    "received_at": "2026-03-01T14:30:00Z",
    "metadata": {
      "referral": {
        "ad_id": "120210572164750432",
        "source": "ADS",
        "type": "OPEN_THREAD",
        "ads_context_data": {
          "ad_title": "Spring Sale 25% Off",
          "photo_url": "https://scontent.xx.fbcdn.net/..."
        }
      }
    }
  }
}

The data object is the same Interaction shape returned by GET /accounts/{id}/comments and equivalent inbox endpoints, so you can reuse the same parser for webhook events and on-demand fetches. dm.referral events (a standalone ad click without a message) always include metadata.referral and have empty content.text, which is how you distinguish them from regular DMs that happen to originate from an ad.

Common social listening webhook mistakes

  • Trusting the payload without verifying the signature. Anyone can POST JSON to your URL. The X-SocialAPI-Signature header is what proves it came from SocialAPI.ai. Verify it on every request, with a constant-time compare.
  • Hardcoding the secret or committing it to source control. Store it in an environment variable or a secrets manager. If it leaks, rotate the endpoint and update the secret.
  • Returning a 2xx after heavy processing. If your handler does database writes, calls another API, or triggers an AI model inline, you will hit the 10-second timeout and trigger retries. Return 200 first, do work after.
  • Skipping idempotency. Retries are real. The same interaction id can arrive 2-5 times. Deduplicate by id in your queue or your database.
  • Allowing HTTP endpoints. SocialAPI.ai rejects HTTP URLs at registration with a 400. Use HTTPS with a valid certificate; self-signed certs will fail the verification ping.
  • Ignoring delivery monitoring. When something stops working, the GET /v1/webhooks/{id}/deliveries endpoint tells you exactly when, why, and what the response code was. Build it into your ops dashboard from day one.

Why route social listening through one webhook surface

Every platform ships its own webhook system: Meta has the Graph API webhooks for Instagram, Facebook, and Threads; TikTok has the Business webhook for Messaging API events; LinkedIn has Events API for engagement notifications; Google Business Profile uses Pub/Sub for review notifications; X/Twitter has the Account Activity API. Each one has its own auth, its own payload shape, its own retry policy, its own verification mechanism, and its own approval process. Wiring them up individually is a several-week project per platform and a permanent maintenance load every time one of them changes.

SocialAPI.ai consolidates all of these into one webhook surface with one payload shape, one signature scheme, one retry policy, and one delivery monitoring API. The Interaction object is identical whether the event came from an Instagram comment or a Google review, which means the same handler code processes everything. For teams that want to ship a social listening feature in days rather than months, this is the entire point: one endpoint on top of a unified social inbox API instead of six. For a deeper breakdown of which APIs cover which inbox surfaces, see the unified social media inbox API comparison.

Frequently asked questions

What is a social listening webhook?
A social listening webhook is an HTTPS POST callback from a social media API that fires the moment a new comment, DM, review, or mention arrives on a connected account. It is the opposite of polling: instead of your server asking on a schedule, the API pushes a signed JSON payload to your endpoint within seconds of the event happening. SocialAPI.ai exposes six event types (comment.received, dm.received, dm.sent, dm.referral, review.received, mention.received) and delivers them through a single webhook endpoint that you register once.
How do I get real-time mentions across Instagram, Facebook, and Threads?
Register an HTTPS webhook endpoint on SocialAPI.ai with the mention.received event subscribed, connect the Instagram, Facebook, and Threads accounts you want to listen to, and verify the X-SocialAPI-Signature header on each incoming request. Every mention across all three platforms arrives as the same Interaction shape with platform set to instagram, facebook, or threads. No per-platform webhook setup or Meta App Review is required if you authenticate through SocialAPI.ai's connected accounts.
Are social listening webhooks faster than polling the API?
Yes, by one to two orders of magnitude. Polling gives you 1-15 minute detection latency depending on interval (and burns rate limit budget whether or not anything happened). Webhooks deliver in seconds and only generate work when an event actually fires. The trade-off is that you have to run an always-on HTTPS endpoint and handle retries, signature verification, and idempotency, but those are one-time costs.
How do I verify a SocialAPI.ai webhook signature?
Compute HMAC-SHA256 of the raw request body using your endpoint secret as the key, hex-encode the result, prepend sha256=, and compare it to the X-SocialAPI-Signature header using a constant-time comparison (crypto.timingSafeEqual in Node, hmac.compare_digest in Python, hmac.Equal in Go). Reject any request that fails verification with a 401. Code examples for Node, Python, and Go are in the SocialAPI.ai webhooks guide.
What happens if my webhook endpoint goes down?
Failed deliveries are retried up to 5 times with exponential backoff: immediate, ~30 seconds, ~5 minutes, ~30 minutes, ~3 hours. After the 5th failed attempt the delivery is marked failed and no further retries occur. You can list failed deliveries via GET /v1/webhooks/{id}/deliveries?status=failed and re-enqueue them with POST /v1/webhooks/{id}/deliveries/{did}/retry once your endpoint is fixed.
Can I track which ad a DM came from with social listening webhooks?
Yes. When a DM originates from an Instagram CTD (click-to-DM) or Facebook CTM (click-to-Messenger) ad, the dm.received payload includes metadata.referral with the ad_id, source, type, and ads_context_data (ad title, photo URL). Standalone ad clicks without a message arrive as dm.referral events with empty content. This is how performance marketers attribute social conversations back to specific campaigns in real time.
Is there a free social listening webhook API?
SocialAPI.ai's free tier includes full webhook access along with 2 brands, 10 posts per month, and 50 interactions per month, with no credit card required. That is enough to wire up real-time mention and review tracking for a personal brand or small business. For higher volume, see plans and pricing starting at $109/mo for unlimited interactions across 50 brands.

Ready to replace polling with real-time webhooks? Read the SocialAPI.ai webhooks guide for the full reference, see the unified inbox documentation for the interaction shapes you will receive, or sign up free and register your first endpoint in 5 minutes.

Get started today

Ready to unify your social interactions?

Free tier available · No credit card required · Ships with MCP server