Skip to main content
The Account Activity API (AAA) provides a way to receive real-time events related to X user accounts via webhooks. By subscribing specific user accounts to a pre-configured webhook, your application can be notified of various activities such as Posts, Direct Messages, Likes, Follows, Blocks, and more, from one or more of your owned or subscribed accounts through a single connection. This API is commonly used to build applications that need to react instantly to user actions or maintain an up-to-date state based on user activity.

Overview

Webhook delivery

Events delivered to your server in real-time

Real-time

Delivers data at the speed of X — no polling required

Comprehensive

Posts, DMs, follows, likes, blocks, mutes, and more

Subscription-based

Subscribe user accounts to receive all their activity

How it works

  1. Register webhook — Register your webhook URL via the V2 Webhooks API
  2. Subscribe users — Add user subscriptions to your webhook
  3. Receive events — Get activity events delivered as POST requests with JSON payloads
  4. Process events — Handle events in your application and respond with 200 OK

Activity types

You will receive all related activities below for each user subscription on your webhook registration:
  • Posts (by user)
  • Post deletes (by user)
  • @mentions (of user)
  • Replies (to or from user)
  • Reposts (by user or of user)
  • Quote Posts (by user or of user)
  • Reposts of Quoted Posts (by user or of user)
  • Likes (by user or of user)
  • Follows (by user or of user)
  • Unfollows (by user or of user)
  • Blocks (by user or of user)
  • Unblocks (by user or of user)
  • Mutes (by user or of user)
  • Unmutes (by user or of user)
  • Direct Messages sent (by user)
  • Direct Messages received (by user)
  • Typing indicators (to user)
  • Read receipts (to user)
  • Subscription revokes (by user)
We do not deliver home timeline data via the Account Activity API. Use the User Posts timeline by User ID endpoint to pull this data.The returned Posts from the Account Activity API count towards the monthly Post cap.

Feature summary

TierNumber of Unique SubscriptionsNumber of Webhooks
Pay Per Use31
Enterprise5000+5+

Account Activity data object structure

ObjectDetails
for_user_idIdentifies the user subscription that the event is related to.
is_blocked_by(Conditional) Shown only for Post mention events if the mentioning user is blocked by the subscribed user.
sourceThe user performing the activity (e.g., the user following, blocking, or muting).
targetThe user the activity applies to (e.g., the user being followed, blocked, or muted).

Available activities

Message TypeDetails
tweet_create_eventsPost status for Posts, Retweets, Replies, @mentions, Quote Tweets, or Retweet of Quote Tweets.
favorite_eventsLike event with user and target.
follow_eventsFollow event with user and target.
unfollow_eventsUnfollow event with user and target.
block_eventsBlock event with user and target.
unblock_eventsUnblock event with user and target.
mute_eventsMute event with user and target.
unmute_eventsUnmute event with user and target.
user_eventRevoke events when a user removes app authorization (subscription auto-deleted).
direct_message_eventsDM status for sent or received messages.
direct_message_indicate_typing_eventsDM typing event with user and target.
direct_message_mark_read_eventsDM read event with user and target.
tweet_delete_eventsNotice of deleted Posts for compliance.

Payload examples

Below are example payloads for each Account Activity event.

tweet_create_events (Posts, Retweets, Replies, QuoteTweets)

{
  "for_user_id": "2244994945",
  "tweet_create_events": [
    {
      <Tweet Object>
    }
  ]
}

tweet_create_events (@mentions)

{
  "for_user_id": "2244994945",
  "user_has_blocked": "false",
  "tweet_create_events": [
    {
      <Tweet Object>
    }
  ]
}

favorite_events

{
  "for_user_id": "2244994945",
  "favorite_events": [{
    "id": "a7ba59eab0bfcba386f7acedac279542",
    "created_at": "Mon Mar 26 16:33:26 +0000 2018",
    "timestamp_ms": 1522082006140,
    "favorited_status": {
      <Tweet Object>
    },
    "user": {
      <User Object>
    }
  }]
}

follow_events

{
  "for_user_id": "2244994945",
  "follow_events": [{
    "type": "follow",
    "created_timestamp": "1517588749178",
    "target": {
      <User Object>
    },
    "source": {
      <User Object>
    }
  }]
}

unfollow_events

{
  "for_user_id": "2244994945",
  "follow_events": [{
    "type": "unfollow",
    "created_timestamp": "1517588749178",
    "target": {
      <User Object>
    },
    "source": {
      <User Object>
    }
  }]
}

block_events

{
  "for_user_id": "2244994945",
  "block_events": [{
    "type": "block",
    "created_timestamp": "1518127020304",
    "source": {
      <User Object>
    },
    "target": {
      <User Object>
    }
  }]
}

unblock_events

{
  "for_user_id": "2244994945",
  "block_events": [{
    "type": "unblock",
    "created_timestamp": "1518127020304",
    "source": {
      <User Object>
    },
    "target": {
      <User Object>
    }
  }]
}

mute_events

