Twitter (X) Bulk Unfollow + Follower Remover — API Guide
Bulk unfollow workflows are common for cleaning up inactive follows, culling low-signal accounts, or migrating between account curation strategies. 'Follower remover' has a different meaning — kicking someone off your follower list without them realizing — which X made harder post-2023.
This guide walks both intents (unfollow-mine vs remove-theirs), the exact endpoints, ToS-safe pacing patterns that avoid account suspension, and runnable Python with the block-then-unblock workaround for the follower-removal case.
Two intents — clarify which you mean
Unfollow (mine): I stop following account X. My following count −1, their follower count −1. They may or may not notice (depends on their app settings). Fully supported API endpoint on both twitterapi.io + X official.
Remove follower (theirs): account X currently follows me — I want them to no longer follow me, without them seeing an explicit 'you were unfollowed' notification. X removed the dedicated endpoint that did this cleanly post-2023.
Workaround for follower removal: temporary block, then immediate unblock. Blocking forces X to remove the follow relationship silently on both sides. Unblock preserves your future ability to interact.
Choose the endpoint / pattern based on which intent you actually have.
Runnable — unfollow (single + bulk)
Auth via session cookie (see /blog/twitter-api-python-complete-guide for auth flow). Pace at 3-5s per unfollow to stay comfortably below X's write thresholds.
import os, requests, time, random
BASE = "https://api.twitterapi.io"
SESSION_COOKIE = os.environ["TWITTERAPI_SESSION_COOKIE"]
def unfollow(user_name: str) -> dict:
r = requests.post(
f"{BASE}/twitter/unfollow",
cookies={"session": SESSION_COOKIE},
json={"userName": user_name},
timeout=15,
)
r.raise_for_status()
return r.json()
# Bulk unfollow with pacing
TO_UNFOLLOW = ["inactive_account_1", "inactive_account_2", "noisy_account_3"]
for handle in TO_UNFOLLOW:
try:
result = unfollow(handle)
print(f" unfollowed @{handle}")
except requests.RequestException as e:
print(f" ERROR @{handle}: {e}")
time.sleep(3 + random.uniform(1, 3)) # 3-6s pacing
# For 500+ unfollows, distribute across days — see 'daily cap' section belowFollower removal via block-unblock
Since X removed the dedicated 'remove follower' endpoint, the standard workaround is a quick block-then-unblock cycle:
import os, requests, time
BASE = "https://api.twitterapi.io"
SESSION_COOKIE = os.environ["TWITTERAPI_SESSION_COOKIE"]
def _post(path: str, payload: dict) -> dict:
r = requests.post(
f"{BASE}{path}",
cookies={"session": SESSION_COOKIE},
json=payload, timeout=15,
)
r.raise_for_status()
return r.json()
def remove_follower(handle: str) -> None:
_post("/twitter/block", {"userName": handle})
time.sleep(2) # let X propagate
_post("/twitter/unblock", {"userName": handle})
print(f" removed follower @{handle} via block+unblock")
# Practical: identify low-signal followers, remove
TO_REMOVE = ["spam_follower_1", "bot_follower_2"]
for h in TO_REMOVE:
remove_follower(h)
time.sleep(5) # pace between full block-unblock cyclesRate limits + daily caps
Per-request pacing: 3-5s between unfollows keeps you well below X's threshold. Faster is possible but risky.
Daily cap: X's account-level daily action limits (posts + follows + unfollows combined) are not publicly documented but community reports place safe daily unfollow volumes at ~200-400 per account. Above that, suspensions accelerate.
Distributed pattern: 5000 unfollow goal → spread across 15-25 days at 200/day + 5-8 hours-of-day window (not middle-of-night burst).
Multi-account: for higher throughput, distribute across multiple accounts (each with their own daily cap).
ToS-safe workflow patterns
Filter list carefully first: don't unfollow accounts you actually engage with. Pre-filter by: is_active (recent tweet within 90 days), followers_count > 100, is_verified.
Preserve mutual follows: check if a target follows you back before unfollowing. Losing mutual-follow relationships often triggers engagement drops.
Human-like cadence: 3-6s per action + variable timing + business-hours window. Not middle-of-night bursts.
Never combine with auto-follow same session: X's spam heuristics correlate follow + unfollow patterns. If you're actively following new accounts, run the unfollow separately in a different day.
Log every action: keep a local record of unfollows in case you need to reverse or audit later.
Alternative — X official /2/users/:id/following DELETE
Same intent via X's own OAuth 2.0 mutation endpoint: DELETE /2/users/:source_user_id/following/:target_user_id per docs.x.com/x-api/users/manage-follows.
Auth: OAuth 2.0 with follows.write scope. Full user-context auth flow.
Rate limit: 50 requests per 15 minutes per user for the mutation per docs.x.com/x-api/rate-limits (Basic tier), meaning ~200/hour = ~4800/day theoretical but X's account-level anti-spam heuristics still gate you far below that.
Wins when: already on X Developer Console for other workloads + want X-issued OAuth tokens. Loses when: you want simpler session-cookie auth for automation.
Comparison — 3 unfollow / removal paths
# Complete workflow: identify inactive follows → filter safely → bulk unfollow with pacing.
import os, requests, time, random, json
from datetime import datetime, timezone, timedelta
BASE = "https://api.twitterapi.io"
HEADERS_READ = {"X-API-Key": os.environ["TWITTERAPI_IO_KEY"]}
SESSION_COOKIE = os.environ["TWITTERAPI_SESSION_COOKIE"]
def list_my_following(my_handle: str) -> list:
following, cursor = [], None
for _ in range(200):
params = {"userName": my_handle, "count": 5000}
if cursor: params["cursor"] = cursor
r = requests.get(f"{BASE}/twitter/user/followings", headers=HEADERS_READ, params=params, timeout=30)
r.raise_for_status()
resp = r.json()
following.extend(resp.get("data", []))
cursor = resp.get("next_cursor")
if not cursor: break
return following
def is_inactive(user: dict, days: int = 90) -> bool:
last = user.get("last_tweet_at")
if not last: return False
dt = datetime.fromisoformat(last.replace("Z", "+00:00"))
return (datetime.now(timezone.utc) - dt) > timedelta(days=days)
def unfollow(user_name: str) -> None:
r = requests.post(f"{BASE}/twitter/unfollow",
cookies={"session": SESSION_COOKIE},
json={"userName": user_name}, timeout=15)
r.raise_for_status()
MY_HANDLE = os.environ["MY_HANDLE"]
DAILY_CAP = 150
following = list_my_following(MY_HANDLE)
print(f"currently following: {len(following)}")
inactive = [u for u in following if is_inactive(u, days=180) and not u.get("verified")]
print(f"inactive-180d unverified candidates: {len(inactive)}")
targets = inactive[:DAILY_CAP]
for u in targets:
handle = u.get("userName")
try:
unfollow(handle)
print(f" unfollowed @{handle}")
except Exception as e:
print(f" ERROR @{handle}: {e}")
time.sleep(4 + random.uniform(1, 4))
print(f"\nunfollowed {len(targets)} today, {len(inactive) - len(targets)} remaining for tomorrow")
# Log this batch to audit trail — see 'workflow patterns' sectionQuestions readers ask
Will the person I unfollow get notified?
By default X does NOT send an unfollow notification. But third-party tools + browser extensions can detect unfollows on their side by comparing follower snapshots. Assume the unfollow may be discovered if the target is monitoring.
What's the max unfollow per day safely?
Community consensus: ~200-400 per account per day, spread across business hours with 3-6s pacing. Bursts above 400/day materially increase suspension risk. For 5000+ unfollows, distribute across weeks.
Does unfollowing lose me their follow back?
Depends on the account. Many accounts follow back automatically — losing mutual triggers no automatic reaction. Manually curated follow-backs may notice and unfollow you in response. Check the target's follow-back pattern before if it matters.
Can I un-unfollow (re-follow) after unfollowing?
Yes — just call POST /twitter/follow (twitterapi.io) or POST /2/users/:id/following (X official) with the target userName. No cooldown on re-follows.
Is the block-unblock follower-removal workaround detectable?
The blocked-then-unblocked account can technically detect via their own follower-monitoring tools if they use them, since their following count changes silently. In practice most accounts don't monitor at that granularity, so the workaround is effectively invisible to typical users.
Does removing a follower affect my own follower count?
Yes — your follower count drops by 1 for each follower removed. The removed account's following count also drops by 1 on their side.
Can I bulk-remove followers, not just unfollow?
Yes, the block-unblock workaround scripts the same way as unfollow. Same rate-limit caveats + same daily-cap safety window.
Continue
- Twitter (X) API — cluster hub
- Mass unfollow Twitter (X) API tutorial
- Twitter (X) follower tracking API guide
- Twitter (X) follower count API tutorial
- Twitter (X) automation guide
- twitterapi.io pricing
Stop reading. Start building.
Starter credits cover real testing on real data. Google sign-in, no card, no application queue.
Get an API key