Webhooks
Receive matches as JSON on your own endpoint, and verify they came from BuzzGlean.
A webhook channel sends every alert batch to your HTTPS endpoint as a JSON POST. Use it to push matches into a CRM, a help desk, a spreadsheet automation (Zapier, Make, n8n) or your own service.
Create one in the app under Notifications → New channel → Webhook, or with the REST API.
Request
- URL: a public HTTPS endpoint. Localhost, private IP ranges and cloud metadata addresses are rejected; use a tunnel such as ngrok to test locally.
- Method:
POST - Content type:
application/json - Timeout: your endpoint must respond within 5 seconds with a
2xxstatus. Do slow work asynchronously after responding. - Signature:
X-App-Signatureheader, when the channel has a signing secret (see below).
Payload
{
"type": "buzz.alert_batch",
"sent_at": "2026-10-29T09:14:03.120Z",
"channel_id": "5f0c1c8e-7c1a-4d0f-9a43-2f1d6c3e9b10",
"settings": {},
"batchId": "b_8c2f",
"alertRuleId": "r_41aa",
"ruleName": "CRM shoppers",
"ruleContent": "People looking for a simple, affordable CRM, or unhappy with their current one.",
"ruleKeywords": ["CRM", "switching"],
"posts": [
{
"id": "post_01",
"post_id": "733291000000001",
"group_id": "smallbusiness",
"source": "reddit",
"source_type": "subreddit",
"source_id": "smallbusiness",
"page_name": "r/smallbusiness",
"author_name": "Minh Nguyen",
"title": null,
"rating": null,
"content": "We're a 3-person team and our current CRM just doubled its price. Any CRM that's simple and doesn't cost a fortune?",
"url": "https://reddit.com/r/smallbusiness/comments/example1",
"created_at": "2026-10-29T09:02:11.000Z",
"ai_score": 0.94,
"ai_reason": "Asking for a CRM recommendation",
"tags": ["recommendation_request", "buy_intent"],
"sentiment": "neutral",
"matched_keywords": ["CRM"],
"detail_url": "https://buzzglean.com/app/posts/post_01"
},
{
"id": "post_02",
"post_id": "trustpilot.com:6720f1c2a9b3e4d5f6a7b8c9",
"group_id": "w_3f9a1c2b7d4e8f60",
"source": "trustpilot",
"source_type": "page",
"source_id": "w_3f9a1c2b7d4e8f60",
"page_name": "Example CRM reviews",
"author_name": "Laura K.",
"title": "Support never got back to me",
"rating": 2,
"content": "Import failed twice and I've been waiting four days for an answer from support. Thinking about switching.",
"url": "https://www.trustpilot.com/reviews/6720f1c2a9b3e4d5f6a7b8c9",
"created_at": "2026-10-29T08:47:30.000Z",
"ai_score": 0.88,
"ai_reason": "Unhappy customer considering switching",
"tags": ["complaint", "alternative_seeking"],
"sentiment": "negative",
"matched_keywords": ["switching"],
"detail_url": "https://buzzglean.com/app/posts/post_02"
}
]
}| Field | Description |
|---|---|
type | Always buzz.alert_batch for alerts. |
sent_at | When this request was sent (ISO 8601). |
channel_id | The webhook channel that sent it. |
settings | The channel's non-secret settings (usually empty). |
batchId | Unique id of this batch. Use it to de-duplicate retries. |
alertRuleId | The rule that produced the matches. |
ruleName | The rule's name. |
ruleContent | The rule's description (what AI looks for). |
ruleKeywords | The rule's keywords ([] when it has none). |
posts[] | The matched posts. |
posts[].source | The platform: facebook, reddit, a site id (trustpilot, g2, capterra, apple_app_store, google_play) or web for any other site. |
posts[].source_type | group (Facebook group), subreddit, or page (review site, app store or web page). |
posts[].source_id | Id of the source: the Facebook group id, the subreddit name, or a page id like w_3f9a… for other pages. |
posts[].group_id | Same as source_id; kept for compatibility. |
posts[].page_name | The source's name as shown in the app. |
posts[].title | The review or post title, when the site has one. |
posts[].rating | The star rating for reviews (for example 1-5), otherwise null. |
posts[].url | Link to the original post. |
posts[].ai_score | Relevance from 0 to 1. |
posts[].ai_reason | Why AI matched the post. |
posts[].tags | Tag keys assigned by AI (see taxonomy). |
posts[].sentiment | positive, neutral or negative; null when the rule has sentiment analysis turned off. |
posts[].matched_keywords | The rule's keywords found in the post. Older matches without this information get the rule's keywords. |
posts[].detail_url | The match in the BuzzGlean app. |
Fields that aren't known for a post are null or omitted. Facebook posts may also include fb_group_id and fb_post_id. For review sites and app stores, post_id is prefixed with the site's domain.
Verify signatures
When a webhook channel has a signing secret, each request carries:
X-App-Signature: sha256=<hex HMAC-SHA256 of the raw request body>Compute the HMAC over the raw body bytes (before parsing JSON) with your secret and compare in constant time.
Set the secret in the channel form (Signing secret → Generate, then copy it before saving), or with webhook_secret in the REST API. The secret is write-only: BuzzGlean never shows it again, so store it in your endpoint's configuration. Channels without a secret send unsigned requests.
import { createHmac, timingSafeEqual } from "node:crypto"
export function isValidSignature(rawBody: string, header: string | null, secret: string) {
if (!header) return false
const expected = `sha256=${createHmac("sha256", secret).update(rawBody).digest("hex")}`
const a = Buffer.from(expected)
const b = Buffer.from(header)
return a.length === b.length && timingSafeEqual(a, b)
}Test your endpoint
From the channel's actions menu, choose Send test alert, or call POST /channels/{id}/test with the API. BuzzGlean sends a sample batch to your endpoint; a 2xx response marks the channel as verified.
Best practices
- Respond fast: return
200immediately, then process the batch in the background. - De-duplicate: a batch may be delivered more than once; use
batchIdandposts[].idto ignore repeats. - Use HTTPS and verify the signature before trusting the body.
Tags and sentiment
| Type | Label | API value |
|---|---|---|
| Sentiment | Positive | positive |
| Sentiment | Neutral | neutral |
| Sentiment | Negative | negative |
| Tag | Buy intent | buy_intent |
| Tag | Asking for recommendations | recommendation_request |
| Tag | Looking for alternatives | alternative_seeking |
| Tag | Complaint | complaint |
| Tag | Praise | praise |
| Tag | Question | question |
| Tag | Feedback | feedback |
| Tag | Other | other |