{
  "for_user_id": "2244994945",
  "mute_events": [
    {
      "type": "mute",
      "created_timestamp": "1518127020304",
      "source": {
        <User Object>
      },
      "target": {
        <User Object>
      }
    }
  ]
}

unmute_events

{
  "for_user_id": "2244994945",
  "mute_events": [
    {
      "type": "unmute",
      "created_timestamp": "1518127020304",
      "source": {
        <User Object>
      },
      "target": {
        <User Object>
      }
    }
  ]
}

user_event

{
  "user_event": {
    "revoke": {
      "date_time": "2018-05-24T09:48:12+00:00",
      "target": {
        "app_id": "13090192"
      },
      "source": {
        "user_id": "63046977"
      }
    }
  }
}

direct_message_events

{
  "for_user_id": "4337869213",
  "direct_message_events": [{
    "type": "message_create",
    "id": "954491830116155396",
    "created_timestamp": "1516403560557",
    "message_create": {
      "target": {
        "recipient_id": "4337869213"
      },
      "sender_id": "3001969357",
      "source_app_id": "13090192",
      "message_data": {
        "text": "Hello World!",
        "entities": {
          "hashtags": [],
          "symbols": [],
          "user_mentions": [],
          "urls": []
        }
      }
    }
  }],
  "apps": {
    "13090192": {
      "id": "13090192",
      "name": "FuriousCamperTestApp1",
      "url": "https://x.com/furiouscamper"
    }
  },
  "users": {
    "3001969357": {
      "id": "3001969357",
      "created_timestamp": "1422556069340",
      "name": "Jordan Brinks",
      "screen_name": "furiouscamper",
      "location": "Boulder, CO",
      "description": "Alter Ego - X PE opinions-are-my-own",
      "url": "https://t.co/SnxaA15ZuY",
      "protected": false,
      "verified": false,
      "followers_count": 22,
      "friends_count": 45,
      "statuses_count": 494,
      "profile_image_url_https": "https://pbs.twimg.com/profile_images/851526626785480705/cW4WTi7C_normal.jpg"
    },
    "4337869213": {
      "id": "4337869213",
      "created_timestamp": "1448312972328",
      "name": "Harrison Test",
      "screen_name": "Harris_0ff",
      "location": "Burlington, MA",
      "protected": false,
      "verified": false,
      "followers_count": 8,
      "friends_count": 8,
      "statuses_count": 240,
      "profile_image_url_https": "https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png"
    }
  }
}

direct_message_indicate_typing_events

{
  "for_user_id": "4337869213",
  "direct_message_indicate_typing_events": [{
    "created_timestamp": "1518127183443",
    "sender_id": "3284025577",
    "target": {
      "recipient_id": "3001969357"
    }
  }],
  "users": {
    "3001969357": {
      "id": "3001969357",
      "created_timestamp": "1422556069340",
      "name": "Jordan Brinks",
      "screen_name": "furiouscamper",
      "location": "Boulder, CO",
      "description": "Alter Ego - X PE opinions-are-my-own",
      "url": "https://t.co/SnxaA15ZuY",
      "protected": false,
      "verified": false,
      "followers_count": 23,
      "friends_count": 47,
      "statuses_count": 509,
      "profile_image_url_https": "https://pbs.twimg.com/profile_images/851526626785480705/cW4WTi7C_normal.jpg"
    },
    "3284025577": {
      "id": "3284025577",
      "created_timestamp": "1437281176085",
      "name": "Bogus Bogart",
      "screen_name": "bogusbogart",
      "protected": true,
      "verified": false,
      "followers_count": 1,
      "friends_count": 4,
      "statuses_count": 35,
      "profile_image_url_https": "https://pbs.twimg.com/profile_images/763383202857779200/ndvZ96mE_normal.jpg"
    }
  }
}

direct_message_mark_read_events

{
  "for_user_id": "4337869213",
  "direct_message_mark_read_events": [{
    "created_timestamp": "1518452444662",
    "sender_id": "199566737",
    "target": {
      "recipient_id": "3001969357"
    },
    "last_read_event_id": "963085315333238788"
  }],
  "users": {
    "199566737": {
      "id": "199566737",
      "created_timestamp": "1286429788000",
      "name": "Le Braat",
      "screen_name": "LeBraat",
      "location": "Denver, CO",
      "description": "data by day @X, design by dusk",
      "protected": false,
      "verified": false,
      "followers_count": 299,
      "friends_count": 336,
      "statuses_count": 752,
      "profile_image_url_https": "https://pbs.twimg.com/profile_images/936652894371119105/YHEozVAg_normal.jpg"
    },
    "3001969357": {
      "id": "3001969357",
      "created_timestamp": "1422556069340",
      "name": "Jordan Brinks",
      "screen_name": "furiouscamper",
      "location": "Boulder, CO",
      "description": "Alter Ego - X PE opinions-are-my-own",
      "url": "https://t.co/SnxaA15ZuY",
      "protected": false,
      "verified": false,
      "followers_count": 23,
      "friends_count": 48,
      "statuses_count": 510,
      "profile_image_url_https": "https://pbs.twimg.com/profile_images/851526626785480705/cW4WTi7C_normal.jpg"
    }
  }
}

