# Xanguard — Real-Time Twitter/X Monitoring Platform (Full Reference) > Xanguard is a real-time Twitter/X monitoring platform that delivers tweet alerts (median ~200 ms on paid plans, published live at https://xanguard.tech/speed/), community gate detection, profile watching, follow/unfollow tracking, new-follower detection, deleted-tweet detection, contract-address tweet search, and engagement monitoring across 9 products. Xanguard serves crypto traders, DeFi protocols, trading bots, and AI agents through Telegram bots, WebSocket feeds and REST APIs, plus HMAC-signed webhooks on paid Tweet Alerts plans. The B2B WebSocket API uses TweetCatcher-compatible opcodes and starts at $49/mo for 50 handles. - Website: https://xanguard.tech - API Documentation: https://docs.xanguard.tech - Telegram Bot Guides: https://docs.xanguard.tech/telegram/ - OpenAPI Spec: https://xanguard.tech/openapi.json - Blog: https://xanguard.tech/blog/ - Health: https://xanguard.tech/health --- ## Core Products ### 1. Tweet Alerts (@Xanguard_bot) — Free + Paid ($19-$700/mo) Plans: Free 1 account · Starter $19 (10) · Growth $49 (35) · Pro $99 (75) · Business $179 (150) · Scale $230 (200) · Enterprise $349 (500) · Ultra $700 (1,000). Tweet notifications with a measured median of ~200 ms on paid plans (the free plan is slower). Delivery via Telegram. Paid plans can also register HMAC-SHA256 signed webhooks (headers `X-Signature` and `X-Webhook-Id`; limit per plan: Starter 1, Growth 2, Pro 5, Business and Scale 10, Enterprise 25, Ultra 50; not on the free plan). High-volume WebSocket and REST feeds come with B2B plans (API keys are issued in @B2B_Xanguard_bot). Features keyword filtering, contract address extraction with a live token box on Telegram alerts (price, market cap, FDV, liquidity, 24h volume, price change, ATH, buys/sells, token age, DexScreener and pump.fun links), reply/quote filtering, and mute controls. The free tier supports 1 handle with Telegram delivery. Paid tiers support 10 to 1,000 handles. - Bot: https://t.me/Xanguard_bot - Page: https://xanguard.tech/ ### 1b. Add-ons inside @Xanguard_bot (each a separate subscription, no Tweet Alerts plan required, paid in SOL) - **Follow Watch** (https://xanguard.tech/follow-watch/): Telegram alerts when a watched account follows or unfollows someone, with the followed account's name, bio and follower counts. New follows alerted in a median of 284 ms, 93.5% under 500 ms (measured from the moment X shows the follow; 784 follows, 48h to 20 Sep 2026). 15 accounts $15/mo · 60 $59 · 120 $89 · 350 $189 · 600 $299. - **Profile Watch**: alerts on name, bio, avatar and banner changes. 35 accounts $35/mo · 75 $75 · 150 $150 · 500 $500. - **Keyword Alerts**: one keyword list applied to all tracked accounts, $10/mo flat. Per-account keyword filters are included in every plan. - **Search Alerts**: keyword monitoring across all of X, 20 queries for $50/mo. Checked on a schedule, as often as every minute (you choose: 1 min, 5 min, 10 min, 30 min, 1 h or 6 h), not in real time. ### 2. Community Watch (@F_xanguard_bot) — $100-$1,500/mo Twitter/X Community monitoring with approximately 5-second detection. Tracks when watched accounts join communities, community renames and description changes, follows, and new-follower events. (X stopped new community creation in April 2026, so alerts focus on existing communities.) Delivery: Telegram, API, and signed webhook (set via the API). - Bot: https://t.me/F_xanguard_bot - Page: https://xanguard.tech/communities/ ### 3. Convergence Tracker (@T_Xanguard_bot) — $100-$1,500/mo Multi-account community clustering detection. Identifies when multiple monitored Twitter accounts join the same community within a configurable time window. Delivery: Telegram, API, and signed webhook (set via the API). - Bot: https://t.me/T_Xanguard_bot - Page: https://xanguard.tech/tracker/ ### 4. Xanguard B2B (@B2B_Xanguard_bot) — $49-$2,849/mo High-volume real-time Twitter monitoring via WebSocket with TweetCatcher-compatible opcodes. Positioned as Tweets + Profile + new-follower + deleted-tweet detection. Modules: tweets (realtime), follow/unfollow detection (follows), profile change detection (profile_watch), new-follower detection (followers — usually within 30 minutes, and exactly who it was), and deleted-tweet detection (realtime — usually within about 2 minutes of the deletion, with the deleted text when Xanguard saw the tweet). REST endpoints for on-demand data. Supports up to 1,000 handles per client. - Bot: https://t.me/B2B_Xanguard_bot - WS Endpoint: wss://api.xanguard.tech/v1/dt/realtime/ws ### 5. Trending Alerts (@Trends_Xanguard_bot) — $39/mo Trending tweet monitoring across 24 categories. Pro tier at $39/mo for all categories with WebSocket and REST access. - Bot: https://t.me/Trends_Xanguard_bot - Page: https://xanguard.tech/trending/ ### 6. Engagement Tracker (@E_Xanguard_bot) — $100-$200/mo Real-time tweet engagement monitoring. Tracks likes, retweets, replies, quotes and bookmarks on specific tweets. - Bot: https://t.me/E_Xanguard_bot ### 7. PF — pump.fun Callouts + Wallet Events (@PF_Xanguard_bot) — $100-$500/mo Real-time pump.fun caller callout alerts with entry market cap, caller position size, cost basis, thesis, and the caller's track record (win rate at 2x+, median multiple, followers). Milestone pings at 2x/5x/10x with time-to-hit. Wallet events too: livestreams, launches, graduations. Callouts, Livestream, Token Launch and Graduation are four separate subscriptions on the same grid: $100 (3 callers or wallets), $180 (6), $270 (10), $500 (20), per alert type. - Bot: https://t.me/PF_Xanguard_bot (`/call` for callers, `/add` for wallets) - Page: https://xanguard.tech/pumpfun/ ### 8. Search Alerts — $50/mo add-on Keyword search monitoring across all of X, 20 queries for $50/mo. Checks as often as every minute (you choose: 1 min to 6 h). Not real-time. Bought inside @Xanguard_bot; no Tweet Alerts plan required. ### 9. CA Search (B2B add-on) — $100-$250/mo Full tweet search by contract address, ticker, cashtag, or keyword via `POST /v1/search`. Each call walks the last 24 hours of matches (or a custom since/until window) and returns up to 200 tweets with full author metadata, engagement metrics, quote/reply context, and a summary (unique authors, total reach, top 5 callers). Auth: B2B `dt_` key; also accepts the twitterapi.io-compatible `X-API-Key` header. - Docs: https://docs.xanguard.tech/ca-search/ --- ## B2B API Pricing ### Starter (tweets + deleted-tweet) | Handles | Price | |---------|-------| | 50 | $49/mo | | 250 | $229/mo | | 500 | $449/mo | | 1,000 | $849/mo | ### Pro (+ profile watch + new-follower) | Handles | Price | |---------|-------| | 50 | $99/mo | | 250 | $429/mo | | 500 | $749/mo | | 1,000 | $1,349/mo | ### Enterprise (+ follow/unfollow, all 5 modules) | Handles | Price | |---------|-------| | 50 | $249/mo | | 250 | $979/mo | | 500 | $1,649/mo | | 1,000 | $2,849/mo | ### Comparison to Alternatives - **TweetStream**: $199/mo ($139/mo billed annually), tweet-focused feed (checked September 2026) - **TweetCatcher**: EUR 300/mo for 200 handles (tweets + follows) (checked September 2026) - **Official X API**: pay-per-use since 2026: $0.005 per post read, $0.010 per user read, 3 million post reads a month before Enterprise; filtered stream limited to 1 connection (docs.x.com, checked 5 October 2026). Comparison: https://xanguard.tech/blog/xanguard-vs-x-api/ Xanguard provides tweet detection in a median of ~200 ms, 5 monitoring modules, WebSocket and REST delivery, and starts at $49/mo for 50 handles. ### CA Search add-on (standalone, or on top of any B2B tier) | Searches/day | Price | |--------------|-------| | 1,000 | $100/mo | | 2,000 | $180/mo | | 5,000 | $250/mo | Payment is accepted in SOL (Solana) only, and payments are final and non-refundable (https://xanguard.tech/refund/). All monitoring is non-custodial and read-only. A 10% referral commission is available with instant SOL payout. --- ## Authentication ### Bearer Token (REST API) Each product uses a prefixed API key obtained from the corresponding Telegram bot: - **Tweet Alerts**: `xg_` prefix, created at https://xanguard.tech/api-keys (a B2B `dt_` key also works on Tweet Alerts endpoints) - **Community Watch**: `cw_` prefix from @F_xanguard_bot - **Convergence Tracker**: `ct_` prefix from @T_Xanguard_bot - **Xanguard B2B**: `dt_` prefix from @B2B_Xanguard_bot - **Engagement Tracker**: `et_` prefix from @E_Xanguard_bot - **Trending Alerts**: `trend_` prefix from @Trends_Xanguard_bot - **PumpFun Bot**: `pf_` prefix from @PF_Xanguard_bot - **Search Alerts**: `sa_` prefix from @Xanguard_bot - **ECA**: `eca_` prefix from @ECA_Xanguard_bot (`/apikey`) ``` Authorization: Bearer ``` ### WebSocket Auth (Tweet Alerts) Pass api_key as query parameter: ``` wss://api.xanguard.tech/v1/ws?api_key= ``` ### WebSocket Auth (B2B Realtime) Connect without auth, receive HELLO, then send LOGIN opcode with `dt_` key. See B2B Realtime section below. ### WebSocket Auth (Other Products) Pass api_key as query parameter on each product's WS endpoint: ``` wss://api.xanguard.tech/v1/{product}/ws?api_key= ``` ### JWT Cookie (Web Dashboard) Cookie name: `xg_session`. Obtained via POST `/v1/auth/telegram` or POST `/v1/auth/apikey`. ## Response Envelope All REST responses use this envelope: ```json {"ok": true, "data": { ... }} {"ok": false, "error": "Error message", "code": "unauthorized"} ``` Every error carries a stable machine-readable `code` (match on it, not on `error` text). Some add `hint` (what to do next) and `retry_after` (seconds; also sent as the `Retry-After` header). ## Error Codes | Status | Meaning | |--------|---------| | 401 | Missing or invalid API key | | 403 | Insufficient tier / feature not available | | 404 | Resource not found | | 409 | Handle already tracked / duplicate | | 429 | Rate limit or daily allowance exceeded (Tweet Alerts REST: per account, by plan; CA Search: 10/s, 20/min, daily; B2B `/v1/dt/*` and `/twitter/*` are not rate limited) | | 500 | Internal server error | Error `code` values. The `key_*` codes come from B2B (`/v1/dt/*` and the B2B WebSockets) only; `ip_blocked` from the B2B WebSockets only; `handle_limit_reached` from B2B, Community Watch and Convergence Tracker; `daily_limit_reached` from CA Search. Tweet Alerts and the product APIs (cw/ct/eca/et/trending/pf/sa) return status-derived codes only, and product WebSockets reject a bad key with a plain-text HTTP 401 before the upgrade. Requests the server can't parse (bad JSON, body over 64 KB) get a plain-text 400/413/415/422. | code | Status | Meaning / what to do | |------|--------|----------------------| | key_missing | 401 | No key sent, or empty. Set the key variable/config on that machine. | | key_in_query | 401 | Key sent as `?api_key=` on REST. Use `Authorization: Bearer` or `X-API-Key` header. | | key_malformed | 401 | Wrong key prefix for this product. | | key_unknown | 401 | Typo, cut-off key, or an old key you regenerated. | | key_expired | 401 | Subscription expired (date in message). Renew in the bot; key stays the same. | | key_deactivated | 401 | Key deactivated. Contact support. | | ip_blocked | 429 | B2B WebSockets only: 5 failed logins from your IP within 60s blocked it for 1 hour. Fix the key; lifts by itself (`retry_after`). | | handle_limit_reached | 403 | Plan handle ceiling full. Remove a handle or upgrade. | | rate_limited | 429 | Too many requests. Wait `retry_after` seconds. | | daily_limit_reached | 429 | Daily allowance used; resets 00:00 UTC. | | service_unavailable / server_error | 503 / 5xx | Temporary problem on our side. Retry in ~30s. | When no specific code applies, `code` is derived from the status: bad_request, unauthorized, forbidden, not_found, conflict, rate_limited, server_error, service_unavailable. --- ## Xanguard B2B Realtime API (WebSocket) High-volume real-time feed with TweetCatcher-compatible opcode protocol. Supports tweets, follows, profile changes, new-follower detection, and deleted-tweet detection. Auth: `dt_` prefixed API key. ### WebSocket Endpoint ``` wss://api.xanguard.tech/v1/dt/realtime/ws ``` No query parameter required. Authentication happens via the LOGIN opcode after connection. Maximum 5 concurrent connections per account, counted across all B2B WebSocket URLs (`/v1/dt/realtime/ws`, and the tweet-only `/v1/dt/ws?api_key=` and `/twitter/tweet/websocket`). ### Opcodes | Opcode | Name | Direction | Description | |--------|------|-----------|-------------| | 10 | HELLO | server -> client | Sent on connect, includes heartbeat_interval | | 2 | LOGIN | client -> server | Send API key to authenticate | | 4 | READY | server -> client | Auth successful, includes client config | | 0 | EVENT | server -> client | Real-time event data | | 1 | HEARTBEAT | client -> server | Keep-alive ping | | 11 | HEARTBEAT_ACK | server -> client | Response to heartbeat | | 3 | DISCONNECT | server -> client | Connection terminated with reason | ### Connection Flow 1. Connect to `wss://api.xanguard.tech/v1/dt/realtime/ws` 2. Receive HELLO (immediately): ```json {"op": 10, "d": {"heartbeat_interval": 30000}} ``` 3. Send LOGIN as a text frame within 15 seconds (`d` is the key string, or `{"api_key": "dt_..."}`; `apiKey` also accepted, plus optional filters `types`, `categories`, `onlyCA`, `onlyTicker`). Any non-text frame before LOGIN ends the session with `Login timeout`: ```json {"op": 2, "d": "dt_your_api_key_here"} ``` 4. Receive READY on success (these are all its keys; the connection limit, 5 per account, is not included; `modules` can also list `late_delivery`, `ca_search`, `search_*`): ```json {"op": 4, "d": {"client_id": 1, "modules": ["realtime", "follows"], "handles": 150, "max_handles": 1000}} ``` Or DISCONNECT on failure: ```json {"op": 3, "d": {"reason": "Invalid or expired API key", "code": "key_expired", "message": "Your subscription expired on 01 Oct 2026 10:12 UTC. Renew in @B2B_Xanguard_bot; your key stays the same."}} ``` `d.reason` is the unchanged legacy string; `d.code` is stable; `d.message` explains it; `d.retry_after` (seconds) appears when retrying later will work. | reason | code | Retry? | What to do | |--------|------|--------|-----------| | Invalid or expired API key | key_missing / key_malformed / key_unknown / key_expired / key_deactivated | No | Fix or renew the key (see message). | | Invalid or expired API key | key_blocked | after retry_after | Key failed 5 logins in 60s; blocked 1 hour. | | Too many failed logins | ip_blocked | after retry_after | IP blocked 1 hour after 5 failed logins in 60s. Your key is not rate limited. | | Invalid login payload | login_invalid | No | LOGIN must be `{"op":2,"d":"dt_key"}` or `{"op":2,"d":{"api_key":"dt_key"}}`. | | Login timeout | login_timeout | Yes | Send LOGIN within 15s of HELLO; `op` must be the number 2. | | Too many connections (max 5) | too_many_connections | after retry_after | Close unused sockets; dropped ones free up within 3 minutes. | | Subscription expired | subscription_expired | No | Renew in @B2B_Xanguard_bot; key stays the same. | Failed-login IP block: 5 failed logins (missing, wrong or expired key) from one IP within 60 seconds block that IP for 1 hour on every B2B WebSocket URL. Each failed login's message counts down the attempts left. While blocked: HTTP 429 with JSON body (`code: "ip_blocked"`, unblock time) and `Retry-After`; on `/v1/dt/realtime/ws` about once a minute the connection is accepted just to deliver the DISCONNECT. Retrying does not extend the block. 5. Receive EVENTs based on enabled modules. 6. Send HEARTBEAT every `heartbeat_interval` ms to stay connected: ```json {"op": 1} ``` Connection is closed 90 to 120 seconds after your last heartbeat, without a DISCONNECT frame (also after 180 s with no inbound frame, when a write to you blocks for 5 s, and on server restarts). HEARTBEAT_ACK is `{"op": 11}`. Reconnect with backoff (1s, 2s, 4s, capped at 30s) and log in again; stop on "Invalid or expired API key", since 5 failed logins within 60 seconds block the source for an hour. ### Delivery rules - By default the stream is real-time only: tweets older than 30 seconds are dropped and there is no tweet replay after a reconnect. - Opt-in late delivery (per key, on request; `late_delivery` module): late tweets up to 24 h old arrive with `d.delayed: true` and `d.delay_ms`, and right after READY the last 15 minutes of tweets for your handles (newest 500) are replayed with `d.replayed: true` and the live `event_id`. Replayed tweets carry core fields only (no reply/quote body, entities, conversation_id or metrics; no `twitter.post.update`). - On every LOGIN the last 15 minutes of follow/unfollow events are replayed after READY (needs `follows`). Replayed unfollows reuse the live `event_id`; a replayed follow's id can differ by a few ms, so dedupe follows on `task_info.handle` + `data.id`. - Several non-tweet events detected together can share one `event_id`: dedupe follow, unfollow and new-follower events on `event_id` + `data.id`, deleted-tweet events on `event_id` + `data.tweet_id`. - Deleted-tweet events are on for every plan, new-follower events on Pro and Enterprise, OCR fields on Enterprise; all switch on automatically. ### Event Types #### twitter.post.new (module: realtime) First delivery of a detected tweet, with the full payload. Only reply/quote context (or, rarely, the body of a very long post) can be incomplete; a `twitter.post.update` then follows with the same `event_id`. ```json { "op": 0, "d": { "event": "twitter.post.new", "event_id": "evt_1234567890123456789", "task_info": {"handle": "example_dev"}, "data": { "id": "1234567890123456789", "created_at": 1712000000000, "type": "post", "text": "Hello world $EXMPL", "cashtags": ["EXMPL"], "media": [{"type": "photo", "url": "https://pbs.twimg.com/media/..."}], "mentions": [], "author": { "id": "1234567890", "handle": "example_dev", "name": "Example Dev", "avatar": "https://pbs.twimg.com/profile_images/...", "description": "Example account used in these docs", "verification": {"is_verified": true, "type": "blue"}, "affiliation": null, "stats": {"followers": 12000, "following": 800} }, "in_reply_to": null, "quoted_tweet": null, "possibly_sensitive": false, "conversation_id": "1234567890123456789", "entities": {"hashtags": [], "urls": [], "symbols": [{"text": "EXMPL", "indices": [12, 18]}]}, "metrics": {"likes": 10, "retweets": 2, "replies": 1, "quotes": 0, "views": "1500"} } } } ``` Tweet types in `data.type`: `"post"`, `"reply"`, `"quote"`, `"repost"`. `in_reply_to` is null or `{"tweet_id", "user"}`. `quoted_tweet` is null or `{"id", "text", "author": {"handle", "name", "avatar"}, "media": [url strings]}` (on replies it carries the parent). `media[].type` is always `"photo"` (videos show as their preview image). `mentions` may be null or `[]` even when the tweet mentions accounts; parse `@handles` from `text`. `metrics.views` is a string; any metric can be null. `verification.type` is `"blue"`, `"business"`, `"government"` or null. Enterprise plans add `ocr_text` (null if no images) and `extracted_cas` (`[]` if none) to every tweet event. Tweet events have no `event_time`; use `data.created_at` (epoch ms). #### twitter.post.update (module: realtime) Context correction for a previously sent tweet, emitted only when a reply or quote first shipped without its full context, a very long post shipped truncated, or (OCR plans) media was recovered later. Same `data.id` and the same `event_id` (`evt_`) as the original `twitter.post.new`: replace the stored data for this tweet. Same payload structure; in an update `quoted_tweet` may have no `media` and `quoted_tweet.author.name` may be null. ```json { "op": 0, "d": { "event": "twitter.post.update", "event_id": "evt_1234567890123456789", "task_info": {"handle": "example_dev"}, "data": { "id": "1234567890123456789", "created_at": 1712000000000, "type": "quote", "text": "This is huge", "media": [], "mentions": [], "author": {"id": "1234567890", "handle": "example_dev", "name": "Example Dev", "avatar": "https://pbs.twimg.com/profile_images/...", "description": "Example account used in these docs", "verification": {"is_verified": true, "type": "blue"}, "affiliation": null, "stats": {"followers": 12000, "following": 800}}, "in_reply_to": null, "quoted_tweet": { "id": "9876543210987654321", "text": "Original tweet text here", "author": {"handle": "example_founder", "name": "Example Founder", "avatar": "https://pbs.twimg.com/profile_images/..."}, "media": [] }, "possibly_sensitive": false } } } ``` Non-tweet event ids (`evt_f_`, `evt_fr_`, `evt_p_`, `evt_fl_`, `evt_del_`) are `_`; the suffix is epoch milliseconds equal to `event_time`. #### twitter.following.new (module: follows) Fired when a monitored handle follows a new account. `task_info.id` is the tracked account's user id. ```json { "op": 0, "d": { "event": "twitter.following.new", "event_id": "evt_f_example_dev_1712000000000", "event_time": 1712000000000, "task_info": {"handle": "example_dev", "id": "1234567890"}, "data": { "id": "2345678901", "handle": "example_founder", "name": "Example Founder", "bio": "Building things", "followers": 5200, "following": 350, "protected": false } } } ``` `bio`, `followers`, `following` and `protected` can be null. #### twitter.following.removed (module: follows) Fired when a monitored handle unfollows an account. Same envelope and `data` shape as `twitter.following.new`; event ids start with `evt_fr_`. `data.handle` is `""` and `data.name` null when that profile is no longer available. #### twitter.profile.update (module: profile_watch) Fired when a monitored handle changes its bio, name, avatar, banner, location, website, verified badge, pinned post, or handle. ```json { "op": 0, "d": { "event": "twitter.profile.update", "event_id": "evt_p_example_dev_1712000000000", "event_time": 1712000000000, "task_info": {"handle": "example_dev"}, "data": { "field": "bio", "prev": "Old bio text", "updated": "New bio text" } } } ``` `field` is one of: `"bio"` or `"description"` (both mean the bio), `"name"` and `"display_name"` (a name change arrives under both), `"avatar"` and `"avatar_url"` (same), `"banner_url"`, `"location"`, `"website"`, `"verified"` (`prev`/`updated` are `"true"`/`"false"`), `"pinned_post"` (comma-separated tweet ids, `""` if none), `"handle"` (rename: `prev` = old handle, `updated` = new; `task_info.handle` is the new handle). `prev`/`updated` are always strings, `""` when empty. #### twitter.follower.new (module: followers) Fired when a monitored handle gains a new follower (usually within 30 minutes). Identifies who the new follower was. ```json { "op": 0, "d": { "event": "twitter.follower.new", "event_id": "evt_fl_example_dev_1712000000000", "event_time": 1712000000000, "task_info": {"handle": "example_dev", "id": "1234567890"}, "data": { "id": "12345678", "handle": "newfollower", "name": "New Follower" } } } ``` #### twitter.tweet.deleted (module: realtime) Fired when a monitored handle deletes a tweet, usually within about 2 minutes (each deletion is confirmed before it is sent). Included on every B2B tier. `text` carries the deleted tweet's text when Xanguard saw the tweet; `tweet_id` and `text` are `null` when a deletion is confirmed but the specific tweet cannot be identified. Guide: https://xanguard.tech/deleted-tweets/ ```json { "op": 0, "d": { "event": "twitter.tweet.deleted", "event_id": "evt_del_example_dev_1712000000000", "event_time": 1712000000000, "task_info": {"handle": "example_dev"}, "data": { "tweet_id": "1234567890123456789", "text": "Deleted tweet text, when available" } } } ``` Match `tweet_id` against the `data.id` of the earlier `twitter.post.new`. Tweets deleted together share one `event_id`; dedupe on `event_id` + `data.tweet_id`. --- ## Xanguard B2B REST API On-demand Twitter data endpoints. Auth: `Authorization: Bearer dt_...` or `X-API-Key: dt_...` (keys in the URL are rejected with 401 `key_in_query`). `/v1/dt/*` responses use the `{ok, data}` / `{ok: false, error, code}` envelope; `/twitter/*` routes use the twitterapi.io shape (bare objects on success, `{"status": "error", "msg": "..."}` on failure). B2B REST is not rate limited; limits are your plan's handle ceiling and a 64 KB request-body cap. Not currently populated: `/v1/dt/profile/{handle}/history`, `/v1/dt/following/{handle}`, `/v1/dt/followers/{handle}`, `/v1/dt/communities/{handle}` and `/v1/dt/social/diff/{handle}` return empty lists today. For follow, follower and profile data use the realtime WebSocket and `GET /v1/dt/events/{event_id}`. ### GET /v1/dt/targets List watched handles for this client, with `count` and `max_handles`. Includes handles paused by the system (`is_active: false`); only active handles count toward `max_handles`. ### POST /v1/dt/targets Add a handle to watch. Re-adding an active handle returns 409; re-adding a paused one reactivates it (201). If the handle cannot be resolved right away it is still added with `twitter_user_id: null`. Errors: 400 empty handle · 403 `handle_limit_reached` · 404 not found or suspended · 409 already tracked · 503 retry with backoff. Request: ```json {"handle": "example_dev"} ``` ### DELETE /v1/dt/targets/{handle} Remove a handle from watch list. ### GET /v1/dt/profile/{handle} Latest profile snapshot. Populated: `twitter_id`, `screen_name`, `display_name`, `bio`, `followers`, `following`, `is_blue_verified`, `avatar_url`, `scraped_at`; other fields are null or 0. ### GET /v1/dt/profile/{handle}/history Follower/following/tweet/like/listed count snapshots, newest first (`limit` default 50, max 200; `offset`). Requires `profile_watch`. Not currently populated. ### GET /v1/dt/tweets/{handle} Last 20 tweets captured for the handle (engagement counts are 0 on this endpoint; use the WebSocket for full tweet objects). ### GET /v1/dt/following/{handle} Accounts the handle follows (`limit` default 100, max 500; `offset`). Response key `following`. Requires `follows`. Not currently populated. ### GET /v1/dt/followers/{handle} Followers of the handle (`limit` default 100, max 500; `offset`). Response key `follower` (singular). Requires `followers`. Not currently populated. ### GET /v1/dt/communities/{handle} Community memberships for a handle. Not currently populated. ### GET /v1/dt/social/diff/{handle} Following and follower edges added or removed in the last 7 days (up to 100 each, newest first; `relation` tells them apart). Requires `follows`. Not currently populated. ### GET /v1/dt/events/{event_id} Trace any `event_id` received over the WebSocket back to its detection record (`match_count`, `matches`). Tweet ids are `evt_`; non-tweet ids (`evt_f_`, `evt_fr_`, `evt_p_`, `evt_fl_`) are matched on the handle within a 10-second window. Deleted-tweet ids (`evt_del_`) return 404 (not retained). ### GET /v1/dt/webhook Get the stored webhook URL. Stored only; delivery is not currently sent. Use WebSocket or REST. ### PUT /v1/dt/webhook Store a webhook URL. Stored only; delivery is not currently sent. Use WebSocket or REST. Request: ```json {"url": "https://your-server.com/dt-webhook"} ``` ### GET /v1/dt/status Handle count (`targets`), `max_handles`, `is_active`, `days_left` (0 for plans with no end date), `modules`. ### twitterapi.io-compatible lookups (same `dt_` key) - `GET /twitter/user/{username}`: profile for a handle Xanguard holds data on (404 otherwise). - `GET /twitter/tweet/{tweetId}`: single tweet with current engagement counts (counts can be null; `type` is post, reply or quote). - `GET /twitter/blacklist`, `POST /twitter/blacklist/{username}`, `DELETE /twitter/blacklist/{username}`: stores a per-key exclusion list (feed filtering by it is not active yet). - `GET /twitter/communities`: catalog of communities, ranked by member count (`search`, `limit` default 50 max 200, `offset`). ### WebSocket: GET /v1/dt/realtime/ws Product-specific WebSocket. Connect: `wss://api.xanguard.tech/v1/dt/realtime/ws`. Authenticate via the LOGIN opcode after connecting (no query parameter) — see the Xanguard B2B Realtime API section above. --- ## Tweet Alerts API Real-time tweet notifications (median detection ~200 ms on paid plans). Auth: `Authorization: Bearer xg_...` on REST, `?api_key=xg_...` on the WebSocket. `xg_` keys are created at https://xanguard.tech/api-keys (paid Tweet Alerts plan; a new key revokes the old one). A B2B `dt_` key also works on every endpoint here; with a `dt_` key, `/v1/accounts` manages your B2B handle list. Rate limit: per account (all keys share it), 1-second windows, scales with plan; 429 `rate_limited` with `retry_after: 1`. Errors use status-derived codes only (`unauthorized` for any key problem, `forbidden` for no paid plan or a full plan). ### WebSocket: GET /v1/ws Connect: `wss://api.xanguard.tech/v1/ws?api_key=xg_...` Only handles already on your tracked list can be subscribed (others are skipped with an `error` message; no `@`). Only tweets posted less than 60 s earlier and detected after you subscribed are sent; there is no replay after a reconnect. Telegram settings, keywords and mutes do not apply. Connections per account, across keys: Starter 2, Growth 3, Pro 5, Business 10, Scale 10, Enterprise 25, Ultra 50 (`dt_` keys 5); excess gets a plain-text HTTP 429, a bad key or free plan a plain-text HTTP 401. The 11th inbound frame in any 1-second window closes the connection. Also supports JWT cookie auth (web dashboard). **Client messages:** ```json {"type": "subscribe", "handles": ["example_dev", "example_founder"]} ``` ```json {"type": "unsubscribe", "handles": ["example_dev"]} ``` ```json {"type": "ping"} ``` **Server messages:** Subscribe/unsubscribe acknowledgment: ```json {"type": "ack", "action": "subscribe", "handles": ["example_dev", "example_founder"], "active": 2, "max": 50} ``` Tweet alert: ```json { "type": "alert", "tweet_id": "1234567890123456789", "handle": "example_dev", "text": "Hello world", "url": "https://x.com/example_dev/status/1234567890123456789", "image_url": "https://pbs.twimg.com/media/...", "image_urls": ["https://pbs.twimg.com/media/..."], "is_reply": false, "is_quote": false, "received_at": 1712000000120, "created_at": 1711999999800, "original_tweet_id": null, "possibly_sensitive": false, "mentions": [] } ``` Pong: ```json {"type": "pong"} ``` Error: ```json {"type": "error", "message": "Would exceed handle limit: 10 + 5 new = 15, max 10"} ``` ### GET /v1/accounts List tracked Twitter handles for the authenticated user. Response: ```json {"ok": true, "data": {"accounts": [{"handle": "example_dev", "is_active": true, "keywords": [], "muted": false, "exclude_replies": false, "exclude_reposts": false, "exclude_quotes": false, "added_at": 1782248682700, "profile": null}], "count": 1, "limit": 10}} ``` ### POST /v1/accounts Add Twitter handles (max 25 per request). Handles are normalized to lowercase, @ stripped. Returns 201; handles that don't exist or are suspended, and any beyond your remaining slots, are skipped silently. A full plan returns 403. Request: ```json {"handles": ["example_dev", "example_founder"]} ``` ### GET /v1/accounts/{handle} Get details for a single tracked handle including profile data. ### DELETE /v1/accounts/{handle} Remove a handle from tracking. Keyword filters are kept and return if you re-add it. ### PUT /v1/accounts/{handle}/keywords Set keyword filters (max 20, 50 characters each). Only tweets containing at least one keyword trigger Telegram alerts. Request: ```json {"keywords": ["bitcoin", "solana", "$SOL"]} ``` ### DELETE /v1/accounts/{handle}/keywords Clear keyword filters (receive all tweets from this handle). ### PUT /v1/accounts/{handle}/mute Mute or unmute a handle (suppress Telegram alerts without removing it). Request: ```json {"muted": true} ``` ### PATCH /v1/accounts/{handle}/filters Per-account Telegram filters: `exclude_replies`, `exclude_reposts`, `exclude_quotes` (booleans). The response echoes the request; omitted fields come back null (= unchanged). ### GET /v1/settings Get user notification settings (these apply to Telegram alerts; the WebSocket and webhooks ignore them). ### PATCH /v1/settings Update notification settings. ### GET /v1/subscription Get current subscription tier, limits, and expiration. ### GET /v1/plans List public subscription plans with pricing (currently includes every product's plans, with no product field). ### POST /v1/webhooks Register a webhook URL for tweet delivery (paid Tweet Alerts plans). Payloads are signed with HMAC-SHA256 in the `X-Signature` header, with `X-Webhook-Id` identifying the webhook. Limit per plan: Starter 1, Growth 2, Pro 5, Business and Scale 10, Enterprise 25, Ultra 50; the free plan has none. Request: ```json {"url": "https://your-server.com/webhook"} ``` ### GET /v1/webhooks List registered webhooks. ### DELETE /v1/webhooks/{id} Delete a webhook. Webhook changes take effect within 30 seconds. After 10 consecutive failed deliveries a webhook is disabled for good and disappears from the list. --- ## Community Watch API Monitor the X Community activity of accounts you track (~5s detection): joins, community renames and description changes, follows, and an optional new-follower digest. X stopped new community creation in April 2026, so alerts cover existing communities. Auth: `Bearer cw_...` (key from `/apikey` in @F_xanguard_bot). ### WebSocket: GET /v1/cw/ws Connect: `wss://api.xanguard.tech/v1/cw/ws?api_key=cw_...`. Frames: `{"type": "community_change", "data": {...}}` (same `data` as the webhook) for every handle you watch. Follow and new-follower events go to webhook and Telegram only. Filter settings apply to webhook and Telegram, not the WebSocket. Your handle list is read at connect; reconnect after changing targets. ### GET /v1/cw/targets List monitored handles. ### POST /v1/cw/targets Add a handle to monitor for community changes. Request: ```json {"handle": "example_dev"} ``` ### DELETE /v1/cw/targets/{handle} Remove a handle from monitoring. ### GET /v1/cw/webhook Get configured webhook URL. ### PUT /v1/cw/webhook Set webhook URL (`{"url": "https://..."}`). The response shows the signing secret once; every event is then POSTed automatically. Headers: `X-Signature` (hex HMAC-SHA256 of the raw body, keyed with your webhook secret) and `X-CW-Client-Id`. Retried up to 2 more times (after 1s, 2s) on a network error or 5xx; 4xx is not retried; 5s timeout. Webhook body: `{"event": "community_change", "timestamp": ms, "data": {"event_type": "community_joined" | "community_renamed" (adds old_name) | "community_description_changed" (adds old_description), "screen_name", "twitter_user_id", "community_id", "community_name", "description", "member_count", "creator_screen_name", "detected_at", "detection_latency_ms"}}`. Follow events use `{"event": "follow_change", ...}` and the new-follower digest `{"event": "new_followers", ...}`. Rename Watch and Posts Scanner add-on alerts are Telegram only. ### GET /v1/cw/settings Get notification settings (which event types are enabled, etc.). ### PATCH /v1/cw/settings Update 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). Turn on the new-follower digest per handle in @F_xanguard_bot. ### GET /v1/cw/status Handles tracked, handle limit, communities tracked, deliveries in the last 24h. --- ## Convergence Tracker API Detect when multiple monitored accounts cluster in the same community. Auth: `Bearer ct_...` ### WebSocket: GET /v1/ct/ws Connect: `wss://api.xanguard.tech/v1/ct/ws?api_key=ct_...`. Frames: `{"type": "convergence", "data": {"community_id", "community_name", "member_count", "converging_handles": [...], "convergence_count", "detected_at"}}`. ### GET /v1/ct/targets List monitored handles. ### POST /v1/ct/targets Add a handle. Request: ```json {"handle": "example_dev"} ``` ### DELETE /v1/ct/targets/{handle} Remove a handle. ### GET /v1/ct/convergence Get current convergence data (which communities have multiple monitored accounts). ### GET /v1/ct/convergence/history Last 50 convergence events. ### GET /v1/ct/settings Get convergence detection settings (time window, minimum accounts, minimum community members). ### PATCH /v1/ct/settings Update settings. Body, all optional: `min_convergence` (2-20), `time_window_hours` (1-168), `min_member_count` (0 or more). ### GET /v1/ct/webhook Get configured webhook URL. ### PUT /v1/ct/webhook Set webhook URL (`{"url": "https://..."}`); delivery starts immediately. Body: `{"event": "convergence_detected", "timestamp": ms, "data": {same as the WebSocket data}}`. Signed with `X-Signature` like Community Watch, plus `X-CT-Client-Id`; same retry rules. ### GET /v1/ct/status Handles tracked, handle limit, convergences in the last 24h. --- ## Engagement Tracker API Track engagement counts on specific tweets: likes, retweets, replies, quotes and bookmarks. Auth: `Bearer et_...` ### WebSocket: GET /v1/et/ws Connect: `wss://api.xanguard.tech/v1/et/ws?api_key=et_...`. Frames: `{"type": "engagement_update", "data": {"tweet_id", "old": {"favorite_count", "retweet_count", "reply_count", "quote_count", "bookmark_count"}, "new": {...}}}`. Watched tweets are read at connect; reconnect after adding tweets. ### GET /v1/et/targets List tracked tweet IDs. ### POST /v1/et/targets Add tweets to track. Request: ```json {"tweet_ids": ["1234567890123456789"]} ``` ### DELETE /v1/et/targets/{tweet_id} Stop tracking a tweet. ### GET /v1/et/engagement/{tweet_id} Get current engagement counts (likes, retweets, replies, quotes, bookmarks). ### GET /v1/et/webhook Get configured webhook URL. ### PUT /v1/et/webhook Set webhook URL. ET deliveries are not HMAC-signed: they carry your secret in an `X-Webhook-Secret` header. Body: `{"type": "engagement_update", "tweet_id", "old": {...}, "new": {...}}`; single attempt, no retries. ### GET /v1/et/status Get service status. --- ## Trending Alerts API Trending tweet alerts across 24 categories. Auth: `Bearer trend_...` ### WebSocket: GET /v1/trending/ws Connect: `wss://api.xanguard.tech/v1/trending/ws?api_key=trend_...`. Streams new trending tweets from all 24 categories; filter on `data.category` (subscriptions control Telegram alerts). Frames: `{"type": "trending_tweet", "data": {"category", "tweet": {"tweet_id", "author_screen_name", "author_display_name", "full_text", "created_at", "retweet_count", "like_count", "reply_count", "quote_count", "view_count", "media_count", "tweet_url"}}}`. ### GET /v1/trending/categories List the 24 category slugs (crypto, news, sports, music, technology, etc.) with subscription status. ### GET /v1/trending/subscriptions Get your subscribed categories. ### PUT /v1/trending/subscriptions Set which categories to receive Telegram alerts for, e.g. `{"categories": ["crypto", "technology"]}`. Unknown slugs are ignored. ### GET /v1/trending/webhook Get the stored webhook URL. Stored only; delivery is not currently sent. Use WebSocket or REST. ### PUT /v1/trending/webhook Store a webhook URL. Stored only; delivery is not currently sent. Use WebSocket or REST. ### GET /v1/trending/status Get service status. --- ## PumpFun Bot API pump.fun caller callouts, milestones, livestreams, token launches and graduations for @PF_Xanguard_bot. Callouts, Livestream, Token Launch and Graduation are four separate subscriptions. Event types: `callout_new`, `callout_milestone`, `livestream_started`, `livestream_ended`, `token_launched`, `graduated`. Auth: `Bearer pf_...` ### WebSocket: GET /v1/pf/ws Connect: `wss://api.xanguard.tech/v1/pf/ws?api_key=pf_...` Streams every wallet event (livestream, launch, graduation) for your watched wallets, and callout frames for callers on your `/call` list (adding callers needs the Callouts subscription). Both lists are read at connect; reconnect after changing either. Frames are wrapped `{"type": "pf_event", "data": {...}}`; callout frames carry: ```json { "type": "pf_event", "data": { "event_type": "callout_new", "mint": "CekGTBEd...", "creator": "6vbrTLsW...", "token_name": "", "token_symbol": "EXMPL", "market_cap": 14600, "detected_at": 1787825953817, "caller_wallet": "6vbrTLsW...", "caller_username": "example_caller", "callout_mcap": 14600, "multiplier": 1.0, "amount_held": 8400000, "cost_basis_sol": 0.9, "thesis": "We will see", "milestone": null } } ``` `callout_milestone` frames add `milestone` ("2x" / "5x" / "10x") and the live `multiplier`. Manage tracked callers in @PF_Xanguard_bot with `/call`. ### GET /v1/pf/targets List watched wallets. ### POST /v1/pf/targets Add a wallet to watch. Request: ```json {"wallet_address": "So11111111111111111111111111111111111111112", "label": "optional"} ``` ### DELETE /v1/pf/targets/{wallet} Remove a wallet. ### GET /v1/pf/events Last 50 wallet events (livestream, launch, graduation). Callouts are not included. ### GET /v1/pf/webhook Get the stored webhook URL. Stored only; delivery is not currently sent. Use WebSocket or REST. ### PUT /v1/pf/webhook Store a webhook URL. Stored only; delivery is not currently sent. Use WebSocket or REST. ### GET /v1/pf/status Get service status. --- ## ECA API (pump.fun launch alerts) Watchlist for pump.fun launches matching a ticker, token name, contract address or deployer wallet. Auth: `Bearer eca_...` (key from `/apikey` in @ECA_Xanguard_bot). ### WebSocket: GET /v1/eca/ws Connect: `wss://api.xanguard.tech/v1/eca/ws?api_key=eca_...`. Frames: `{"type": "match", "data": {"watchlist_entry": {"id", "source", "community_name", "twitter_handle", "added_by_telegram_id"}, "token": {"name", "symbol", "mint", "creator", "bonding_curve", "uri", "signature"}, "match_type", "matched_at"}}`. ### GET /v1/eca/watchlist List active watchlist entries. ### POST /v1/eca/watchlist Add an entry: either `creator_address` alone, or any of `ticker` / `token_name` / `contract_address`. Request: ```json {"ticker": "EXMPL"} ``` ### DELETE /v1/eca/watchlist/{id} Remove an entry. ### GET /v1/eca/matches Recent token matches (last 24h). ### GET /v1/eca/webhook Get the stored webhook URL. Stored only; delivery is not currently sent. Use WebSocket or REST. ### PUT /v1/eca/webhook Store a webhook URL. Stored only; delivery is not currently sent. Use WebSocket or REST. ### GET /v1/eca/status Active entries, total matches. --- ## Search Alerts API Keyword-based tweet monitoring across all of X. Each query is checked at the interval you choose (1 min to 6 h), so matches are not real-time. Auth: `Bearer sa_...` ### WebSocket: GET /v1/sa/ws Connect: `wss://api.xanguard.tech/v1/sa/ws?api_key=sa_...`. Frames: `{"type": "search_alert", "data": {"query_id", "query_text", "tweet_id", "full_text", "screen_name", "display_name", "tweet_url"}}`. ### GET /v1/sa/queries List saved search queries. ### POST /v1/sa/queries Add a search query (`query_text`, 1-200 chars; up to 20 queries). Request: ```json {"query_text": "solana pump"} ``` ### DELETE /v1/sa/queries/{id} Remove a search query. ### GET /v1/sa/webhook Get the stored webhook URL. Stored only; delivery is not currently sent. Use WebSocket or REST. ### PUT /v1/sa/webhook Store a webhook URL. Stored only; delivery is not currently sent. Use WebSocket or REST. ### GET /v1/sa/status Get service status. --- ## CA Search API (B2B add-on) Full tweet search by contract address, ticker, cashtag, or keyword. Auth: `Authorization: Bearer dt_...` or `X-API-Key: dt_...` (twitterapi.io-compatible). Requires a `dt_` key with CA Search enabled (Extra Features menu in @B2B_Xanguard_bot), standalone or on top of any B2B tier. ### POST /v1/search Each call walks the last 24 hours of matches by default, or a custom window via `since` / `until` (RFC3339, YYYY-MM-DD or unix s/ms; `until` exclusive; an `until` older than 24h needs `since` too), newest first, and returns up to 200 tweets with full author + engagement metadata. `query` is 1-200 bytes after trimming. Hot queries that exceed 200 tweets return `has_next_page: true`: send `next_cursor` back as `cursor` with the same query, since and until. Request: ```json {"query": "0x7a848a5a8169aa6a2f603d056a749f924f504444"} ``` Optional continuation: ```json {"query": "$SOL", "cursor": ""} ``` Response (truncated): ```json { "ok": true, "data": { "tweets": [ { "type": "tweet", "id": "1947000000000000000", "url": "https://x.com/hongxiao_sol/status/1947000000000000000", "text": "$EXAMPLE just launched, CA: 0x7a84…4444", "createdAt": "Sun Jul 20 10:15:00 +0000 2026", "retweetCount": 3, "replyCount": 1, "likeCount": 42, "quoteCount": 0, "viewCount": 5100, "bookmarkCount": 2, "lang": "en", "isReply": false, "inReplyToId": "", "inReplyToUsername": "", "conversationId": "1947000000000000000", "author": { "userName": "hongxiao_sol", "name": "Hong", "id": "1500000000000000000", "followers": 11145, "following": 320, "isBlueVerified": true, "profilePicture": "https://pbs.twimg.com/profile_images/…", "description": "sol maxi", "createdAt": "Mon Mar 15 09:00:00 +0000 2021", "statusesCount": 8900, "mediaCount": 1200, "favouritesCount": 4500 }, "entities": {"hashtags": [], "urls": [], "user_mentions": []}, "quoted_tweet": null, "retweeted_tweet": null } ], "summary": { "total_tweets": 20, "unique_authors": 17, "total_reach": 208122, "top_callers": ["@whalecaller", "@hongxiao_sol"] }, "window_hours": 24, "has_next_page": false, "next_cursor": null } } ``` Context fields per tweet: - `quoted_tweet` — nested tweet object when the tweet quotes another (not set for reply parents) - `retweeted_tweet` — nested original when the tweet is a repost - `original` — parent tweet (id, text, author username) when the tweet is a reply (first 30 replies per call; omitted if the parent could not be fetched) Limits: 10 requests/sec and 20 requests/min per Telegram account (all keys share it). Daily allowance per plan: 1,000 / 2,000 / 5,000 searches per day ($100 / $180 / $250 per month), resetting 00:00 UTC; every call counts, including failed ones. `summary.total_reach` sums author followers once per returned tweet; `top_callers` are the authors of the 5 highest-follower tweets and can repeat. Errors: 400 bad query/since/until · 401 missing/invalid key · 403 CA Search not enabled or expired · 429 `rate_limited` / `daily_limit_reached` (with `retry_after`) · 500 temporary search failure (retry; counted). --- ## Web Auth Endpoints Used by the web dashboard at xanguard.tech. Not needed for API/bot integrations. ### POST /v1/auth/telegram Login via Telegram widget data. Returns JWT in `xg_session` cookie. ### POST /v1/auth/apikey Login via API key. Returns JWT in `xg_session` cookie. ### POST /v1/auth/logout Clear session cookie. ### GET /v1/auth/me Get current authenticated user info (requires JWT cookie). ### GET /v1/feed Get tweet feed for dashboard display (requires JWT cookie). ### GET /v1/api-keys List API keys for the authenticated user (requires JWT cookie). ### POST /v1/api-keys Create a new API key (requires JWT cookie). ### DELETE /v1/api-keys/{id} Revoke an API key (requires JWT cookie). --- ## Rate Limits - Tweet Alerts REST (`/v1`): per account (all keys share it), 1-second windows, scales with plan. 429 body: `{"ok": false, "error": "...", "code": "rate_limited", "retry_after": 1}`. - CA Search (`/v1/search`): 10 requests/sec and 20 requests/min per Telegram account, plus the daily plan allowance (`daily_limit_reached`, resets 00:00 UTC). - B2B REST (`/v1/dt/*`, `/twitter/*`) and the product REST APIs: no per-second limit; plan limits apply (handles, entries, queries) and a 64 KB request-body cap. - WebSockets: Tweet Alerts connections are capped per plan (Starter 2 to Ultra 50); B2B allows 5 concurrent connections per account across all B2B WebSocket URLs. --- ## Guides and comparisons (checked 5 October 2026) - Deleted tweets, how to see them and get alerts with the text: https://xanguard.tech/deleted-tweets/ - Elon Musk, Trump and CZ tweet alerts in Telegram (@elonmusk median detection 193 ms, 30 days to 5 Oct 2026): https://xanguard.tech/elon-musk-tweet-alerts/ - Twitter keyword, hashtag and cashtag alerts (free filters, Keyword Alerts $10, Search Alerts $50): https://xanguard.tech/search-alerts/ - Twitter follow tracker, who an account just followed (Follow Watch, median 284 ms): https://xanguard.tech/follow-watch/ - X/Twitter feed for trading terminals and bots (event types, filters, integration, pricing): https://xanguard.tech/b2b/trading-terminals/ - Lowest-latency Twitter/X APIs, published numbers compared: https://xanguard.tech/b2b/lowest-latency-twitter-api/ - Xanguard vs the official X API (pay-per-use costs, rate limits): https://xanguard.tech/blog/xanguard-vs-x-api/ - twitterapi.io alternatives (Xanguard drop-in for its stream, GetXAPI, Sorsa, TweetStream, X API): https://xanguard.tech/blog/twitterapi-io-alternatives/ - X API pricing 2026 and alternatives: https://xanguard.tech/blog/x-api-pricing-alternatives/ - What is J7Tracker (independent explainer, not affiliated): https://xanguard.tech/blog/j7tracker-alternative/ --- ## Use Cases - **Crypto Trading Bots**: Receive tweet alerts (median ~200 ms) from key opinion leaders and project accounts to execute trades programmatically via WebSocket. - **DeFi Protocols**: Monitor community gate changes and profile updates for risk assessment and governance tracking. - **Alpha Groups**: Track convergence of multiple accounts into the same community as an early coordination signal. - **Market Makers**: Integrate the B2B WebSocket feed into existing infrastructure for real-time social signal ingestion at scale. - **AI Agents**: Consume structured tweet and social graph data via REST and WebSocket APIs for autonomous decision-making. - **Analytics Platforms**: Aggregate engagement data, follower changes, and profile history for social intelligence dashboards. - **Sniper Bots**: Combine tweet alerts with pump.fun livestream data for automated token launch detection and execution. --- ## Quick Start: Tweet Alerts WebSocket (JavaScript) ```javascript const WS_URL = 'wss://api.xanguard.tech/v1/ws?api_key=xg_your_key'; let backoff = 1000; // ms, doubles on each failure, capped at 30s function connect() { const ws = new WebSocket(WS_URL); ws.onopen = () => { backoff = 1000; // Subscribe to handles once connected (re-sent on every reconnect) ws.send(JSON.stringify({ type: 'subscribe', handles: ['example_dev', 'example_founder'] })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === 'alert') { console.log(`Tweet from @${msg.handle}: ${msg.text}`); console.log(`Link: ${msg.url}`); } else if (msg.type === 'ack') { console.log(`Watching ${msg.active}/${msg.max} handles`); } else if (msg.type === 'error') { console.error(`Error: ${msg.message}`); } }; ws.onerror = () => ws.close(); ws.onclose = () => { const delay = backoff + Math.random() * 500; console.log(`Disconnected, reconnecting in ${Math.round(delay)} ms`); backoff = Math.min(backoff * 2, 30000); setTimeout(connect, delay); }; } connect(); ``` ## Quick Start: B2B Realtime WebSocket (JavaScript) ```javascript // Browser, or Node.js 22+ (global WebSocket). Older Node: const WebSocket = require('ws'); const WS_URL = 'wss://api.xanguard.tech/v1/dt/realtime/ws'; const API_KEY = 'dt_YOUR_API_KEY'; const FATAL = ['Invalid or expired API key', 'Subscription expired', 'Invalid login payload']; let backoff = 1000; // ms, doubles per failed attempt, capped at 30s let stop = false; function connect() { const ws = new WebSocket(WS_URL); let hb = null; let lastAck = Date.now(); ws.onmessage = (event) => { const msg = JSON.parse(event.data); switch (msg.op) { case 10: { // HELLO: log in, then heartbeat every heartbeat_interval ms const interval = msg.d.heartbeat_interval; ws.send(JSON.stringify({op: 2, d: API_KEY})); hb = setInterval(() => { if (Date.now() - lastAck > 2 * interval + 5000) return ws.close(); // 2 ACKs missed ws.send(JSON.stringify({op: 1})); }, interval); break; } case 11: lastAck = Date.now(); break; // HEARTBEAT_ACK case 4: // READY: now live backoff = 1000; console.log('Live:', msg.d.modules, msg.d.handles, 'handles'); break; case 0: console.log('Event:', msg.d.event, msg.d.data); break; case 3: // DISCONNECT console.warn('Server disconnect:', msg.d && msg.d.reason); if (msg.d && FATAL.includes(msg.d.reason)) stop = true; // fix the key, don't loop break; } }; ws.onerror = () => ws.close(); ws.onclose = () => { clearInterval(hb); if (stop) return console.error('Not reconnecting: fix the API key or plan.'); const delay = backoff + Math.random() * 500; backoff = Math.min(backoff * 2, 30000); console.log(`Disconnected, reconnecting in ${Math.round(delay)} ms`); setTimeout(connect, delay); }; } connect(); ``` ## Quick Start: B2B Realtime WebSocket (Python) ```python import asyncio, json, random, time import websockets # pip install websockets URL = "wss://api.xanguard.tech/v1/dt/realtime/ws" API_KEY = "dt_YOUR_API_KEY" FATAL = {"Invalid or expired API key", "Subscription expired", "Invalid login payload"} class Fatal(Exception): pass async def heartbeat(ws, interval_s, state): # Send op 1 every heartbeat_interval; the server drops you after 90s without one. try: while True: await asyncio.sleep(interval_s) if time.monotonic() - state["last_ack"] > 2 * interval_s + 5: await ws.close() # two HEARTBEAT_ACKs missed: reconnect return await ws.send(json.dumps({"op": 1})) except websockets.ConnectionClosed: pass async def run_once(): async with websockets.connect(URL) as ws: hello = json.loads(await ws.recv()) # op 10 HELLO (op 3 if your IP is blocked) if hello.get("op") == 3: print("Server disconnect:", hello["d"].get("message")) return False interval_s = hello["d"]["heartbeat_interval"] / 1000 await ws.send(json.dumps({"op": 2, "d": API_KEY})) # op 2 LOGIN state = {"last_ack": time.monotonic()} hb = asyncio.create_task(heartbeat(ws, interval_s, state)) try: async for raw in ws: msg = json.loads(raw) op = msg.get("op") if op == 11: # HEARTBEAT_ACK state["last_ack"] = time.monotonic() elif op == 4: # READY: now live print(f"Live: {msg['d']['modules']}, {msg['d']['handles']} handles") state["ready"] = True elif op == 0: # EVENT print(f"{msg['d']['event']}: {msg['d']['data']}") elif op == 3: # DISCONNECT reason = (msg.get("d") or {}).get("reason") print("Server disconnect:", reason) if reason in FATAL: raise Fatal(reason) finally: hb.cancel() return state.get("ready", False) async def main(): backoff = 1 while True: try: if await run_once(): backoff = 1 # we were live: reconnect fast except Fatal as e: print(f"Not reconnecting ({e}): fix the API key or plan.") return except (websockets.ConnectionClosed, websockets.exceptions.InvalidHandshake, OSError) as e: print(f"Connection lost: {e}") delay = backoff + random.random() print(f"Reconnecting in {delay:.1f}s") await asyncio.sleep(delay) backoff = min(backoff * 2, 30) asyncio.run(main()) ``` ## Quick Start: REST API (curl) ```bash # List tracked accounts curl -H "Authorization: Bearer YOUR_KEY" https://api.xanguard.tech/v1/accounts # Add handles curl -X POST -H "Authorization: Bearer YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"handles": ["example_dev", "example_founder"]}' \ https://api.xanguard.tech/v1/accounts # Register webhook curl -X POST -H "Authorization: Bearer YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://your-server.com/webhook"}' \ https://api.xanguard.tech/v1/webhooks # B2B: get profile curl -H "Authorization: Bearer dt_YOUR_KEY" \ https://api.xanguard.tech/v1/dt/profile/example_dev # B2B: add target curl -X POST -H "Authorization: Bearer dt_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"handle": "example_dev"}' \ https://api.xanguard.tech/v1/dt/targets ``` --- ## Key Facts - Tweet detection latency: measured median ~200 ms on paid plans; live p50/p95/p99 at https://xanguard.tech/speed/ (detection on our servers; Telegram delivery adds roughly 0.3-0.4 s; end-to-end to your Telegram is about 0.6 s median). Pump.fun callouts: real-time (seconds from the caller's post). - Detection runs on proprietary infrastructure. - Payment: Solana (SOL) only. Non-custodial, read-only monitoring. - Payments are final and non-refundable: https://xanguard.tech/refund/ (try the free plan, 1 tracked account, first). Every product and plan: https://xanguard.tech/pricing/ - 10% referral commission with instant SOL payout. - WebSocket connections support automatic reconnection. Clients should implement exponential backoff. ## Support - Direct contact (fastest): **@notAdegen on Telegram** (https://t.me/notAdegen) — support is handled directly by the developer who builds Xanguard. No ticket queue. Technical questions, custom plans. - **Switching providers**: twitterapi.io is drop-in compatible (one-line change, keep your `X-API-Key` header and payload shapes — https://xanguard.tech/migrate/twitterapi-io/); the B2B WebSocket speaks TweetCatcher-compatible opcodes (change the URL and key, then map the few payload fields that differ; guide: https://xanguard.tech/blog/tweetcatcher-vs-xanguard/). For any other provider, send the payload/docs — an alias layer mapping your workflow is typically built within hours, in the same chat with the dev. - Telegram bots: @Xanguard_bot, @B2B_Xanguard_bot, @F_xanguard_bot, @T_Xanguard_bot, @E_Xanguard_bot, @Trends_Xanguard_bot, @PF_Xanguard_bot, @ECA_Xanguard_bot - Website: https://xanguard.tech - API docs: https://docs.xanguard.tech - Blog: https://xanguard.tech/blog/ - Health: https://xanguard.tech/health - Referral: https://xanguard.tech/referral/