FOLLOW AND UNFOLLOW
Twitter Follow API: Follow and Unfollow for $0.0008
Updated July 2026
Can you follow a user through the Twitter API?
Yes. POST /twitter/user/follow follows an account from the X account you registered, and POST /twitter/user/unfollow reverses it. Each call takes a user ID or a handle and costs $0.0008. X removed follows from its self-serve API tiers in April 2026, so this is one of the few pay-as-you-go routes left for the action.
Flat $0.0008 per call, the same rate as a read. Registering the X session is free.
Per our own API records, 125 endpoints share this one Bearer key and one prepaid balance. Start with the quickstart, compare every price, or connect an agent through the MCP server.
By the numbers
Where the follow action stands in 2026
The official route changed this year, which is why this page exists.
X removed following, likes and quote-posts via API writes from all self-serve tiers, effective April 20, 2026. (X Developer Community, 2026)
A follow or an unfollow on TwitterAPIs bills $0.0008, which is $0.80 per 1,000 actions. (TwitterAPIs pricing, 2026)
The relationship check reads both directions plus block, mute and DM flags in one response. (TwitterAPIs API reference, 2026)
Per our billing data, paying customers made 484,424 tweet-returning read calls over October 22 to 28, 2026 (UTC), on the same keys and the same per-call billing as this endpoint. (TwitterAPIs measured yield, 2026)
The three endpoints behind the Twitter follow API
Two writes and one read make up the full loop: check, act, confirm. All three accept handles as well as numeric IDs, so you do not need a lookup step first. Handles are resolved for you, and the optional proxy parameter on the writes lets you send the action through an IP you control.
POST /twitter/user/follow
Follow a user as the authenticated account. Requires a logged-in session for the acting account. Billed at $0.0008 per call, the same as a standard read.
| Parameter | Where | Required | Purpose |
|---|---|---|---|
| user_id | query | No | Numeric ID of the user to follow. Send this or username; user_id wins when both are present. |
| username | query | No | Handle of the user to follow, with or without the leading @. Resolved to its numeric ID for you through the same cached lookup as Check Follow Relationship; an unknown handle returns 404 and no follow is issued. |
| proxy | query | No | Optional. Pass your own proxy (http(s)/socks URL) to egress the write through your clean IP for best success; if omitted, we use the session's proxy / our default. |
POST /twitter/user/unfollow
Unfollow a user as the authenticated account. Requires a logged-in session for the acting account. Billed at $0.0008 per call, the same as a standard read.
| Parameter | Where | Required | Purpose |
|---|---|---|---|
| user_id | query | No | Numeric ID of the user to unfollow. Send this or username; user_id wins when both are present. |
| username | query | No | Handle of the user to unfollow, with or without the leading @. Resolved to its numeric ID for you through the same cached lookup as Check Follow Relationship; an unknown handle returns 404 and no unfollow is issued. |
| proxy | query | No | Optional. Pass your own proxy (http(s)/socks URL) to egress the write through your clean IP for best success; if omitted, we use the session's proxy / our default. |
GET /twitter/user/check_follow_relationship
Return the directional relationship between a source and target user: whether source follows target (following) and target follows source (followed_by), plus block, mute, and DM-eligibility flags. An account that does not exist returns a 404 with error not_found; the relationship object is null when X returns none.
| Parameter | Where | Required | Purpose |
|---|---|---|---|
| source_user_id | query | No | Numeric ID of the account whose following is checked. Send this or source_username. |
| source_username | query | No | Handle of the source account, as an alternative to source_user_id. Resolved to its ID first; an unknown handle returns a 404 and nothing is billed. |
| target_user_id | query | No | Numeric ID of the account being checked against. Send this or target_username. |
| target_username | query | No | Handle of the target account, as an alternative to target_user_id. Resolved to its ID first; an unknown handle returns a 404 and nothing is billed. |
Sample responses from the follow endpoints
The writes answer with a single ok field, so the informative response is the relationship check. It is directional, which trips people up: following means the source follows the target, and followed_by means the target follows the source. Read both before you decide what to do.
{
"ok": true
}{
"ok": true
}{
"relationship": {
"source_id": "745273",
"target_id": "2178758961",
"following": true,
"followed_by": false,
"blocking": null,
"blocked_by": null,
"muting": null,
"can_dm": true
}
}| Field | What it tells you |
|---|---|
| ok | True when X accepted the follow or unfollow. |
| relationship.following | The source account follows the target. |
| relationship.followed_by | The target account follows the source, which is what a follow-back check needs. |
| relationship.blocking | The source has blocked the target. Null means X did not report it for this pair. |
| relationship.muting | The source has muted the target. |
| relationship.can_dm | Whether the source can send the target a direct message right now. |
Quickstart: follow an account from code
A follow has to come from a real account, so a write needs the one-time session step. Reads do not, which means the relationship check works on a key alone. Once the session is stored, the call below is the whole integration.
- Create a key at signup.
- Register the acting account with
POST /twitter/customer/session, sending itsauth_tokenandct0. This is free and only happens once per account. - Send the request below with
usernameset to the handle you want to follow. - Call
GET /twitter/user/check_follow_relationshipif you want to confirm the result.
curl -X POST "https://api.twitterapis.com/twitter/user/follow?user_id=44196397" \
-H "Authorization: Bearer $TWITTERAPIS_KEY"
# Add &proxy=http://user:pass@host:port to route through your own clean IP.import os
import requests
resp = requests.post(
"https://api.twitterapis.com/twitter/user/follow",
headers={"Authorization": f"Bearer {os.environ['TWITTERAPIS_KEY']}"},
params={ "user_id": "44196397" }, # add "proxy": "http://user:pass@host:port" to use your own IP
)
resp.raise_for_status()
data = resp.json()
print(data)const url = new URL("https://api.twitterapis.com/twitter/user/follow");
url.search = new URLSearchParams({ "user_id": "44196397" }).toString();
// Add proxy: "http://user:pass@host:port" above to route through your own clean IP.
const resp = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.TWITTERAPIS_KEY}` },
});
const data = await resp.json();
console.log(data);What the follow endpoints cost per 1,000
Every action here is one call that does one thing, so the fill is exactly 1 and the arithmetic is simple. The relationship check bills like a read, and the batch version bills per pair, so a 100-target sweep costs the same as 100 single checks with fewer round trips.
| Action | Per call | Per 1,000 |
|---|---|---|
| Follow an account | $0.0008 | $0.80 |
| Unfollow an account | $0.0008 | $0.80 |
| Check one relationship | $0.0008 | $0.80 |
| Check, then follow | $0.0016 | $1.60 |
An unknown handle returns a 404 and no follow is issued. The signup credit of $0.50 covers 625 calls. See all endpoint prices.
Follow automation options compared
Follow automation sits in an awkward spot, because the first-party route closed to most budgets and the rest of the market varies a lot. These are the routes teams use today, compared on whether the action is available at all and what each one asks you to run.
| Option | Follow action | Cost | What you run |
|---|---|---|---|
| TwitterAPIs | Available | $0.0008 per call | A key plus one registered session |
| Official X API, self-serve | Removed April 20, 2026 | No self-serve price | Not available on these tiers |
| Official X API, enterprise | By contract | Negotiated | A sales process |
| Browser automation | Available | Proxy and compute costs | A browser per account and selectors that change |
What changed on the official API in 2026
In the announcement covering changes effective April 20, 2026, X withdrew following, likes and quote-posts via API writes from every self-serve tier. These actions were not repriced upward, they were removed, so there is no line item to budget for on those plans. Any guide still quoting a per-request cost for an API follow is describing something that no longer exists.
That matters most for products built on the old POST /2/users/:id/following call, such as community tools that follow new members back. Those integrations stopped working without a code change on their side. Our X API pricing breakdown covers the rest of that announcement, and the Twitter engagement API handles the like and repost side of the same gap.
Reading a relationship before you act
A check before each write keeps your data honest and saves you sending actions that do nothing. If you only need the answer for a few accounts, the free follow checker gives it to you in a browser, and our answer on checking whether one account follows another explains the response in more detail.
For volume, GET /twitter/user/check_follow_relationship/batch compares one account against up to 100 others in a single request. That is how you find who has not followed back across a whole list without making 100 round trips. To get the list itself, use the Twitter followers API, which pages through follower and following lists.
- Follow-back checks. Read
followed_byfor each account you follow, then decide who to keep. - Partner verification. Confirm a campaign partner follows the account they said they would.
- DM eligibility. Read
can_dmbefore you queue a message, so a send does not fail later.
Using follow automation without losing the account
An API call does not change what X allows. Following on behalf of an account a real person controls is ordinary use, and aggressive follow and unfollow cycling is exactly the pattern X's automation rules target, whichever tool sent it. X enforces daily follow limits on every account, and a new account will hit them sooner than an established one.
Pace actions the way a person would, spread them through the day, and stop on a 403 or a 429 instead of retrying in a tight loop. A 403 from X usually means the account or session has a problem, and hammering it makes that worse. Check the session with GET /twitter/customer/session/status before you resume.
A follow-back job in a few lines
The example below shows the check-then-act pattern with real parameter names. It reads the relationship between your account and each candidate, follows only the accounts that already follow you and that you do not follow yet, and waits between writes. The check is a read that uses your key alone, while the follow runs as the session you registered.
Keep the list short and the wait long. A job like this is meant to run a few times a day on a handful of accounts, not to sweep thousands of handles in a loop. To get the candidates in the first place, read your newest followers with the Twitter followers API, and use the guide to who an account follows for the other direction.
import os
import time
import requests
BASE = "https://api.twitterapis.com/twitter/user"
HEADERS = {"Authorization": f"Bearer {os.environ['TWITTERAPIS_KEY']}"}
me = "your_handle"
candidates = ["naval", "openai"]
for handle in candidates:
check = requests.get(
f"{BASE}/check_follow_relationship",
headers=HEADERS,
params={"source_username": me, "target_username": handle},
timeout=30,
)
check.raise_for_status()
relationship = check.json()["relationship"]
if relationship and relationship["followed_by"] and not relationship["following"]:
follow = requests.post(
f"{BASE}/follow",
headers=HEADERS,
params={"username": handle},
timeout=30,
)
follow.raise_for_status()
time.sleep(60)Moving off POST /2/users/:id/following
If your product called the first-party route, the move is mostly a matter of auth. There is no OAuth 2.0 user token and no refresh cycle to keep alive. You register the account's session once, then call one URL with your Bearer key. The target can be a handle as well as an ID, which removes the lookup step many integrations carried only to satisfy the old path.
The response is simpler too. You get ok rather than a following and pending_follow pair, so read the relationship check if your logic depends on whether a request to a protected account is pending. Run the two paths side by side on one account first, and compare the results before you switch everything over. The API alternatives comparison covers other vendors if you want to weigh more than one route.
- Auth. Replace the user token with a Bearer key plus a registered session. The API key page covers the key, and our answer on logging in to X with an API covers the session options.
- Identifiers. Send
user_idto keep your stored IDs working, orusernameto drop your lookup call. The user API resolves one to the other if you need it elsewhere. - Several accounts. One key can act for many accounts, and our answer on multiple X accounts shows how to pass the session on each call.
- Knowing who followed you. Follow events are a read problem, covered by the account activity API page.
Follow accounts from an AI agent
All three actions are tools in the MCP server, so an agent can check a relationship and act on it on the account you registered. Keep a person in the loop for writes, since the follow happens as soon as the tool runs. The MCP page has the client setup.
twitter_follow_usercalls POST /twitter/user/followtwitter_unfollow_usercalls POST /twitter/user/unfollowtwitter_check_follow_relationshipcalls GET /twitter/user/check_follow_relationship
npx -y @twitterapis/mcp@latestTwitter follow API questions
On TwitterAPIs, yes: POST /twitter/user/follow costs $0.0008 and runs on the X account you registered. On the official X API, following via API writes was removed from all self-serve tiers effective April 20, 2026.
Send POST /twitter/user/unfollow with the same user_id or username parameters. It costs $0.0008, the same as a follow.
For the writes, yes: a follow has to come from an account, so you register that account's session once. The relationship check is a read and needs only your Bearer key.
Yes. GET /twitter/user/check_follow_relationship/batch compares one account against up to 100 others in one request, billed per pair.
Pass username with or without the leading @. The handle is resolved to its numeric ID for you. If you send both, user_id wins. An unknown handle returns a 404 and no follow is issued.
Call GET /twitter/user/check_follow_relationship with a source and a target. following tells you whether the source follows the target, and followed_by tells you the reverse. It works on a key alone with no session.
It is optional. Pass your own http, https or socks URL to send the write through an IP you control. If you leave it out, the session's proxy or our default is used.
It can if you follow and unfollow aggressively. X enforces daily follow limits and rules against bulk cycling regardless of the tool. Pace actions like a person would, and stop on a 403 or a 429.
Send your first follow from code
Create a key, register one X session for free and make the call. The signup credit covers 625 follow calls.
Next read
Continue exploring related pages:
Twitter API use cases
14 use cases from sentiment analysis to lead generation.
Twitter API answers
Short, sourced answers to the most common Twitter and X API questions.
Twitter timeline API
Pull an account's full posting history over one REST endpoint.
Twitter list API
Read list members and list timelines with the same Bearer key.