Twitter/X Profile API
X profile: verified + blue/legacy/identity, displayName, avatar/banner, tipjar→contact{}, expanded website.
Paste a profile URL or @handle and get clean JSON. Canonical profile core: platform, id, username, url, displayName, bio, avatar, banner, followers, following, postCount, verified, createdAt. No handle/name/profileImage/bannerImage/tweetCount twins — those names are gone, not a one-release alias window. Identity-card keys stay on the set when unpublished: location, website, businessAffiliatesCount, creatorSubscriptionsCount, affiliate, bioUrls[], withheldInCountries are null/0/empty, never missing. null vs 0/false: present none is 0/false; omitted is null on the HTML fallback. Guest GraphQL (source=native) omits empty parents (no business_account object) — those independent counts and verification bits become 0/false because Twitter did not send a distinguishable unknown. Split fields (fastFollowers / normalFollowers) stay null when omitted so we never invent 0+0 against followers. verified is derived: isBlueVerified OR isLegacyVerified OR isIdentityVerified OR (affiliate != null). A null bit is treated as false in that OR — it cannot hide a known badge. Verification lives once, on verification{isBlueVerified, isLegacyVerified, isIdentityVerified, verifiedType, reason, verifiedSince}; affiliate is a sibling (object or null). reason is the tooltip text with X's "Learn more" CTA stripped. Trust signals: followers = normalFollowers + fastFollowers when both splits are present; possiblySensitive. followersIsApproximate / followingIsApproximate / postCountIsApproximate use CP-F (true when v ≥ 10000 and v % 100 === 0). Outreach: tipjarSettings (camelCase isEnabled) + contact{emails,paymentHandles,links} always keyed. Cashtags like $NPCBRO land in paymentHandles, not links; links does not repeat website. website / bioUrls[].expandedUrl are expanded (not raw t.co). Twitter-surface extras (fastFollowers, listedCount, pinnedTweetIds, tipjarSettings, profileImageShape, …) stay at the top level — they are not a second contract and are not namespaced under raw. Also listedCount, mediaCount, likesCount, pinnedTweetIds, highlightedTweets. source + timings on every 200 (native | cache). Flat 1 credit. cache=true uses the 1-hour profile TTL (0 credits on hit); pass cacheMaxAge=1d|3d|7d|14d|30d for a longer window. Envelope includes cached, creditsUsed, requestId, fetchedAt, cachedAt.
Request
- Base URL: https://api.captapi.com
- URL: https://api.captapi.com/v1/twitter/profile
- Auth: one of:
- HTTP bearer
- API key in header X-API-Key
Query parameters
Twitter/X profile URL or @handle, e.g. https://x.com/username. The URL platform must match this endpoint's platform. Do not pass cross-platform URLs, e.g. YouTube to TikTok, Instagram to Facebook, LinkedIn to X/Twitter, or Pinterest to Rumble.
Set true to use the 1-hour profile cache (0 credits on hit). Default false — always fetch fresh. Prefer cacheMaxAge for 1d–30d.
Max age of a cached response: 1d, 3d, 7d, 14d, or 30d. When set, enables caching with that TTL.
Response
Success. The data object for this endpoint.
Changes
No recorded changes to this operation across all 3 revisions of this API.