X / Twitter Account Origin Intelligence avatar

X / Twitter Account Origin Intelligence

Pricing

from $0.35 / 1,000 account lookup completeds

Go to Apify Store
X / Twitter Account Origin Intelligence

X / Twitter Account Origin Intelligence

Extract X/Twitter account origin signals by username, profile URL, or numeric user ID, including account_based_in, app/source, username changes, and public profile metadata.

Pricing

from $0.35 / 1,000 account lookup completeds

Rating

5.0

(1)

Developer

Arjun Data

Arjun Data

Maintained by Community

Actor stats

2

Bookmarked

47

Total users

22

Monthly active users

15 days ago

Last modified

Share

Look up X/Twitter account origin, username-change history, and public profile data by username, profile URL, or numeric user ID. Review where X says an account is based, the app/source it reports, and its audience and verification details without supplying X credentials.

Key data includes:

  • account_based_in - the country or region reported by X
  • account_source - the application/source reported by X
  • username_changes_count - the number of recorded username changes
  • username_last_changed_at - the latest recorded username-change time
  • created_country_accurate - whether X marks the creation-country signal as accurate
  • user_id - the account's stable numeric X user ID

Use it for account provenance checks, OSINT research, risk review, creator research, lead enrichment, and social media monitoring.

Quick start

  1. Add usernames or profile links under X usernames or profile URLs, or numeric IDs under X user IDs.
  2. Click Start. No X login, cookies, API key, or proxy setup is needed.
  3. Open Output to review profiles and account statuses, then export JSON or CSV.

For example:

{
"screenNames": [
"https://x.com/apify",
"@NASA"
]
}

Use screenNames for plain usernames, @handles, and full x.com/twitter.com profile URLs. Use userIds for stable numeric X user IDs. You can use either field or both. Equivalent username formats are normalized, and duplicate values within each field are requested only once. If different inputs resolve to the same native X user ID, only the first successful profile is saved and charged. Invalid values are ignored before any X request is made.

Input

FieldTypeRequiredDescription
screenNamesstring[]No*Enter usernames, @handles, or full X/Twitter profile URLs.
userIdsstring[]No*Enter numeric X user IDs such as 3510729917. IDs remain stable after username changes.

Provide at least one valid value in screenNames or userIds. A run accepts at most 100 combined account inputs after normalization and deduplication within each field. The limit applies before successful results are deduplicated by native X user ID. If no valid input remains, or if the combined total exceeds 100, the Actor writes one invalid_input record without a lookup fee and stops before making an X request. Split larger lists across several runs.

No X login, cookies, API key, or proxy setup is required. Apify Proxy routing and internal authentication are handled automatically. Results can be downloaded from the Dataset or used through the Apify API, schedules, webhooks, and integrations.

Output

Each saved account lookup is one Dataset item. Common profile fields are flattened for CSV exports and the Overview and Profile details views. Source fields remain in profile, including enrichment data under X's native field names and object structure. Accounts without accessible profiles receive a status record instead; duplicate successful profiles are saved only once.

{
"status": "success",
"requested_screen_name": "apify",
"requested_user_id": "",
"user_id": "3510729917",
"screen_name": "apify",
"name": "Apify",
"profile_url": "https://x.com/apify",
"account_based_in": "United States",
"account_source": "Web",
"created_country_accurate": true,
"account_location_accurate": true,
"verification_type": "Business",
"affiliate_username": "ExampleOrg",
"affiliation_name": "Example Org",
"affiliation_url": "https://x.com/ExampleOrg",
"affiliation_badge_url": "https://pbs.twimg.com/profile_images/example_bigger.jpg",
"account_label": null,
"professional_type": "Business",
"professional_categories": [
{
"id": 713,
"name": "Technology",
"icon_name": "IconBriefcaseStroke"
}
],
"username_changes_count": 1,
"username_last_changed_at": "2022-09-26T05:44:58.550Z",
"username_last_changed_at_msec": 1664171098550,
"account_created_at": "2008-03-10T14:27:04Z",
"description": "Web scraping and browser automation platform.",
"location": "",
"website_url": "https://apify.com",
"bio_links": ["https://apify.com"],
"followers_count": 10000,
"following_count": 500,
"tweets_count": 3000,
"media_count": 600,
"likes_count": 2000,
"listed_count": 300,
"verified": false,
"blue_verified": true,
"protected": false,
"possibly_sensitive": false,
"business_affiliates_count": 0,
"creator_subscriptions_count": 0,
"profile_image_url": "https://pbs.twimg.com/profile_images/example_normal.jpg",
"profile_banner_url": "https://pbs.twimg.com/profile_banners/example",
"pinned_tweet_ids": ["1234567890123456789"],
"profile_interstitial_type": null,
"default_profile_image": false,
"can_media_tag": true,
"withheld_scope": null,
"withheld_description": null,
"profile": {
"account_based_in": "United States",
"source": "Web",
"created_country_accurate": true,
"rest_id": "3510729917",
"username_changes": {
"count": "1",
"last_changed_at_msec": "1664171098550"
},
"user_created_at": "Mon Mar 10 14:27:04 +0000 2008",
"user_name": "Apify",
"user_screen_name": "apify",
"location_accurate": true,
"verification": {
"verified": false,
"verified_type": "Business"
},
"professional": {
"professional_type": "Business",
"category": [
{
"id": 713,
"name": "Technology",
"icon_name": "IconBriefcaseStroke"
}
]
},
"pinned_tweet_ids_str": ["1234567890123456789"],
"can_media_tag": true
}
}

