Screen name vs user id



Hi. i’m currently migrating our app from the streaming API to the new webhook API, and I notice that the webhook calls from Twitter don’t include hydrated users - just the user ids, so no screen_name. I also notice that contains no mention of using screen_name, even tho we still use it with this param.

I get the problem with screen_name - users can change it. So am I right to conclude that we need to start converting all our stored screen names to user ids? We have hundreds of thousands of stored twitter accounts so it’s gonna take more than a few API calls.


It has always been a good strategy to store IDs rather than screen_names, for the exact reason that you note i.e. that screen_names are mutable and user_ids are not. At the moment I’m not aware of plans to extend the data available in the webhook calls, but this is still the early implementation so there may be reasons to add screen_names in the future.

There’s no immediate urgency that I’m aware of to directly migrate to user_id usage, unless you want to start on that. Note that users/lookup can handle 100 queries at one time.

As we move forward with the roadmap and review our documentation and developer experience, we hope to clarify good practices and strategies in terms of addressing the API.


Hey @rowanseymour,

There are condensed user objects hydrated in a different manner than you are used to. At the same level of the direct_message_events array there is also a users object that contains all of the condensed user objects keyed by user ID. In the future possibility that the same user is referenced in multiple events, this keeps the payload size down by not requiring to repeat the user object.

Note that the user objects are only in webhook payloads and not returned by GET direct_messages/events/list.


  "direct_message_events": [
  "users": {
    "1234858592": {
      "id": "1234858592",
      "created_timestamp": "1415320482361",
      "name": "TwitterDev",
      "screen_name": "TwitterDev",
      "location": "Internet",
      "description": "Developer and Platform Relations @Twitter. We are developer advocates. We can't answer all your questions, but we listen to all of them!",
      "protected": false,
      "verified": true,
      "followers_count": 440643,
      "friends_count": 1534,
      "statuses_count": 2837,
      "profile_image_url": "",
      "profile_image_url_https": ""
    "3805104374": {
      "id": "3805104374",
      "created_timestamp": "1449607341142",
      "name": "Furni",
      "screen_name": "furni",
      "location": "San Francisco, CA",
      "description": "Furni is Twitter's example company to showcase new developer features.",
      "protected": false,
      "verified": false,
      "followers_count": 297,
      "friends_count": 7,
      "statuses_count": 1,
      "profile_image_url": "",
      "profile_image_url_https": ""


I think using both screen names and ids is best. The load isn’t much more. But, if you want to choose one or the other, go with ids.

Like Andy says, users/lookup can be used on 100 screen names using a POST. That would mean 90,000 per 15 minutes at full rate limits. That’s never a good idea. I’d cut it down to 75,000.

I would suggest you have your users fill in the blanks for you. Use a little script on wherever people go after login (that’s usually a busy page or choose another fairly busy page). Let that script pull 20 to 50 screen_names that don’t have ids yet, and call users/lookup on them. Write the ids. Rinse and repeat.

Calling users/lookup on that small a number of users will likely have such a short lag that no one would notice. Heck, I doubt anyone would notice users/show on 20 users.

Depending on how busy the app is, you should have all your ids populated fairly quickly. Then you can kill the little script.



Ah yeah they are there. Thanks!