Introduction

We offer two sets of endpoint groups to help you lookup, create, and delete follow relationships: follows lookup and manage follows.  

Follows lookup

Only available to those with Enterprise access

The follows lookup endpoints enable you to explore and analyze relationships between users, which is sometimes called network analysis. Specifically, there are two REST endpoints that return user objects representing who a specified user is following, or who is following a specified user.

You can authenticate this endpoint with either OAuth 1.0a User Context, [App only](https://developer.twitter.com(/resources/fundamentals/authentication#app-only-authentication-and-oauth-2-0-bearer-token), or OAuth 2.0 Authorization Code with PKCE. You can request up to 1,000 users per request, and pagination tokens will be provided for paging through large sets of results.  

Manage follows

The manage follows endpoints enable you to follow or unfollow users.

Since you are making requests on behalf of a user, you must authenticate these endpoints with either OAuth 1.0a User Context or OAuth 2.0 Authorization Code with PKCE, and utilize the user Access Tokens associated with the user you are making the request on behalf of. You can generate this user Access Token using the 3-legged OAuth flow (OAuth 1.0a) or using the Authorization Code with PKCE grant flow) (OAuth 2.0).

You are limited to 400 follow actions per day on behalf of each authenticated user, and will be limited to 1,000 actions per day per App across all of your authenticated users. For example, if you have five authenticated users, you can follow 400 users per day (per user limit) with two of those users for a total of 800 actions, and will have to split the remaining 200 actions (per app) amongst the remaining three users. This limit does not apply to the unfollow endpoint, which has a separate limit of 500 actions per day (per app).

Account setup

To access these endpoints, you will need:

Learn more about getting access to the X API v2 endpoints in our getting started guide.

Getting started with the manage follows endpoints

This quick start guide will help you make your first request to the manage follows endpoints using Postman.

If you would like to see sample code in different languages, please visit our X API v2 sample code GitHub repository. 

Prerequisites

To complete this guide, you will need to have a set of keys and tokens to authenticate your request. You can generate these keys and tokens by following these steps:

  • Sign up for a developer account and receive approval.
  • Create a Project and an associated developer App in the developer portal.
  • Navigate to your App’s “Keys and tokens” page to generate the required credentials. Make sure to save all credentials in a secure location.

Steps to build a manage follows request

Step one: Start with a tool or library

There are several different tools, code examples, and libraries that you can use to make a request to this endpoint, but we are going to use the Postman tool here to simplify the process.

To load the X API v2 Postman collection into your environment, please click on the following button:

Once you have the X API v2 collection loaded in Postman, navigate to the “Follows” folder, and select “Follow a user ID”.  

Step two: Authenticate your request

To properly make a request to the X API, you need to verify that you have permission. To do so with this endpoint, you must authenticate your request using either OAuth 1.0a User Context or OAuth 2.0 Authorization Code with PKCE.

In this example, we are going to use OAuth 1.0a User Context.

You must add your keys and tokens – specifically your API Key, API Secret Key, OAuth 1.0a user Access Token, and OAuth 1.0a user Access Token Secret – to Postman. You can do this by selecting the environment named “X API v2” in the top-right corner of Postman and adding your keys and tokens to the “initial value” and “current value” fields (by clicking the eye icon next to the environment dropdown).

These variables will automatically be pulled into the request’s authorization tab if you’ve done this correctly.  

Step three: Specify who is going to follow whom

Manage follows endpoints take two IDs: one for the source user (the user who wishes to follow or unfollow another user) and the target user (the user that will be followed or unfollowed). The source user’s ID must correspond to the user ID of the authenticating user. In this case, you can specify the ID belonging to your own user. You can find your ID in two ways:

  1. Using the user lookup by username endpoint, you can pass a username and receive the id field. 
  2. Looking at your Access Token, you will find that the numeric part is your user ID.  

The target ID can be any valid user ID. For example the user ID for @XDevelopers is 2244994945.

In Postman, navigate to the “Params” tab, and enter your ID into the “Value” column of the id path variable. Navigate to the “Body” tab and and 2244994945 (the user ID for @XDevelopers) as the value for the target_user_id parameter. Making sure to not include any spaces before or after any ID.

KeyValue
id(your user ID)
target_user_id2244994945

If you click the “Send” button, you will receive a response object containing the status of the relationship:

  • If you receive a “following”: true, then the id is successfully following the target_user_id.
  • If you receive a “pending”: true, then the target_user_id is protected and must accept your follow request.

Step four: Make your request and review your response

Once you have everything set up, hit the “Send” button and you will receive the following response:

    "data": {
        "following": true,
        "pending_follow": false
    }
}

Similarly, if you were trying to unfollow a user, you would use the “Unfollow a user ID” request within the same Postman collection. However, both the source_user_id and target_user_id parameters should be passed as path variables using the unfollow endpoint. 

Comparing X API’s follows endpoints

Follows lookup

The v2 follows lookup endpoints will replace the standard v1.1 followers/ids, v1.1 followers/list, v1.1 friends/ids, and v1.1 friends/list endpoints.

The following tables compare the various types of follows lookup endpoints:

DescriptionStandard v1.1X API v2
HTTP methods supportedGETGET
Host domainhttps://api.x.comhttps://api.x.com
Endpoint path/1.1/friends/ids.json

/1.1/friends/list.json

/1.1/followers/ids.json

/1.1/followers/list.json
/2/users/:id/following

/2/users/:id/followers
AuthenticationOAuth 1.0a User Context

App only
OAuth 1.0a User Context

OAuth 2.0 Authorization Code with PKCE

App only
Default request rate limits15 requests per 15 min (per user)

15 requests per 15 min (per app)
15 requests per 15 min (per user)

15 requests per 15 min (per app)
Maximum users per responseGET friends/id & GET followers/id return a maximum of 5000 users IDs per page.



GET friends/list & GET followers/list return a maximum of 200 user objects per page.
1000 user objects per page
PaginationToken returns in a next_cursor field, which can then be passed as the value to the cursor parameter to return the next page of results.Token returns in a next_token field, which can then be passed as the value to the token parameter to return the next page of results.

The v2 payload also delivers a previous_token field, which can also be passed with the pagination_token parameter to return the previous page of results.
JSON formatStandard v1.1 formatX API v2 format (determined by fields and expansions request parameters, not backward-compatible with v1.1 formats)

To learn more about how to migrate from the Standard v1.1 format to the X API v2 format, please visit our data formats migration guide.
Supports selecting which fields return in the payload
Supports the Post annotations fields
Supports requesting new metrics fields
Supports the conversation_id field
Requires the use of credentials from a developer App associated with a project

Manage follows

The v2 manage follows endpoints will replace the standard v1.1 POST friendships/create and POST friendships/destroy endpoints.

The following tables compare the standard v1.1 and X API v2 create follow endpoints:

Follow a user

DescriptionStandard v1.1X API v2
HTTP methods supportedPOSTPOST
Host domainhttps://api.x.comhttps://api.x.com
Endpoint path/1.1/friendships/create.json/2/users/:id/following
AuthenticationOAuth 1.0a User ContextOAuth 1.0a User Context

OAuth 2.0 Authorization Code with PKCE
Default request rate limits50 requests per 15 min50 requests per 15 min
Maximum daily operations per users400400
Maximum daily operations per app10001000
Requires use of credentials from a developer App that is associated with a Project✔️

Unfollow a user

The following tables compare the standard v1.1 and X API v2 delete follow endpoints:

DescriptionStandard v1.1X API v2
HTTP methods supportedPOSTDELETE
Host domainhttps://api.x.comhttps://api.x.com
Endpoint path/1.1/friendships/destroy.json/2/users/:source_user_id/following/:target_user_id
AuthenticationOAuth 1.0a User ContextOAuth 1.0a User Context

OAuth 2.0 Authorization Code with PKCE
Default request rate limits15 requests per 15 min (per user)50 requests per 15 min (per user)
Maximum daily operations per appNone500
Requires use of credentials from a developer App that is associated with a Project✔️

