read:user

Reads one user, by handle or by id: the name, the bio, the follower counts, the joining date. It is also how a handle becomes an id, which several other operations require, so it is worth keeping the id once you have it.

One operation, two endpoints: which one runs is decided by the field you filled in, and the answer is the same shape either way.

Fields

username the X handle, without the @. One or the other
id X's own numeric id, as a string. One or the other
profile the account to read as. Optional when the agent has one
reason Required over MCP. One short sentence, in the agent's own words, for the person

A handle and an id never share a call

Giving both is refused rather than resolved by precedence. An X id is digits and a handle may be digits too, so there is no safe test, and a silent winner would spend money on the wrong account.

What comes back

{ "status": "done",
  "ref": "W6ZFQ70K",
  "data": {
    "data": {
      "id": "1400000000000000044",
      "name": "Playground User",
      "username": "playground_user",
      "created_at": "2024-09-08T14:18:21.362Z",
      "description": "Default playground user for testing API endpoints.",
      "location": "San Francisco, CA",
      "profile_image_url": "https://pbs.twimg.com/profile_images/.../normal.png",
      "protected": false,
      "verified": false,
      "verified_type": "none",
      "public_metrics": {
        "followers_count": 18, "following_count": 23, "tweet_count": 67,
        "listed_count": 10, "like_count": 109, "media_count": 16
      }
    }
  } }

id, name and username are always there. location, pinned_tweet_id and entities appear only when the account has them set.

A handle X does not hold is not an error

It answers 200 with an errors array and no data, rather than a 404. Check for data before reading it.