Twitter User IDs: Converting Between Handles and IDs, and Why It Matters
Twitter User IDs: Converting Between Handles and IDs, and Why It Matters
Every X account has two identifiers, and confusing them causes a specific, nasty class of bug.
The handle — @nasa. Human-readable, visible everywhere, and ★changeable at any time★.
The numeric ID — something like 11348282. Assigned at signup, ★never changes for the life of the account★, and invisible in the interface.
The interface only shows you one of them. The one that's stable is the one you can't see.
Why this matters more than it sounds
★Handles are recycled. When someone changes their handle, the old one becomes available for anyone to claim.★
Think about what that does to a system keyed on handles:
- You store
@acmecorpin your watchlist - They rebrand to
@acmehq - Your system now watches
@acmecorp— which either 404s, or belongs to someone entirely different
⚠️ ★The second case is the dangerous one. Your monitoring keeps working, keeps returning data, and the data is about a stranger.★ There's no error to alert you. A system keyed on IDs would have followed the rename automatically, because the ID didn't move.
The failure mode is the tell: handle-keyed systems break in a way that looks like "the account disappeared" rather than "the account was renamed" — which sends people looking in entirely the wrong direction.
Storing the ID once and querying by it afterwards is a two-line change — both directions are a single call.
Getting an ID from a handle
The straightforward direction. Any profile lookup returns it:
import requests
BASE = "https://api.socialapi.tech"
KEY = "your_api_key"
HDRS = {"X-API-Key": KEY}
def handle_to_id(username):
r = requests.get(f"{BASE}/v1/user/info",
params={"username": username},
headers=HDRS, timeout=60)
if r.status_code == 404:
return None # handle doesn't exist right now
r.raise_for_status()
return r.json()["data"]["id"]
print(handle_to_id("nasa"))
★The ID comes back as a string, not a number.★ X IDs exceed what some languages hold in a standard integer, and JavaScript in particular loses precision above 2^53 — a bug that produces IDs off by one or two and lookups that fail for no visible reason. Keep them as strings all the way through.
Getting a handle from an ID
The reverse direction, and the one people struggle to find:
def id_to_handle(user_id):
r = requests.get(f"{BASE}/v1/user/info_by_id",
params={"user_id": user_id},
headers=HDRS, timeout=60)
if r.status_code == 404:
return None # deleted or suspended
r.raise_for_status()
d = r.json()["data"]
return d["username"], d["display_name"]
print(id_to_handle("11348282"))
★This is how you recover from a rename. You stored the ID, the handle changed, and one call tells you what it changed to.★ (Both directions are single calls — handle to ID, ID to handle.) Without the ID, a renamed account is genuinely hard to find again — you'd be searching display names and hoping.
Keeping a watchlist that survives renames
The pattern worth adopting if you monitor accounts:
import json, pathlib
STORE = pathlib.Path("watchlist.json")
def resolve_once(handles):
"""Convert handles to IDs on first run. Store the result."""
known = json.loads(STORE.read_text()) if STORE.exists() else {}
for h in handles:
if h not in known:
uid = handle_to_id(h)
if uid:
known[h] = uid
STORE.write_text(json.dumps(known, indent=1))
return known
def refresh(known):
"""Query by ID. Detect and report renames instead of losing the account."""
for original, uid in known.items():
result = id_to_handle(uid)
if result is None:
print(f" {original}: gone (deleted or suspended)")
continue
current, name = result
if current.lower() != original.lower():
# ★the account didn't disappear — it was renamed★
print(f" {original} → @{current} ({name})")
refresh(resolve_once(["nasa", "esa"]))
⚠️ The distinction this buys you: "gone" and "renamed" become two different outcomes instead of one confusing one. Handle-keyed monitoring reports both as a 404 — see what a missing account actually means.
Looking up many accounts at once
Resolving a list one call at a time works but costs a call per account. For a large watchlist there's a batch path, which is the difference between 500 calls and a handful — and call count is what drives your bill.
Either way, resolve once and store. ★A watchlist should be resolved on the day you build it, not on every run.★ IDs don't change, so re-resolving is pure waste.
What you can't do
Being explicit, because these come up constantly:
You can't find an account by email address. Not through search, not through any API. X once supported contact-based discovery for people who'd opted in; it isn't a public lookup.
You can't find an account by phone number. Same answer, same reason. ★Anything claiming to do either is either guessing or working from a leaked dataset.★
You can't get an ID for a deleted or suspended account. The lookup returns nothing. If you recorded the ID earlier you keep the number, but nothing resolves from it.
You can't see someone's full handle history. X doesn't publish previous handles. You'd only know a rename happened if you were watching before and after.
Questions people ask
What is a Twitter user ID? A permanent numeric identifier assigned at signup. Unlike the handle, it never changes.
How do I find my Twitter ID? Any profile lookup returns it. It isn't shown in the interface, so you need a lookup or a third-party finder.
How do I convert a Twitter ID to a username? A lookup by ID returns the current handle — the reverse direction, and the one that rescues you after a rename.
How do I find someone's Twitter ID? Look up their handle; the ID comes back with the profile. It's public information.
Does the Twitter ID change if someone changes their username? No. ★That's the entire reason to store it.★
Can two accounts have the same ID? No. IDs are unique and never reissued, even after an account is deleted.
What happens to an ID when an account is deleted? It stops resolving. The number isn't reassigned to anyone else.
Can I find a Twitter account by email? No. There's no public lookup by email.
Can I find a Twitter account by phone number? No, for the same reason. Anything offering this isn't using a legitimate route.
Why is my Twitter ID lookup returning nothing? The account is deleted, suspended, or the ID is wrong — often from integer precision loss. Check the ID is being handled as a string.
Why do IDs need to be strings? They exceed the safe integer range in some languages. JavaScript silently rounds above 2^53, producing IDs off by one or two that fail lookups with no visible cause.
How long is a Twitter user ID? Varies with signup date. Early accounts have short IDs; recent ones are 19 digits.
Can I tell how old an account is from its ID? Roughly — lower IDs are older. It's an ordering, not a timestamp. The profile's join date is the accurate figure.
How do I look up many accounts at once? Iterate, or use a batch path if you're resolving a large list. Resolve once and store the results.
Should I store handles or IDs? ★IDs, always.★ Store the handle too if you want to display it, but key on the ID.
How do I know if an account changed its handle? Query by ID and compare the returned handle to what you stored. That's the only reliable detection.
Can I see an account's previous usernames? No. X doesn't publish handle history.
What's the difference between user ID and tweet ID? Different identifier spaces — one identifies an account, the other a post. Both are permanent and both should be strings.
Is a Twitter ID private? No, it's public information attached to a public profile.
How do I get IDs for my followers? Follower lists return full profiles including IDs — see paging through follower lists.
Do IDs work across twitter.com and x.com? Yes. The rename changed the domain, not the identifier system.
Can I search for accounts by ID pattern? No. IDs aren't searchable; you look up a specific one.
What if I only have an old handle? Try it — if it 404s or belongs to someone else, and you never stored the ID, searching the display name is the remaining option.
Is there a Twitter ID finder? Any profile lookup returns it — the ID comes back with the profile, so ★no dedicated "finder" is needed★.
How do I search by Twitter ID? Look the account up by ID directly. ★That resolves even after a rename★, which is the whole reason to store IDs.
How do I convert a user ID to a username? Fetch the profile by ID; the current handle is on it. ★The ID is the input that always works.★
How do I find a user by ID? Same call. ★Handle → ID is convenient; ID → handle is the one that survives time.★
Can I search for someone using their ID? Yes, and it is the reliable direction. ★Handles get changed and reused; IDs never do.★
Why store the ID instead of the handle? ★Because a handle can be released and claimed by a stranger★ — a stored handle can silently start pointing at the wrong person.
Does the ID change if the account is renamed? No. That is the entire point — ★renaming changes everything visible except the ID★.
Is the ID visible in the app? Not directly. ★It comes back on any profile fetch★, which is where practically everyone gets it.
If you're building on this
One rule covers most of it: ★resolve handles to IDs once, store the IDs, and query by ID from then on.★
It costs one call per account at setup and eliminates an entire class of silent failure — the kind where your system keeps returning data about an account that isn't the one you meant to watch.
Our API supports both directions — handle to ID and ID to handle — plus a batch path for resolving lists. Read-only, flat price per call, no rate limit of your own to manage.
What it can't do: find accounts by email or phone. Those aren't public lookups, and nothing legitimate offers them.
Related reading: finding an account when you only half-remember it · what a missing account actually means · paging follower lists · what call volume costs.