Values in this example are illustrative. Fields may be empty when X does not provide them for an account.

What does each result status mean?

StatusMeaningCompleted lookup fee
successAccount origin and public profile data were retrieved.Yes
not_foundThe account was not found or X did not return an accessible account.Yes
suspendedX explicitly reports that the account is suspended.Yes
request_failedA temporary request or response problem prevented the lookup from completing.No
invalid_inputNo valid account inputs remained, or the input limit was exceeded.No
partialThe run stopped early after repeated request failures; this summary lists accounts not checked.No

The Actor start fee still applies when a run starts. A not_found or suspended result is not a request failure and does not stop the remaining accounts from being processed.

If a requested username or user ID is not found, the Actor records the condition and continues with the remaining accounts:

{
"requested_screen_name": "unknown_user",
"requested_user_id": "",
"user_id": "",
"screen_name": "unknown_user",
"status": "not_found",
"error": "X user @unknown_user was not found."
}

When X explicitly reports that an account is suspended, it receives a separate status and message:

{
"requested_screen_name": "elonjet",
"requested_user_id": "",
"user_id": "",
"screen_name": "elonjet",
"status": "suspended",
"error": "X user @elonjet is suspended."
}

Empty lookup responses are confirmed before a not_found result is saved. If X reports an unavailable account without a suspension reason, the status remains not_found with the message "was not found or is unavailable"; it is not proof that an account never existed. The suspended label is used only when X supplies an explicit suspension reason.

If a profile cannot be checked after automatic retries or within the request time limit, the Actor writes an uncharged failure record:

{
"requested_screen_name": "example_user",
"screen_name": "example_user",
"status": "request_failed",
"error": "AboutAccountQuery failed after 5 attempts: connection timed out."
}

Temporary connection problems are retried automatically. An individual failure normally leaves the remaining accounts available to process. If X requests keep failing, the Actor stops early and saves an uncharged partial record listing the accounts that were not checked. Previously saved results remain available. A not_found or suspended result does not stop the remaining accounts from being processed.

Output fields

Field groupFields
Resultstatus, requested_screen_name, requested_user_id, error
Identityuser_id, screen_name, name, profile_url, description, location, website_url, account_created_at
Account originaccount_based_in, account_source, created_country_accurate, account_location_accurate
Verification and affiliationverification_type, affiliate_username, affiliation_name, affiliation_url, affiliation_badge_url, account_label
Professional profileprofessional_type, professional_categories, bio_links, pinned_tweet_ids
Username historyusername_changes_count, username_last_changed_at, username_last_changed_at_msec
Audience and activityfollowers_count, following_count, tweets_count, media_count, likes_count, listed_count
Account stateverified, blue_verified, protected, possibly_sensitive, business_affiliates_count, creator_subscriptions_count, profile_interstitial_type, default_profile_image, can_media_tag, withheld_scope, withheld_description
Imagesprofile_image_url, profile_banner_url
Original dataprofile preserves the Actor's earlier source-field shape and adds enrichment fields under their native X names and object structures.

account_source, following_count, tweets_count, likes_count, and blue_verified are clearer top-level names for native values also retained as profile.source, profile.friends_count, profile.statuses_count, profile.favourites_count, and profile.is_blue_verified. ISO date fields are derived from X's native date or millisecond timestamp values; the raw username-change timestamp is also retained.

Run with the API

Replace YOUR_APIFY_TOKEN with your Apify API token.

curl -X POST \
"https://api.apify.com/v2/actors/arjun_code~x-twitter-account-origin-scraper/runs" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"screenNames":["elonmusk"],"userIds":["3510729917"]}'

The request starts an Actor run. Use the run's default dataset ID from the API response to retrieve results after the run succeeds.

Run with Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("arjun_code/x-twitter-account-origin-scraper").call(
run_input={"screenNames": ["elonmusk"], "userIds": ["3510729917"]}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

Run with JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('arjun_code/x-twitter-account-origin-scraper').call({
screenNames: ['elonmusk'],
userIds: ['3510729917'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Pricing

This Actor uses pay-per-event pricing:

ChargeBase priceWhat it covers
Actor start$0.00005 per start eventOne start event at the Actor's available memory settings.
Account lookup completed$0.0005 per account ($0.50 / 1,000)Each saved success, confirmed not_found, or explicitly suspended result.

Subscription discounts

Save up to 30% on completed lookups with higher Apify subscription tiers. Your eligible price applies automatically based on your Apify subscription, not the number of accounts you enter. No discount code is needed.

Apify subscription tierPer completed lookupPer 1,000 completed lookupsLookup discount
FREE$0.0005$0.50Base price
BRONZE$0.00045$0.4510%
SILVER$0.0004$0.4020%
GOLD / PLATINUM / DIAMOND$0.00035$0.3530%

Discounts apply only to the completed lookup fee. The Actor start fee remains $0.00005 at every tier.

For example, 100 completed lookups in one run cost $0.05005 on FREE or $0.03505 on GOLD, PLATINUM, or DIAMOND, including one start event. The same lookup rate applies whether the results contain profiles, confirmed not-found accounts, suspended accounts, or a mix. A spending limit can stop the run before all inputs are checked.

Invalid input, request failures, unprocessed accounts, and partial summaries do not incur a completed lookup fee; the start fee still applies when the run starts. Automatic retries do not create extra lookup fees. Duplicate successful profiles are saved and charged only once.

For developers, the completed lookup event retains its existing ID, profile-result. The Actor stops querying when your spending limit cannot cover another completed lookup. See the Pricing tab for current prices and discounts for your subscription.

Use cases

  • Verify account-origin signals during OSINT research
  • Review username-change history and stable numeric user IDs
  • Enrich creator, influencer, lead, or customer records
  • Support social media monitoring and account risk analysis
  • Compare public audience, activity, and verification metadata

Try a ready-made example or enter your own screen names in the Actor input:

Continue your X research workflow

GoalActor
Discover public accounts by keyword, profession, niche, or locationX (Twitter) People Search Scraper
Expand from a known profile through X's native Similar to recommendationsX (Twitter) Similar Accounts Finder — No Login
Export followers or accounts followed by one or more profilesX Followers & Following Scraper — No Login
Inspect account origin, signup source, and username-change historyX / Twitter Account Origin Intelligence
Monitor profile, username, verification, and follower changes over timeX (Twitter) Profile & Username Change Monitor

A practical workflow is: discover accounts by keyword, expand each seed through native Similar to recommendations, export selected audiences, inspect origin signals, then monitor shortlisted profiles over time.

Limitations

  • Results depend on data currently returned by X/Twitter and individual fields may be empty or unavailable.
  • Account-origin signals are reported by X and should not be treated as independent proof of a person's identity, nationality, or physical location.
  • Accounts X explicitly reports as suspended are returned with status: "suspended". Not-found, deleted, renamed, or otherwise unavailable accounts remain not_found; X may not provide a more specific reason. The Actor continues processing the remaining accounts.
  • Temporary request failures are retried automatically. An uncharged request_failed record identifies an account that could not be checked; a partial record explains when a run stops early because X remains unavailable.
  • X may change its response structure or access controls, which can temporarily affect availability.
  • Accounts are processed sequentially and saved in small batches. Previously saved results remain available if a later request fails.

Privacy and responsible use

This Actor processes publicly accessible X/Twitter account and profile metadata. Use the results only for lawful purposes and in accordance with applicable privacy laws, X's terms, and Apify's terms. Do not use account-origin signals alone to make high-impact decisions about individuals.

Support

If a run fails or a field is unexpectedly missing, open an issue from the Actor's Issues tab and include the run ID. Do not post API tokens, cookies, or other credentials in public issues.