twitterapi.io is an independent third-party service. Not affiliated with X Corp.

Blogmass unfollow twitter

Mass Unfollow on Twitter (X) — A Developer's API Tutorial

By Alex Chen4 min read

Mass-unfollow workflows on Twitter (X) come up for several legitimate reasons — pruning a follower list down to a curated set, removing inactive accounts after years of following, cleaning up post-acquisition account migrations. The 'mass' in 'mass unfollow' just means programmatic + batched; the actual per-account unfollow is a single API call per target.

This guide walks the API workflow with runnable Python, the rate-limit + safe-pacing patterns, and the practical operational issues (followers-list iteration, dedup, dry-run mode). Note: twitterapi.io is read-only and does not offer write endpoints; mass-unfollow is X official path only.

01 — Section

Why this needs the official X API

Unfollowing requires write access against the account owner's identity. The call acts AS the owner — you can only unfollow accounts that you (the authenticated user) follow.

twitterapi.io is a read-only third-party path; it doesn't offer write endpoints by design. For any mass-unfollow workflow you'll use X official with OAuth user-context auth.

Pricing per docs.x.com/x-api/getting-started/pricing: $0.010 per write request (including unfollow). Cost for unfollowing 1,000 accounts: 1,000 × $0.010 = $10. Math derived directly from the cited rate.

02 — Section

Step 1 — list the accounts you currently follow

Before unfollowing, get the current following list. X official: /2/users/{id}/following, returns followers up to 1,000 per page with cursor pagination.

Pricing per docs.x.com pricing: $0.010 per follower-list read (counts as a read of following). For a 5,000-follow list, that's 5 paginated calls × $0.010 = $0.05.

python
# pip install tweepy
import tweepy

client = tweepy.Client(
    consumer_key="YOUR_KEY",
    consumer_secret="YOUR_SECRET",
    access_token="USER_TOKEN",
    access_token_secret="USER_TOKEN_SECRET",
)

def get_following(user_id: str) -> list:
    """Page through the entire following list."""
    all_following = []
    for page in tweepy.Paginator(
        client.get_users_following,
        id=user_id,
        max_results=1000,
    ):
        all_following.extend(page.data or [])
    return all_following

following = get_following("YOUR_USER_ID")
print(f"Currently following {len(following)} accounts")
03 — Section

Step 2 — filter to the unfollow targets

Most mass-unfollow workflows filter by some criterion before issuing the deletes:

- Inactive accounts — fetch each followed account's created_at and last-tweet timestamp; unfollow if no posts in N days

- No engagement back — find accounts you follow that don't follow you back (asymmetric relationship)

- Below threshold — accounts under N followers, accounts that posted in a banned topic, accounts on a blocklist

- Explicit list — you have a CSV of usernames to drop, just resolve each to user_id

Build the target list client-side from the previous step's result + your filter criterion. This is also a good place to add a dry-run mode that prints what would be unfollowed without actually issuing the deletes.

04 — Section

Step 3 — execute the unfollows with rate-limit safety

X publishes rate limits in its docs (separate from per-call price). The unfollow endpoint has its own rate limit; consult docs.x.com for current numbers.

Safe pacing: 1 unfollow per second is a conservative baseline that fits comfortably under most rate limits. Faster bursting risks 429 and (rarely) account-level review.

Backoff on 429: when the API returns 429 Too Many Requests, sleep for the Retry-After header value plus jitter (1-5 seconds random). Don't retry tightly.

Don't unfollow during normal X UI activity: if you're using your account normally at the same time as the script, the combined activity can trip limits faster. Run the script during quiet hours.

python
import time, random

DRY_RUN = False  # flip to False when ready

def mass_unfollow(targets: list, my_user_id: str):
    success, fail = [], []
    for target_id in targets:
        if DRY_RUN:
            print(f"[dry-run] would unfollow {target_id}")
            continue
        try:
            client.unfollow_user(target_user_id=target_id)
            success.append(target_id)
        except tweepy.TooManyRequests:
            print("429 — sleeping 60s + jitter")
            time.sleep(60 + random.uniform(0, 5))
        except Exception as e:
            fail.append((target_id, str(e)))
        time.sleep(1.0 + random.uniform(0.1, 0.5))  # safe pacing: ~1 unfollow/sec
    return success, fail

# success, fail = mass_unfollow(target_ids, "YOUR_USER_ID")
# print(f"unfollowed {len(success)}, errors {len(fail)}")
05 — Section

Side-by-side comparison — 3 paths to mass unfollow

Same job (unfollow N accounts) framed across three options. Costs derived from cited pricing.

DimensionX official APITweepy wrapper (same path)UI dashboard tool
Per-unfollow cost$0.010 (docs.x.com)$0.010 (same surface)bundled in tier
AuthOAuth user-contextOAuth user-contextUI login
Programmaticyesyes (ergonomic wrapper)no (manual or scheduled-batch)
Best forcustom filter logic + large volumequick-start, smaller volumesnon-dev users

Two patterns: (a) the API path is the only programmatic option — twitterapi.io being read-only means dashboard tools or the X official path are your two choices; (b) at any meaningful volume (100+ accounts), the programmatic path is materially faster + cheaper than UI clicking.

06 — Section

Operational notes — suspension risk + reversibility

Suspension risk: very aggressive unfollow patterns can trigger X's anti-spam systems. Don't unfollow >1,000 accounts in a single hour; spread across multiple days for large lists. The risk is low for small workflows; non-zero for very-large ones.

Reversibility: an unfollow is reversible — you can refollow the account if you change your mind. There's no soft-delete window; the unfollow is immediate.

Audit trail: log every unfollow with timestamp + reason (filter criterion). Useful if you need to refollow later or audit the workflow.

Communication: if you're cleaning up a brand account's following list, consider sending a one-time tweet explaining the cleanup — some followers feel slighted by silent unfollows and the explanation softens that.

07 — Section

Cost framing — 100 / 1,000 / 10,000 unfollows

Math from docs.x.com/x-api/getting-started/pricing at $0.010 per write request:

- 100 unfollows = $1.00 — single-script run, no concern

- 1,000 unfollows = $10.00 — split across 2-3 days for safety

- 10,000 unfollows = $100.00 — split across 7-14 days, monitor for 429s and account warnings

Plus the cost of reading the current following list to find targets — at 1,000 entries per page × $0.010 = $0.01 per 1,000 followers listed. For a 10,000-follow account that's $0.10 to list, $100 to mass-unfollow.

python
# Practical example: end-to-end mass unfollow with dry-run, safe pacing, audit log.
import os, time, random, json
from datetime import datetime, timezone
import tweepy

client = tweepy.Client(
    consumer_key=os.environ["X_CONSUMER_KEY"],
    consumer_secret=os.environ["X_CONSUMER_SECRET"],
    access_token=os.environ["X_USER_TOKEN"],
    access_token_secret=os.environ["X_USER_SECRET"],
)

MY_USER_ID = os.environ["X_MY_USER_ID"]
DRY_RUN = True  # start safe

def get_following():
    return [u for page in tweepy.Paginator(
                client.get_users_following, id=MY_USER_ID, max_results=1000)
            for u in (page.data or [])]

def filter_targets(following):
    # Replace with your real filter — example: inactive (none tweeted in 90d)
    return [u for u in following if False]  # placeholder

def mass_unfollow(targets):
    log_path = f"unfollow_log_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}.jsonl"
    success, fail = 0, []
    with open(log_path, "a") as log:
        for u in targets:
            entry = {"target_id": u.id, "username": u.username, "at": datetime.now(timezone.utc).isoformat()}
            if DRY_RUN:
                entry["action"] = "dry_run"
            else:
                try:
                    client.unfollow_user(target_user_id=u.id)
                    entry["action"] = "unfollowed"
                    success += 1
                except tweepy.TooManyRequests:
                    entry["action"] = "rate_limited"
                    log.write(json.dumps(entry) + "\n")
                    time.sleep(60 + random.uniform(0, 5))
                    continue
                except Exception as e:
                    entry["action"] = f"error: {e}"
                    fail.append(u)
            log.write(json.dumps(entry) + "\n")
            time.sleep(1.0 + random.uniform(0.1, 0.5))  # safe pacing
    return success, fail, log_path

following = get_following()
print(f"following: {len(following)}")
targets = filter_targets(following)
print(f"would unfollow: {len(targets)}")
if targets:
    s, f, p = mass_unfollow(targets)
    print(f"done: {s} succeeded, {len(f)} errors. Log: {p}")

# Cost framing (math from cited pricing):
#   1,000 unfollow targets = 1,000 × $0.010 = $10.00 (write)
#   + ~1 list page per 1,000 follows for the target-selection step = $0.01
# Total = $10.01 to mass-unfollow 1,000 accounts.
08 — Questions

Questions readers ask

Can I mass-unfollow via twitterapi.io?

No — twitterapi.io is a read-only third-party API. Write operations (unfollow, like, retweet, post create, etc.) require the X official surface with user-context auth. For mass unfollow, use X official.

How fast can I unfollow without getting suspended?

Conservative baseline is 1 unfollow per second, spread across hours not bursted. Most operational practice keeps under 1,000 unfollows per hour. The suspension risk is non-zero at very-high volume — split very-large lists across days.

Will the people I unfollow be notified?

No — X does not send notifications for unfollows. Some third-party tools surface 'unfollower notifications' to subscribers, so people running those tools may see; X itself does not notify.

Can I batch multiple unfollows in one API call?

No — the X unfollow endpoint is per-target. You issue N requests for N unfollows. Use sensible pacing + retry logic; don't try to parallel-burst many concurrent requests.

What if I unfollow an account I should have kept?

Just refollow. The unfollow is reversible. There's no soft-delete window; you can refollow immediately.

Are there X-rate limits on the read side (following-list pagination)?

Yes — /2/users/{id}/following has its own rate limit documented at docs.x.com. For a 10K-follow account that's 10 page reads, well under most rate-limit windows; no issue at typical mass-unfollow volumes.

09 — Further reading

Continue

Sources & further reading
More from this series
Build it

Stop reading. Start building.

Starter credits cover real testing on real data. Google sign-in, no card, no application queue.

Get an API key
    Mass Unfollow Twitter (X) — API Tutorial | TwitterAPI.io