---
title: "Twitter/X Profile API"
method: GET
path: "/v1/twitter/profile"
tags: ["Twitter / X"]
---

# Twitter/X Profile API

`GET /v1/twitter/profile`

## 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`

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.

Docs: https://captapi.com/apis/twitter-profile

## Query parameters

- `url` string, required
- `cache` boolean
- `cacheMaxAge` '1d' | '3d' | '7d' | '14d' | '30d'

## Response `200`

Success. The data object for this endpoint.

- object
  - `success` unknown, required
  - `data` object, required
    - `platform` string: Platform identifier for this response (matches the endpoint's platform).
    - `url` string: Canonical URL of the item.
    - `id` string: Stable platform ID for the item.
    - `username` string: Canonical @handle without @. No handle twin.
    - `displayName` string: Profile display name. No name twin — that alias window is closed.
    - `name` string: Name of the item or account. On profile endpoints: deprecated alias of displayName (one release).
    - `bio` string: Profile bio. Canonical across profile endpoints (prefer over description on YouTube).
    - `location` string: Profile location string. Always keyed; null when unpublished.
    - `verified` boolean: Derived — isBlueVerified OR isLegacyVerified OR isIdentityVerified OR (affiliate != null). Not a separate Twitter field. A null bit is treated as false in the OR.
    - `isBlueVerified` boolean: Whether the account has blue-check verification.
    - `isIdentityVerified` boolean: Is identity verified. Example: false.
    - `verification` object
      - `isBlueVerified` boolean: Whether the account has blue-check verification.
      - `isIdentityVerified` boolean: Is identity verified. Example: false.
      - `verifiedType` string: Verified type. Example: "Government".
      - `reason` string: Why X shows this account as verified. Tooltip CTA ("Learn more") is stripped; leftover whitespace is collapsed.
      - `verifiedSince` string: Verified since. Example: "2009-08-07T19:53:50.000Z".
    - `followers` integer: Total followers. Equals normalFollowers + fastFollowers when both splits are present (X's own split; fastFollowers is the suspicious-follower bucket).
    - `following` integer: Number of accounts followed.
    - `fastFollowers` integer: Fast followers. Example: 0.
    - `normalFollowers` integer: Normal followers. Example: 92239064.
    - `tweetCount` integer: Total number of tweets.
    - `likesCount` integer: Likes count. Example: 16904.
    - `mediaCount` integer: Total number of media posts.
    - `listedCount` integer: Listed count. Example: 97014.
    - `pinnedTweetIds` string[]: Pinned tweet ids (array).
    - `website` string: Expanded profile website (not raw t.co). Always keyed; null when unpublished. Not repeated in contact.links.
    - `contact` object
      - `links` string[]: Links listed on the page.
    - `tipjarSettings` object
      - `is_enabled` boolean: Is enabled. Example: false.
    - `profileImage` string: Profile image URL. Deprecated alias of avatar on Instagram/Twitter/Threads/TikTok profile endpoints (one release).
    - `bannerImage` string: Banner image URL. Deprecated alias of banner on Twitter (one release).
    - `profileImageShape` string: Profile image shape. Example: "Square".
    - `possiblySensitive` boolean: Possibly sensitive. Example: false.
    - `highlightedTweets` integer: Highlighted tweets. Example: 265.
    - `creatorSubscriptionsCount` integer: Creator-subscriptions count. Always keyed. Same null-vs-0 rule as businessAffiliatesCount — both are 0 or both are null on a given path, never mixed.
    - `businessAffiliatesCount` integer: X business-affiliates count. Always keyed. Present none is 0. GraphQL omit → 0 (empty business_account is dropped). HTML omit → null.
    - `createdAt` string: Creation date (ISO 8601).

## Other responses

- `400`: Bad request: wrong platform URL, unknown endpoint, or an invalid parameter value. Not billed.
- `401`: Missing, invalid or revoked API key. Not billed.
- `402`: Not enough credits for this request. Not billed.
- `404`: The resource does not exist or is not public. Not billed.
- `422`: A required parameter is missing or has the wrong type. Not billed.
- `429`: Rate limit reached. Wait for Retry-After seconds. Not billed.
- `502`: The platform could not be reached or returned nothing usable. Retryable, not billed. 503 and 504 use the same envelope.

---

[API](https://skmtc.dev/captapi/apis/captapi-api.md) · [All operations](https://skmtc.dev/captapi/apis/captapi-api/llms.txt) · [OpenAPI document](https://skmtc.dev/captapi/apis/captapi-api/revisions/c9b9ac5ff1bd?raw)
