One handle in. Clean JSON out.
Give this endpoint an X (Twitter) handle and it returns that account's public profile as JSON: follower and following counts, post count, bio, join date, location, avatar and verification flag. No X developer account, no OAuth dance, no paid API tier. One GET to /v1/twitter/profile, 5 credits per lookup.
The difference
On the left, what a headless browser hands you. On the right, what the endpoint hands you.
<article data-testid="tweet" class="css-175oi2r r-1adg3ll r-1ny4l3l"><div class="css-175oi2r r-18u37iz"><div dir="ltr" class="css-901oao r-1nao33i">Shipping notes: response times are down 40% after this week's cache work.</div></div><div role="group" aria-label="90211 views, 1211 likes, 204 reposts" class="css-175oi2r r-1kbdv8c"><div data-testid="like"><span class="css-1jxf684">1,211</span></div><div data-testid="retweet"><span>204</span></div></div><time datetime="2026-07-06T08:15:00.000Z">8h</time><script>window.__INITIAL_STATE__={"entities":{"tweets":{"entities":{"186112... {"data": {"platform": "twitter","handle": "XDevelopers","name": "Example Creator","bio": "Tutorials and behind-the-scenes. New video every Tuesday.","verified": true,"metrics": {"followers": 2450318,"following": 132,"posts": 842}},"request_id": "req_01JZX4M8Q2TE9W"}
The payload
One object per handle, describing the account rather than any of its posts. Think of it as the header of a profile page turned into structured data: who they say they are, how many people follow them, how long the account has existed, and where they claim to be.
The counters are the figures X shows publicly when the profile is loaded logged out. Follower counts on large accounts drift constantly and the platform is not always precise about them, so treat the number as a reading rather than an audited total. Because profile data changes slowly compared with post engagement, this endpoint sits in the slow cache class — repeat lookups of the same handle inside the window come back in milliseconds and still cost 5 credits.
Everything here is self-reported except the counts. Bio, location and display name are free text the account owner typed. Location in particular is not geocoded and is frequently a joke, an emoji, or empty. Do not build address logic on it.
Lifetime post count including replies and reposts, as X reports it. Deleted posts are not subtracted retroactively in any reliable way.
Pricing
One profile lookup is 5 credits — about 2.5¢ on the monthly plan. $5 covers roughly 200 handles, and calls that fail on a protected or missing account are never charged.
Estimate only, on a full-year basis. 5 credits per returned lookup. Monthly: $5 per 1,000 credits with $4/1,000 top-ups. Annual: $54 per 12,000 credits with $3/1,000 top-ups. We show whichever plan is cheaper for your annual volume, divided by 12. Failed calls are never charged; cache hits cost the same as fresh calls.
Entry price, side by side
Credits are not equivalent units across vendors — each meters differently. Price your own workload on both before deciding on entry price alone. At high volume, several of these are cheaper per credit than we are.
Engineering notes
We document exactly how every endpoint behaves — nulls, caching, billing — so what you ship on day one is still running in month six. No surprises, no support tickets.
X lets people rename themselves, and a freed-up handle can be claimed by someone else. This response is keyed on the handle, so a stored handle that used to point at one account can quietly start pointing at a different one. If you are tracking accounts over months, store `created_at` alongside the handle and treat a sudden change in join date as a signal that you are now looking at a different account.
For an account with a few hundred followers the number is exact. For one with millions it is a figure X computes and updates on its own schedule, and it can move up and down without anyone gaining or losing anything real. Sample on a fixed daily cadence if you want a growth curve, and ignore movements smaller than a fraction of a percent on large accounts.
We read public pages logged out, so a protected (private) account has no public profile body for us to read and a suspended or deleted one has no page at all. All three return an error rather than an object with nulls in it. Failed calls are not charged. There is no mode, flag or parameter that reaches private content.
Profile responses are cached in the slow class because bios and join dates barely move. A cached hit returns in milliseconds and sets `x-cache: hit`; it costs the same 5 credits as a fresh call. If you are running a daily follower-count snapshot and need the reading to be genuinely fresh, pass `fresh=true` to skip the cache.
A profile describes a person. If you store these responses, that is a processing activity under GDPR and similar regimes even though everything in it is public. Keep a retention period, keep it short, and be ready to delete on request. We do not disclose email addresses, phone numbers or anything else X keeps behind a login, and there is no version of this endpoint that does.
Questions
Call /v1/twitter/profile with the handle and your API key. You get followers, following, post count, bio, join date and verification back as JSON. X's own API requires a developer account, an approved project and a paid tier for most useful access, and the free tier does not cover user lookups at all. This endpoint reads the public profile page instead, so there is nothing to apply for.
5 credits. Credits are $0.005 each on monthly billing and $0.0045 on annual, so a lookup is about 2.5 cents and $5 buys roughly 200 of them. Cached lookups cost the same as fresh ones. Calls that fail — suspended account, protected account, handle that does not exist — are not charged at all.
Send the bare handle: `nasa`, not `@nasa` and not https://x.com/nasa. We pass the value through to the profile lookup as given, so a stray @ or a full URL is the most common cause of a failed call on this endpoint. Handles are case-insensitive on X, so `NASA` and `nasa` reach the same account, and the `handle` field comes back in the casing X stores.
No. A protected account shows nothing publicly, and we only read what a logged-out browser can read, so the call returns an error rather than a stub object. The same applies to suspended and deleted accounts. This is a hard limit, not a plan restriction — there is no upgrade that unlocks private profiles.
Accurate for small accounts, approximate for large ones. X computes public follower counts on its own schedule and the figure for a big account can drift by hundreds without any real change in audience. Use it for scale and for trends measured over days, not for exact reconciliation. Snapshot on a fixed daily cadence so your intervals are even.
It means the account displays a verification badge, nothing more. X has attached that badge to both legacy verification and paid subscriptions, so a true value tells you the account pays for or was granted a badge, not that the person behind it was identity-checked. For vetting, `created_at` and the followers-to-following ratio are usually more informative than the badge.
One handle per call, run concurrently. Nothing in a lookup depends on any other lookup, so a few dozen in flight at once is normal. Deduplicate your handle list first — repeated lookups of the same handle hit the cache but still bill 5 credits each, so the saving is latency, not money.
Next
100 trial credits on signup — no card, key on screen immediately.