How to Find a Twitter/X User ID After the API Changes

Published Updated
X's API moved to pay-per-usage credits, so free handle-to-ID lookups are gone. Here is what still works and what the numeric user ID is good for.

An X user ID is the numeric identifier behind a handle, such as 783214. The /2/users/by/username/{username} endpoint still resolves handles, but X has moved its API to pay-per-usage credit pricing, so what was once a free call now draws on purchased credits. A public lookup tool resolves public accounts without an API account.

If you built something against the Twitter API a few years ago and have come back to it, this is the change that matters. The endpoint shape is familiar. The access model underneath it is not.

What changed with X API access?

The pricing model. X's own developer documentation now describes the X API as using pay-per-usage pricing, on a credit basis: you purchase credits upfront and they are deducted as you make calls. The documentation states there are no contracts or minimum spend, with usage visible in the Developer Console.

What is notable about that documentation page is the absence as much as the presence. It does not describe tiered access plans, and it does not mention a free tier. For a developer whose mental model is the old Basic and Pro plan structure, or the much older era of generous free access, the practical position is different: calls now have a unit cost attached.

I am being deliberately imprecise about the exact per-call rates, and you should be suspicious of articles that are not. Third-party sources quote specific figures for a user lookup, but those figures disagree with each other and I was not able to load X's own pricing page to verify any of them. Check X's current pricing documentation directly before budgeting. Rates have changed repeatedly over the last few years and any number quoted in a blog post, this one included, has a short shelf life.

The documentation does confirm the lookup endpoint still exists. The quick start uses https://api.x.com/2/users/by/username/xdevelopers, which is the canonical handle-to-ID resolution call and returns the numeric id for that account.

What does an X user ID look like?

A plain integer, with wildly varying length depending on when the account was created. This is the platform where ID length is most informative and most likely to break naive validation.

Accounts from the service's earliest period have very short IDs, sometimes only a few digits, because they were assigned sequentially from a counter. Accounts created later have much longer IDs, commonly eighteen or nineteen digits. That is a consequence of the platform switching to a distributed ID generation scheme, the snowflake system, which produces much larger values.

Two practical implications. First, do not validate on length. A six-digit ID and a nineteen-digit ID can both be perfectly valid. Second, nineteen digits is past the safe integer range in JavaScript, so parse one as a JSON number and you get back a value that is close but wrong, silently, with no error anywhere. Store IDs as strings, compare them as strings, use string columns.

A related caution about snowflake IDs: they encode a creation timestamp, and there are tools that will decode one for you. This genuinely works for post IDs. For user IDs it works only for accounts created after the platform adopted the scheme, and the early sequential IDs carry no timestamp at all. Any tool claiming to tell you an account's creation date from its ID is giving you a wrong answer for older accounts rather than an error, so treat decoded dates as unreliable unless you know the ID is in the snowflake range.

How do you resolve a handle to a user ID now?

Three routes, and the right one depends mostly on whether you already have API credits.

Through the API, if you have credits

Call /2/users/by/username/{username} with your authentication and read the id from the response. This is the supported method and the one to use inside an application you control. The cost per call is whatever X's current pricing specifies, so verify that before running a bulk job rather than discovering the spend afterwards.

If you are resolving many handles, check whether the batch form of the users lookup is available on your access level, since resolving handles in groups rather than one at a time is the difference between a sensible credit spend and a wasteful one.

From a URL you already have

Occasionally a link already contains the numeric ID, typically in older intent URLs or certain widget configurations rather than in a standard profile URL. A plain profile URL at x.com/handle contains only the handle. Worth a glance before assuming you need a lookup, but do not expect it.

Without an API account

Paste the handle or profile URL into the X user ID finder and read the number. No developer account, no credits, no authentication. For the common case of converting a list of public handles into stable identifiers, this avoids setting up billing for a task that is not really an integration.

