Skip to content

Add new endpoints to steer Twitter feed algorithm #767

@yorickvanzweeden

Description

@yorickvanzweeden

Hi @fa0311

I like your repositories. Thank you for your work!

I was wondering if you were willing to add these endpoints. They can be used to steer X's home timeline algorithm

I have created a description of the endpoints below. If it is not possible, would you know how I can ensure I send the right headers for my own implementation?

Thanks!

How api/2/timeline/feedback works

When requesting HomeTimeline, a list of feedbackActions is returned. For example:

{
    "key": "-505584878",
    "value":
    {
        "feedbackType": "DontLike",
        "prompt": "Not interested in this post",
        "confirmation": "Thanks. X will use this to make your timeline better.",
        "childKeys":
        [
            "-987467267",
            "103167583"
        ],
        "feedbackUrl": "/2/timeline/feedback.json?feedback_type=DontLike&action_metadata=SSwWgIPS7cimpLM0ACbSoPPpAQAWgKD2pxMA",
        "hasUndoAction": true,
        "icon": "Frown",
        "clientEventInfo":
        {
            "action": "click",
            "element": "feedback_dontlike"
        }
    }
}

In each Timeline entry, there is a field feedbackInfo, which related the feedbackKey to the correct payload.

"feedbackInfo":
{
    "feedbackKeys":
    [
        "-505584878"
    ]
}

In Python, I can retrieve this here:

response = twitter_client.get_tweet_api().get_home_timeline(count=20, cursor=cursor)
feedback_actions = response.raw.response.data.data.home.home_timeline_urt.response_objects['feedbackActions']
feedback_info = response.data.raw.entry[0].content.actual_instance.feedback_info

The feedback is then sent like this

params = {
    'feedback_type': 'DontLike',
    'action_metadata': 'SSwWgIPS7cimpLM0ACbSoPPpAQAWgKD2pxMA',
}

data = {
    'feedback_type': 'DontLike',
    'undo': 'false',
}

response = requests.post('https://x.com/i/api/2/timeline/feedback.json', params=params, cookies=cookies, headers=headers, data=data)

Regarding feedback_type, I have found the following enum values in loaded obfuscated Javascript, but not all of them seem to be used often?

'Dismiss', 'DontLike', 'GiveFeedback', 'Moderate', 'NotCredible', 'NotAboutTopic', 'NotRecent', 'NotRelevant', 'Relevant', 'SeeFewer', 'SeeMore', 'UnfollowEntity', 'RichBehavior', 'Generic'

How https://api.x.com/1.1/live_pipeline/update_subscriptions works

When the user visits the homepage, a script tracks the user's attention to tweets. I also think it might affect whether a tweet will be reshown later.

data = {
    'sub_topics': '/tweet_engagement/[tweetID1],/tweet_engagement/[tweetID2]',
    'unsub_topics': '/tweet_engagement/[tweetID3],/tweet_engagement/[tweetID4]',
}

response = requests.post('https://api.x.com/1.1/live_pipeline/update_subscriptions', cookies=cookies, headers=headers, data=data)

This API is quite straightforward, and provides less signal to the algorithm than the timeline/feedback. It just takes in tweetIDs for either topics to show more of, or topics to show less often.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions