Community Watch API: X Community activity via webhook, WebSocket and REST

CW has its own REST API and webhook delivery system, separate from the main Xanguard API.

Authentication

All CW API requests require your CW API key (generated via /apikey in the bot). Pass it as a header:

Authorization: Bearer cw_your_api_key_here

Base URL: https://api.xanguard.tech/v1/cw

Endpoints

MethodEndpointDescription
GET/v1/cw/targetsList all monitored accounts
POST/v1/cw/targetsAdd an account to monitor. Body: {"handle": "elonmusk"}
DELETE/v1/cw/targets/{handle}Remove a target
GET/v1/cw/webhookGet configured webhook URL
PUT/v1/cw/webhookSet webhook URL. Body: {"url": "https://..."}. Returns the signing secret once; delivery starts immediately
GET/v1/cw/settingsGet current filter settings
PATCH/v1/cw/settingsUpdate filter settings. Body, all optional: event_types (any of community_joined, community_renamed, community_description_changed, account_followed), min_member_count (0 = off), flap_cooldown_secs (0-3600)
GET/v1/cw/statusHandles tracked, handle limit, communities tracked, deliveries in the last 24h
WS/v1/cw/wsWebSocket stream of community-change events. Auth: ?api_key=cw_...

Webhook Format

Set your webhook with PUT /v1/cw/webhook, body {"url": "https://..."}. The response shows the signing secret once, and every event is then POSTed automatically, one signed request per event. Every community-change delivery uses the constant event name community_change — the specific type is inside data.event_type:

{
  "event": "community_change",
  "timestamp": 1784646000000,
  "data": {
    "event_type": "community_joined",
    "screen_name": "elonmusk",
    "twitter_user_id": "44196397",
    "community_id": "1493446837214187523",
    "community_name": "Crypto Builders",
    "description": "…",
    "member_count": 15420,
    "creator_screen_name": "someuser",
    "detected_at": 1784645998000,
    "detection_latency_ms": 1400
  }
}

data.event_type is one of: community_joined, community_renamed (adds old_name), community_description_changed (adds old_description). X stopped new community creation in April 2026, so alerts cover existing communities. Follow events and the new-follower digest use their own envelopes, shown below. Timestamps are epoch milliseconds.

New-follower events arrive as a batch digest with their own envelope (turn the digest on per handle in @F_xanguard_bot):

{
  "event": "new_followers",
  "timestamp": 1784646000000,
  "data": {
    "screen_name": "elonmusk",
    "twitter_user_id": "44196397",
    "followers": [
      {"user_id": "123", "screen_name": "newfan", "display_name": "New Fan", "followers_count": 320, "following_count": 150, "account_age_days": 400}
    ],
    "detected_at": 1784645998000
  }
}

Follow events (account_followed) use their own envelope:

{
  "event": "follow_change",
  "timestamp": 1784646000000,
  "data": {
    "screen_name": "elonmusk",
    "twitter_user_id": "44196397",
    "followed_user_id": "783214",
    "followed_screen_name": "someuser",
    "followed_display_name": "Some User",
    "followed_bio": "…",
    "followed_followers_count": 12000,
    "detected_at": 1784645998000
  }
}

Deliveries carry X-Signature (lowercase hex HMAC-SHA256 of the raw body, keyed with your webhook secret; same scheme as Tweet Alerts webhooks) and X-CW-Client-Id. A delivery is retried up to 2 more times (after 1s, then 2s) on a network error or 5xx; 4xx responses are not retried. Requests time out after 5 seconds.

Rename Watch and Posts Scanner add-on alerts are delivered in Telegram only, not to the webhook or WebSocket.

WebSocket

wss://api.xanguard.tech/v1/cw/ws?api_key=cw_your_api_key_here

Each frame is {"type": "community_change", "data": {...}} with the same data as the webhook, for every handle you watch. Follow and new-follower events go to the webhook and Telegram only. Filter settings apply to the webhook and Telegram, not the WebSocket. Your handle list is read when you connect, so reconnect after changing targets.