The limit, stated plainly: public accounts only. A protected account's numeric ID is not publicly derivable, and a lookup failing on one is correct rather than broken. Suspended and deleted accounts will not resolve either, since there is nothing left to read.

Why bother with the numeric ID at all?

Because handles on this platform are unusually volatile, and that volatility has consequences a stored handle cannot survive.

Handles can be changed by their owners, and released handles can be claimed by others. On a platform where handle squatting and impersonation are both common, a stored handle is a reference that can quietly start pointing at a different and possibly hostile account. The numeric ID cannot be reassigned, so it does not have that failure mode. For anything resembling trust, verification or moderation, that difference is the entire point.

For analytics, the ID keeps one account's history as one series through any number of renames. For research datasets, it is the only honest join key, which is why academic Twitter datasets have always been distributed as ID lists. For archival work, it is what lets you tell whether the account you are looking at today is the account you recorded three years ago.

And for anyone auditing a list of brand or competitor accounts, the ID is what turns a spreadsheet that needs manual reconciliation every quarter into one that does not.

How does X compare to the other platforms now?

X has gone from being the easiest platform for this kind of work to one of the more awkward, and the change is about access rather than technology.

The endpoint is still there and still clean. What changed is that casual and research use no longer has an obvious free path, so a project that would once have resolved ten thousand handles over a weekend now has a budget question attached. For hobby projects, student work and small-scale research, that is a meaningful barrier.

By comparison, YouTube is now the most straightforward: the /channel/UC... URL form contains the channel ID outright, and the Data API documents a handle filter at a quota cost of 1 unit per call. The YouTube channel ID lookup covers the three identifier styles in circulation there.

Instagram sits in the middle, with a documented Business Discovery endpoint that returns another public professional account's ID but demanding permission requirements to reach it. See the Instagram user ID lookup. TikTok is more restrictive in a different way: its official API only returns identifiers for users who have authorised your app, so third-party lookups are not supported at all, as covered in the TikTok user ID lookup. Facebook remains the most permissive, with several URL formats exposing IDs directly, which the Facebook ID finder handles.

The pattern across all five: handles are display, IDs are references, and resolving between them costs something on every platform. The currency varies.

Frequently asked questions

Is there still a free tier for the X API?

X's current developer documentation describes pay-per-usage credit pricing and does not mention a free tier. Third-party reports about remaining free allowances disagree with one another, so check X's own pricing documentation directly rather than relying on any secondary source, including this article. The position has changed repeatedly in recent years.

Does the handle-to-ID endpoint still exist?

Yes. X's documentation shows /2/users/by/username/{username} in its quick start, returning the numeric id for the named account. The endpoint shape has not changed; what changed is that calling it draws on purchased credits rather than falling under a free allowance, so verify the current per-call cost before bulk use.

Can I tell when an account was created from its user ID?

Only sometimes, and unreliably. Accounts created after the platform adopted snowflake IDs have a creation timestamp encoded in the number, but early accounts were assigned sequential IDs with no timestamp. A decoder will return a plausible-looking wrong date for those rather than an error, so do not treat decoded creation dates as trustworthy.

Why do X user IDs vary so much in length?

Because the platform changed how it generates them. Early accounts received short sequential IDs from a counter, sometimes only a few digits. Later accounts received much larger snowflake IDs, commonly eighteen or nineteen digits. Both are valid, so any validation that checks ID length will reject real accounts.

Can I look up a protected account's user ID?

No. A protected account's numeric ID is not publicly derivable, and a public lookup failing on one is correct behaviour rather than a defect. The same applies to suspended and deleted accounts, where there is no longer anything public to read. Record these as unresolvable rather than retrying them.

Should I store the handle or the ID?

The ID, as your primary reference, with the handle stored only as a display label you refresh. Handles on this platform change often and released handles can be claimed by others, so a stored handle can end up pointing at an unrelated or impersonating account. The numeric ID is never reassigned and does not drift.