tweet_delete_events

{
  "for_user_id": "930524282358325248",
  "tweet_delete_events": [
    {
      "status": {
        "id": "1045405559317569537",
        "user_id": "930524282358325248"
      },
      "timestamp_ms": "1432228155593"
    }
  ]
}

Support for longform Posts

The V2 Account Activity API supports longform posts, which are posts exceeding 280 characters. When a longform post is included in a tweet_create_events payload, the text field contains the first 140 characters (or fewer), and the truncated field is set to true. The full post content is delivered in the extended_tweet object, which includes:
  • full_text — The complete text of the post, including all characters beyond the 280-character limit.
  • entities — Any entities (e.g., hashtags, URLs, user mentions, symbols) appearing in the full text, including those after the 280th character.
  • display_text_range — The range of characters to display, accounting for the full text.
This ensures that applications can process the entire content of longform posts, including mentions or other entities that appear later in the text. Below is an example of a tweet_create_events payload for a longform post:
{
  "for_user_id": "1603419180975409153",
  "tweet_create_events": [
    {
      "created_at": "Mon May 19 14:01:46 +0000 2025",
      "id": 1924465506158879000,
      "id_str": "1924465506158878979",
      "text": "The Antikythera Mechanism: A Window into Ancient Ingenuity Discovered in 1901 among the wreckage of a Roman ship of… https://t.co/bzbEKj8cd8",
      "display_text_range": [0, 140],
      "truncated": true,
      "user": { ... },
      "extended_tweet": {
        "full_text": "The Antikythera Mechanism: A Window into Ancient Ingenuity Discovered in 1901 among the wreckage of a Roman ship off the Greek island of Antikythera...",
        "display_text_range": [0, 2051],
        "entities": {
          "hashtags": [],
          "urls": [],
          "user_mentions": [
            {
              "screen_name": "xai",
              "name": "xAI",
              "id": 1661523610111193000,
              "id_str": "1661523610111193088",
              "indices": [2032, 2036]
            },
            {
              "screen_name": "HistoryInPics",
              "name": "History Photographed",
              "id": 1582853809,
              "id_str": "1582853809",
              "indices": [2037, 2051]
            }
          ],
          "symbols": []
        }
      },
      "entities": {
        "hashtags": [],
        "urls": [
          {
            "url": "https://t.co/bzbEKj8cd8",
            "expanded_url": "https://twitter.com/i/web/status/1924465506158878979",
            "display_url": "twitter.com/i/web/status/1…",
            "indices": [117, 140]
          }
        ],
        "user_mentions": [],
        "symbols": []
      }
    }
  ]
}

Frequently asked questions

The Account Activity API uses webhooks, delivering data in real-time without requiring an open connection (unlike streaming APIs) or frequent polling (unlike REST APIs). Benefits include:
  • Speed — Delivers data at the speed of X.
  • Simplicity — Provides all account events through a single webhook connection, including Posts, @mentions, Replies, Reposts, Quote Tweets, Likes, DMs, Follows, Blocks, and Mutes.
  • Scale — Supports all activities for managed accounts without rate limits or event caps (Enterprise tier).
Yes! You can register multiple webhook URLs and manage subscriptions separately via the V2 Webhooks API.
Authentication requirements vary by endpoint:
  • User-specific actions (e.g., subscribing a user) require OAuth 1.0a (3-legged OAuth flow).
  • App-level actions (e.g., listing/deleting subscriptions, subscription count) require OAuth2 App Only Bearer Token.
Review the Authentication section for details.
Yes. If your app has subscriptions for User A and User B, and User A mentions User B in a Post, your webhook receives two events (one per user). Use the for_user_id field to identify the subscription.
No. The /all/ product is the only option, delivering all supported event types.
The webhook limit is set at the account level, not per app. For example, with three webhooks and two apps, you could use two webhooks for one app and one for the other, but not three per app.

API reference index

PurposeV2 Endpoint
Subscribes an application to an account’s eventsPOST /2/account_activity/webhooks/:webhook_id/subscriptions/all
Returns a count of currently active subscriptionsGET /2/account_activity/subscriptions/count
Checks if a webhook is subscribed to an accountGET /2/account_activity/webhooks/:webhook_id/subscriptions/all
Returns a list of currently active subscriptionsGET /2/account_activity/webhooks/:webhook_id/subscriptions/all/list
Deactivates a subscription using app-only OAuthDELETE /2/account_activity/webhooks/:webhook_id/subscriptions/:user_id/all
Creates a replay jobPOST /2/account_activity/replay/webhooks/:webhook_id/subscriptions/all
For webhook management endpoints (register, view, validate, delete), see the V2 Webhooks API documentation.

Getting started

Prerequisites
  • An approved developer account
  • A Project and App in the Developer Console
  • A publicly accessible HTTPS webhook endpoint
  • Enterprise or Pay Per Use access for the Account Activity API