Other migration resources

Follows lookup: Standard v1.1 to X API v2

Manage follows: Standard v1.1 to X API v2

X API migration hub

Manage follows: Standard v1.1 compared to X API v2

If you have been working with the standard v1.1 POST friendships/create and POST friendships/destroy endpoints, the goal of this guide is to help you understand the similarities and differences between the standard and X API v2 manage follows endpoints.

  • Similarities
    • OAuth 1.0a User Context
  • Differences
    • Endpoint URLs

    • App and Project requirements

    • HTTP methods

    • Request parameters

       

Similarities

OAuth 1.0a User Context authentication method

Both the endpoint versions support OAuth 1.0a User Context. Therefore, if you were previously using one of the standard v1.1 manage follows endpoints, you can continue using the same authentication method if you migrate to the X API v2 version. 

Differences

Endpoint URLs

App and Project requirements

The X API v2 endpoints require that you use credentials from a developer App that is associated to a Project when authenticating your requests. All X API v1.1 endpoints can use credentials from standalone Apps or Apps associated with a project.

Request parameters

The following standard v1.1 request parameters have equivalents in X API v2:

Standard v1.1X API v2
No equivalentid (POST), source_user_id (DELETE)
user_idtarget_user_id
screen_nameNo equivalent

Please note that the Standard v1.1 parameters are passed as query parameters, whereas the X API v2 parameters are passed as body parameters (for the POST endpoint) or path parameters (for the DELETE endpoint).

Also, the v2 id and source_user_id are not required when using the standard v1.1 endpoints since the Access Tokens passed with OAuth 1.0a User Context inferred which user was initiating the follow/unfollow. 

API reference index

For the complete API reference, select an endpoint from the list:

Manage follows

Allows a user ID to follow another user[POST /2/users/:id/following](/en/docs/twitter-api/users/follows/api-reference/post-users-source_user_id-following)
Allows a user ID to unfollow another user[DELETE /2/users/:source_user_id/following/:target_user_id](/en/docs/twitter-api/users/follows/api-reference/delete-users-source_id-following)

POST /2/users/:id/following

Allows a user ID to follow another user.

If the target user does not have public Tweets, this endpoint will send a follow request.

The request succeeds with no action when the authenticated user sends a request to a user they’re already following, or if they’re sending a follower request to a user that does not have public Tweets.

Endpoint URL

https://api.x.com/2/users/:id/following

Authentication and rate limits

Authentication methods
supported by this endpoint
OAuth 1.0a is also available for this endpoint.

OAuth 2.0 Authorization Code with PKCE
Rate limitUser rate limit (User context): 50 requests per 15-minute window per each authenticated user

OAuth 2.0 scopes required by this endpoint

tweet.read

users.read

follows.write
Learn more about OAuth 2.0 Authorization Code with PKCE

Path parameters

NameTypeDescription
id
 Required
stringThe authenticated user ID who you would like to initiate the follow on behalf of. You must pass the Access Tokens) that relate to this user when authenticating the request.

JSON body parameters

NameTypeDescription
target_user_id
 Required
stringThe user ID of the user that you would like the id to follow.

Example code with offical SDKs

(async () => {
  try {
    const followUser = await twitterClient.users.usersIdFollow(
      //The ID of the user that is requesting to follow the target user
      "6253282",
      {
        //The ID of the user that the source user is requesting to follow
        target_user_id: "2244994945",
      }
    );
    console.dir(followUser, {
      depth: null,
    });
  } catch (error) {
    console.log(error);
  }
})();

Example responses

{
  "data": {
    "following": true,
    "pending_follow": false
  }
}

Response fields

NameTypeDescription
followingbooleanIndicates whether the id is following the specified user as a result of this request. This value is false if the target user does not have public Tweets, as they will have to approve the follower request.
pending_followbooleanIndicates whether the target user will need to approve the follow request. Note that the authenticated user will follow the target user only when they approve the incoming follower request.

DELETE /2/users/:source_user_id/following/:target_user_id

Allows a user ID to unfollow another user.

The request succeeds with no action when the authenticated user sends a request to a user they’re not following or have already unfollowed.

Endpoint URL

https://api.x.com/2/users/:source_user_id/following/:target_user_id

Authentication and rate limits

Authentication methods
supported by this endpoint
OAuth 2.0 Authorization Code with PKCE

OAuth 1.0a is also available for this endpoint.
Rate limitUser rate limit (User context): 50 requests per 15-minute window per each authenticated user

OAuth 2.0 scopes required by this endpoint

tweet.read

users.read

follows.write
Learn more about OAuth 2.0 Authorization Code with PKCE

Path parameters

NameTypeDescription
source_user_id
 Required
stringThe user ID who you would like to initiate the unfollow on behalf of. You must pass the Access Tokens) that relate to this user when authenticating the request.
target_user_id
 Required
stringThe user ID of the user that you would like the source_user_id to unfollow.

Example code with offical SDKs

(async () => {
  try {
    const unfollowUser = await twitterClient.users.usersIdUnfollow(
      //The ID of the user that is requesting to unfollow the target user
      "2244994945",

      //The ID of the user that the source user is requesting to unfollow
      "6253282"
    );
    console.dir(unfollowUser, {
      depth: null,
    });
  } catch (error) {
    console.log(error);
  }
})();

Example responses

{
  "data": {
    "following": false
  }
}

Response fields

NameTypeDescription
followingbooleanIndicates whether the source_user_id is unfollowing the specified user as a result of this request. This value is false for a successful the unfollow request.

GET /2/users/:id/followers

Returns a list of users who are followers of the specified user ID.

Endpoint URL

https://api.x.com/2/users/:id/followers

Authentication and rate limits

Authentication methods
supported by this endpoint
OAuth 2.0 Authorization Code with PKCE

OAuth 1.0a is also available for this endpoint.

OAuth 2.0 App-only
Rate limitApp rate limit (Application-only): 15 requests per 15-minute window shared among all users of your app

User rate limit (User context): 15 requests per 15-minute window per each authenticated user

OAuth 2.0 scopes required by this endpoint

tweet.read

users.read

follows.read
Learn more about OAuth 2.0 Authorization Code with PKCE

Path parameters

NameTypeDescription
id
 Required
stringThe user ID whose followers you would like to retrieve.

Query parameters

NameTypeDescription
expansions
 Optional
enum (pinned_tweet_id)Expansions enable you to request additional data objects that relate to the originally returned users. The ID that represents the expanded data object will be included directly in the user data object, but the expanded object metadata will be returned within the includes response object, and will also include the ID so that you can match this data object to the original Tweet object. At this time, the only expansion available to endpoints that primarily return user objects is expansions=pinned_tweet_id. You will find the expanded Tweet data object living in the includes response object.
max_results
 Optional
integerThe maximum number of results to be returned per page. This can be a number between 1 and the 1000. By default, each page will return 100 results.
pagination_token
 Optional
stringUsed to request the next page of results if all results weren’t returned with the latest request, or to go back to the previous page of results. To return the next page, pass the next_token returned in your previous response. To go back one page, pass the previous_token returned in your previous response.
tweet.fields
 Optional
enum (attachments, author_id, context_annotations, conversation_id, created_at, edit_controls, entities, geo, id, in_reply_to_user_id, lang, non_public_metrics, public_metrics, organic_metrics, promoted_metrics, possibly_sensitive, referenced_tweets, reply_settings, source, text, withheld)This fields parameter enables you to select which specific Tweet fields will deliver in each returned pinned Tweet. Specify the desired fields in a comma-separated list without spaces between commas and fields. The Tweet fields will only return if the user has a pinned Tweet and if you’ve also included the expansions=pinned_tweet_id query parameter in your request. While the referenced Tweet ID will be located in the original Tweet object, you will find this ID and all additional Tweet fields in the includes data object.
user.fields
 Optional
