Skip to main content
This guide covers all the essential operations for working with tweets, including creating, deleting, retweeting, liking, and replying to tweets.

Creating tweets

You can create tweets with text, media, polls, and more using the create_tweet() method.

Basic tweet

tweet = await client.create_tweet('Hello, Twitter!')
print(tweet.id)

Tweet with media

First upload media files, then attach them to your tweet:
# Upload media and get media IDs
media_id_1 = await client.upload_media('image1.jpg')
media_id_2 = await client.upload_media('video.mp4', wait_for_completion=True)

# Create tweet with media
tweet = await client.create_tweet(
    text='Check out these photos!',
    media_ids=[media_id_1, media_id_2]
)
For videos and GIFs, set wait_for_completion=True to ensure the media is fully processed before posting.

Tweet with a poll

# Create a poll
choices = ['Option A', 'Option B', 'Option C']
duration_minutes = 60
poll_uri = await client.create_poll(choices, duration_minutes)

# Create tweet with the poll
tweet = await client.create_tweet(
    text='What do you prefer?',
    poll_uri=poll_uri
)

Quote tweet

Quote another tweet by providing its URL:
tweet = await client.create_tweet(
    text='Interesting perspective!',
    attachment_url='https://twitter.com/user/status/1234567890'
)

Reply to a tweet

You can reply to tweets in two ways:
reply = await client.create_tweet(
    text='Great point!',
    reply_to='1234567890'  # Tweet ID
)

Long tweets (Premium)

If you have Twitter Premium, you can post tweets longer than 280 characters:
long_text = 'Your very long tweet content here...'
tweet = await client.create_tweet(
    text=long_text,
    is_note_tweet=True
)
The is_note_tweet parameter requires Twitter Premium/Blue subscription.

Conversation control

Limit who can reply to your tweet:
tweet = await client.create_tweet(
    text='Important announcement',
    conversation_control='followers'  # Options: 'followers', 'verified', 'mentioned'
)

Scheduled tweets

Schedule tweets to be posted at a specific time:
import time

# Schedule tweet for 1 hour from now
scheduled_time = int(time.time()) + 3600

scheduled_id = await client.create_scheduled_tweet(
    scheduled_at=scheduled_time,
    text='This will be posted in an hour',
    media_ids=[media_id]
)

Managing scheduled tweets

# Get all scheduled tweets
scheduled_tweets = await client.get_scheduled_tweets()
for tweet in scheduled_tweets:
    print(f'{tweet.text} - scheduled for {tweet.execute_at}')

# Delete a scheduled tweet
await client.delete_scheduled_tweet(scheduled_id)

Retrieving tweets

Get a specific tweet

tweet = await client.get_tweet_by_id('1234567890')
print(tweet.text)
print(f'Likes: {tweet.favorite_count}')
print(f'Retweets: {tweet.retweet_count}')

Get user tweets

user = await client.get_user_by_screen_name('elonmusk')

# Get different types of tweets
tweets = await user.get_tweets('Tweets', count=20)
replies = await user.get_tweets('Replies', count=20)
media_tweets = await user.get_tweets('Media', count=20)
liked_tweets = await user.get_tweets('Likes', count=20)

for tweet in tweets:
    print(tweet.text)

# Fetch more tweets
more_tweets = await tweets.next()

Get multiple tweets by IDs

tweet_ids = ['1111111111', '1111111112', '111111113']
tweets = await client.get_tweets_by_ids(tweet_ids)

Interacting with tweets

Like and unlike

await client.favorite_tweet('1234567890')
await client.unfavorite_tweet('1234567890')

Retweet and unretweet

await client.retweet('1234567890')
await client.delete_retweet('1234567890')

Bookmark tweets

# Add to bookmarks
await tweet.bookmark()

# Remove from bookmarks
await tweet.delete_bookmark()

# Get all bookmarks
bookmarks = await client.get_bookmarks(count=20)
for bookmark in bookmarks:
    print(bookmark.text)

Deleting tweets

await client.delete_tweet('1234567890')

Tweet attributes

The Tweet object provides access to various attributes:
tweet = await client.get_tweet_by_id('1234567890')

# Basic information
print(tweet.id)                    # Tweet ID
print(tweet.text)                  # Tweet text
print(tweet.created_at)            # Creation timestamp
print(tweet.lang)                  # Language code

# User information
print(tweet.user.screen_name)      # Author's screen name
print(tweet.user.name)             # Author's display name

# Engagement metrics
print(tweet.favorite_count)        # Number of likes
print(tweet.retweet_count)         # Number of retweets
print(tweet.reply_count)           # Number of replies
print(tweet.view_count)            # Number of views
print(tweet.bookmark_count)        # Number of bookmarks

# Media and content
print(tweet.media)                 # List of media objects
print(tweet.hashtags)              # List of hashtags
print(tweet.urls)                  # List of URLs

# Relationships
print(tweet.in_reply_to)           # ID of tweet being replied to
print(tweet.quote)                 # Quoted tweet object
print(tweet.retweeted_tweet)       # Retweeted tweet object

# Status flags
print(tweet.favorited)             # Whether you've liked it
print(tweet.bookmarked)            # Whether you've bookmarked it

Getting tweet engagement

Retrieve users who interacted with a tweet:
tweet = await client.get_tweet_by_id('1234567890')

# Get users who retweeted
retweeters = await tweet.get_retweeters(count=40)
for user in retweeters:
    print(user.screen_name)

# Get users who liked
favoriters = await tweet.get_favoriters(count=40)
for user in favoriters:
    print(user.screen_name)

# Pagination
more_retweeters = await retweeters.next()

Working with tweet replies

Access replies to a tweet:
tweet = await client.get_tweet_by_id('1234567890')

# Get direct replies
if tweet.replies:
    for reply in tweet.replies:
        print(f'{reply.user.screen_name}: {reply.text}')
    
    # Load more replies
    more_replies = await tweet.replies.next()

# Get the tweet thread (tweets this is replying to)
if tweet.reply_to:
    for parent in tweet.reply_to:
        print(f'Replying to: {parent.text}')
The replies attribute contains top-level replies. Each reply may also have nested replies accessible through its own replies attribute.

Advanced features

Add alt text to media

media_id = await client.upload_media('image.jpg')

# Add alt text for accessibility
await client.create_media_metadata(
    media_id,
    alt_text='A beautiful sunset over the ocean',
    sensitive_warning=['other']
)

await client.create_tweet(media_ids=[media_id])

Vote on polls

tweet = await client.get_tweet_by_id('1234567890')

if tweet.poll:
    print('Poll choices:')
    for choice in tweet.poll.choices:
        print(f"{choice['label']}: {choice['count']} votes")
    
    # Vote on the poll
    await tweet.poll.vote('Option A')

Get similar tweets (Premium)

tweet = await client.get_tweet_by_id('1234567890')
similar_tweets = await tweet.get_similar_tweets()

for similar in similar_tweets:
    print(similar.text)
The get_similar_tweets() method requires Twitter Premium/Blue subscription.

Build docs developers (and LLMs) love