enum (created_at, description, entities, id, location, most_recent_tweet_id, name, pinned_tweet_id, profile_image_url, protected, public_metrics, url, username, verified, verified_type, withheld)This fields parameter enables you to select which specific user fields will deliver with each returned users objects. Specify the desired fields in a comma-separated list without spaces between commas and fields. These specified user fields will display directly in the user data objects.

Example code with offical SDKs

(async () => {
  try {
    const getUsersFollowers = await twitterClient.users.usersIdFollowers(
      //The ID of the user for whom to return results
      "2244994945"
    );
    console.dir(getUsersFollowers, {
      depth: null,
    });
  } catch (error) {
    console.log(error);
  }
})();

Example responses

{
  "data": [
    {
      "id": "6253282",
      "name": "Twitter API",
      "username": "TwitterAPI"
    },
    {
      "id": "2244994945",
      "name": "Twitter Dev",
      "username": "TwitterDev"
    },
    {
      "id": "783214",
      "name": "Twitter",
      "username": "Twitter"
    },
    {
      "id": "95731075",
      "name": "Twitter Safety",
      "username": "TwitterSafety"
    },
    {
      "id": "3260518932",
      "name": "Twitter Moments",
      "username": "TwitterMoments"
    },
    {
      "id": "373471064",
      "name": "Twitter Music",
      "username": "TwitterMusic"
    },
    {
      "id": "791978718",
      "name": "Twitter Official Partner",
      "username": "OfficialPartner"
    },
    {
      "id": "17874544",
      "name": "Twitter Support",
      "username": "TwitterSupport"
    },
    {
      "id": "234489024",
      "name": "Twitter Comms",
      "username": "TwitterComms"
    },
    {
      "id": "1526228120",
      "name": "Twitter Data",
      "username": "TwitterData"
    }
  ],
  "meta": {
    "result_count": 10,
    "next_token": "DFEDBNRFT3MHCZZZ"
  }
}

Response fields

NameTypeDescription
id
 Default
stringUnique identifier of this user. This is returned as a string in order to avoid complications with languages and tools that cannot handle large integers.
name
 Default
stringThe friendly name of this user, as shown on their profile.
username
 Default
stringThe Twitter handle (screen name) of this user.
created_atdate (ISO 8601)Creation time of this account.

To return this field, add user.fields=created_at in the request’s query parameter.
most_recent_tweet_idstringThe ID of the User’s most recent Tweet

To return this field, add user.fields=most_recent_tweet_id in the request’s query parameter.
protectedbooleanIndicates if this user has chosen to protect their Tweets (in other words, if this user’s Tweets are private).

To return this field, add user.fields=protected in the request’s query parameter.
withheldobjectContains withholding details for withheld content.

To return this field, add user.fields=withheld in the request’s query parameter.
withheld.country_codesarrayProvides a list of countries where this user is not available.

To return this field, add user.fields=withheld.country_codes in the request’s query parameter.
withheld.scopeenum (tweet, user)Indicates whether the content being withheld is a Tweet or a user (this API will return user).

To return this field, add user.fields=withheld.scope in the request’s query parameter.
locationstringThe location specified in the user’s profile, if the user provided one. As this is a freeform value, it may not indicate a valid location, but it may be fuzzily evaluated when performing searches with location queries.

To return this field, add user.fields=location in the request’s query parameter.
urlstringThe URL specified in the user’s profile, if present.

To return this field, add user.fields=url in the request’s query parameter.
descriptionstringThe text of this user’s profile description (also known as bio), if the user provided one.

To return this field, add user.fields=description in the request’s query parameter.
verifiedbooleanIndicate if this user is a verified Twitter user.

To return this field, add user.fields=verified in the request’s query parameter.
verified_typeenum (blue, business, government, none)Indicates the type of verification for the Twitter account.

To return this field, add user.fields=verified_type in the request’s query parameter.
entitiesobjectThis object and its children fields contain details about text that has a special meaning in the user’s description.

To return this field, add user.fields=entities in the request’s query parameter.
entities.urlarrayContains details about the user’s profile website.
entities.url.urlsarrayContains details about the user’s profile website.
entities.url.urls.startintegerThe start position (zero-based) of the recognized user’s profile website. All start indices are inclusive.
entities.url.urls.endintegerThe end position (zero-based) of the recognized user’s profile website. This end index is exclusive.
entities.url.urls.urlstringThe URL in the format entered by the user.
entities.url.urls.expanded_urlstringThe fully resolved URL.
entities.url.urls.display_urlstringThe URL as displayed in the user’s profile.
entities.descriptionarrayContains details about URLs, Hashtags, Cashtags, or mentions located within a user’s description.
entities.description.urlsarrayContains details about any URLs included in the user’s description.
entities.description.urls.startintegerThe start position (zero-based) of the recognized URL in the user’s description. All start indices are inclusive.
entities.description.urls.endintegerThe end position (zero-based) of the recognized URL in the user’s description. This end index is exclusive.
entities.description.urls.urlstringThe URL in the format entered by the user.
entities.description.urls.expanded_urlstringThe fully resolved URL.
entities.description.urls.display_urlstringThe URL as displayed in the user’s description.
entities.description.hashtagsarrayContains details about text recognized as a Hashtag.
entities.description.hashtags.startintegerThe start position (zero-based) of the recognized Hashtag within the Tweet. All start indices are inclusive.
entities.description.hashtags.endintegerThe end position (zero-based) of the recognized Hashtag within the Tweet. This end index is exclusive.
entities.description.hashtags.hashtagstringThe text of the Hashtag.
entities.description.mentionsarrayContains details about text recognized as a user mention.
entities.description.mentions.startintegerThe start position (zero-based) of the recognized user mention within the Tweet. All start indices are inclusive.
entities.description.mentions.endintegerThe end position (zero-based) of the recognized user mention within the Tweet. This end index is exclusive.
entities.description.mentions.usernamestringThe part of text recognized as a user mention.
entities.description.cashtagsarrayContains details about text recognized as a Cashtag.
entities.description.cashtags.startintegerThe start position (zero-based) of the recognized Cashtag within the Tweet. All start indices are inclusive.
entities.description.cashtags.endintegerThe end position (zero-based) of the recognized Cashtag within the Tweet. This end index is exclusive.
entities.description.cashtags.cashtagstringThe text of the Cashtag.
profile_image_urlstringThe URL to the profile image for this user, as shown on the user’s profile.
public_metricsobjectContains details about activity for this user.
public_metrics.followers_countintegerNumber of users who follow this user.
public_metrics.following_countintegerNumber of users this user is following.
public_metrics.tweet_countintegerNumber of Tweets (including Retweets) posted by this user.
public_metrics.listed_countintegerNumber of lists that include this user.
pinned_tweet_idstringUnique identifier of this user’s pinned Tweet.

You can obtain the expanded object in includes.tweets by adding expansions=pinned_tweet_id in the request’s query parameter.
includes.tweetsarrayWhen including the expansions=pinned_tweet_id parameter, this includes the pinned Tweets attached to the returned users’ profiles in the form of Tweet objects with their default fields and any additional fields requested using the tweet.fields parameter, assuming there is a referenced Tweet present in the returned Tweet(s).
errorsobjectContains details about errors that affected any of the requested users. See Status codes and error messages for more details.
meta
 Default
objectThis object contains information about the number of users returned in the current request, and pagination details.
meta.result_count
 Default
integerThe number of users returned in this request. Note that this number may be lower than what was specified in the max_results query parameter.
meta.previous_tokenstringPagination token for the previous page of results. This value is returned when there are multiple pages of results, as the current request may only return a subset of results. To go back to the previous page, passing the value from this field in the pagination_token query parameter. When this field is not returned in the response, it means you are on the first page of results.
meta.next_tokenstringPagination token for the next page of results. This value is returned when there are multiple pages of results, as the current request may only return a subset of results. To retrieve the full list, keep passing the value from this field in the pagination_token query parameter. When this field is not returned in the response, it means you’ve reached the last page of results, and that there are no further pages.