# Twitter Profile Scraper - X Followers, Bio & Verified Badge (`topapi/x-profile-scraper`) Actor

Scrape X (Twitter) profiles in bulk from handles, URLs or ids: followers, following, posts, likes and listed counts, bio, website, location, join date, verified type, pinned post and recent activity. No login or cookies. Monitor mode returns only changed profiles.

- **URL**: https://apify.com/topapi/x-profile-scraper.md
- **Developed by:** [Top Api](https://apify.com/topapi) (community)
- **Categories:** Social media, Lead generation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.14 / 1,000 profiles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Twitter Profile Scraper do?

**Twitter Profile Scraper** extracts public X (Twitter) profiles from x.com and turns a list of handles, profile URLs or user ids into structured rows: one account with its followers, following, posts, likes and listed counts, bio, website, location, join date, verified badge, pinned post and recent activity. Built for influencer marketers, sales and lead-gen teams, and analysts who need clean Twitter profile data without copying it by hand.

X Profile Scraper - Twitter Profile Scraper - X.com User Scraper - Twitter Follower Count Checker

<a href="https://console.apify.com/actors/7WTqvvkL6e0zXIHkR"><img src="https://api.apify.com/v2/key-value-stores/qNQ9zP0xaj2yxGeMY/records/x-profile-scraper-source.png" alt="Public X (Twitter) profile page that Twitter Profile Scraper turns into a row" style="width:70%"></a>

- **Full Twitter profile per row:** id, handle, display name, bio with links expanded, website, location, followers, following, posts, likes, listed and media counts, join date, avatar and banner.
- **Verification and status:** blue, Business (gold) and Government (grey) check marks, protected accounts, affiliate badges, plus a status row for handles that do not exist or are suspended.
- **Activity signals from the same page, at no extra request:** last post date, days since the last post, average likes, replies, reposts and views of the latest posts, and an engagement rate, all read from the same page.
- **No login, cookies or X API key:** paste handles, `@handles`, x.com or twitter.com URLs, or numeric ids.
- **Monitor mode:** re-check the same accounts on a schedule and get only the profiles whose followers, posts, bio or badge changed, with the deltas.
- **Pay only for delivered profiles:** no start fee.
- **Export anywhere:** JSON, CSV, Excel, XML; schedules, webhooks, Make, Zapier, n8n, Google Sheets, Slack, the Apify API and MCP.

### What data can you get from an X (Twitter) profile?

<table>
<tr>
<td>🆔 User id (`id`)</td>
<td>👤 Handle (`userName`)</td>
<td>📝 Display name</td>
</tr>
<tr>
<td>💬 Bio (`description`)</td>
<td>🔗 Bio links and mentions</td>
<td>🌐 Website</td>
</tr>
<tr>
<td>📍 Location</td>
<td>📅 Join date (`createdAt`)</td>
<td>👥 Followers</td>
</tr>
<tr>
<td>➡️ Following</td>
<td>🧾 Posts count (`statusesCount`)</td>
<td>❤️ Likes count (`favouritesCount`)</td>
</tr>
<tr>
<td>📋 Listed count</td>
<td>🖼️ Media count</td>
<td>✅ Verified badge and type</td>
</tr>
<tr>
<td>🔒 Protected flag</td>
<td>🏢 Affiliate badge</td>
<td>📌 Pinned post id</td>
</tr>
<tr>
<td>🧑 Avatar (400x400) and banner</td>
<td>🕒 Last post date</td>
<td>📈 Engagement rate</td>
</tr>
<tr>
<td>👍 Average likes, replies, reposts</td>
<td>👀 Average views</td>
<td>📰 Latest 5 posts (add-on)</td>
</tr>
</table>

On a 22-profile test run every row had the id, handle, name, follower, following and post counts, join date and verification fields; 86% had a bio, 73% a website, 82% likes/listed/media counts and 91% a last-post date.

### How to scrape Twitter profiles with Twitter Profile Scraper

1. [Create a free Apify account](https://console.apify.com/sign-up): $5 of monthly credit, no card needed.
2. Open [Twitter Profile Scraper](https://apify.com/topapi/x-profile-scraper) and click **Try for free**.
3. Paste handles, profile URLs or ids into **Handles, profile URLs or user ids**, one per line.
4. Optionally set filters (minimum followers, verified only, bio keywords) and **Max profiles to deliver**.
5. Click **Start**. Profiles stream into the dataset in about a second each.
6. Open the **Storage** tab and **Export** as JSON, CSV or Excel, or let a schedule run it for you.

### ⬇️ Input

| Parameter | Type | Description |
|---|---|---|
| **🔍 What to scrape** | | |
| `handles` | List | **Required** (prefilled with `nasa`, `apify`). Handles, `@handles`, x.com / twitter.com profile URLs, `x.com/i/user/<id>` links or `id:<number>`. |
| **✂️ Refine results** | | |
| `minFollowers` / `maxFollowers` | Integer | Follower range. Default `0` = no limit. |
| `verifiedOnly` | Boolean | Only accounts with a blue, Business or Government check mark. Default `false` |
| `withWebsiteOnly` | Boolean | Only accounts that list a website. Default `false` |
| `bioKeywords` | List | Only accounts whose bio or name contains one of these words. |
| `excludeProtected` | Boolean | Drop protected (locked) accounts. Default `false` (they are delivered with their public counts). |
| `activeWithinDays` | Integer | Only accounts whose latest post or reply is at most N days old. Default `0` = any. |
| **➕ Extra data** | | |
| `includeLatestTweets` | Boolean | Adds `latestPosts`: up to 5 latest original posts and replies. Charged as **posts**. |
| `tweetsPerProfile` | Integer | 1-5 posts to attach. Default `5` |
| `includePinnedTweet` | Boolean | Adds the full `pinnedPost`. Charged as **posts** (once per profile, together with latest posts). |
| `includeUnavailable` | Boolean | Status rows for missing, suspended or invalid inputs. Default `false` |
| **🔁 Monitoring** | | |
| `monitorMode` | Boolean | Deliver only accounts that are new or changed since the last run. Pair with a schedule. |
| `monitorStoreName` | String | Key-value store that keeps the per-account memory. Default `x-profile-monitor` |
| **📦 Output** | | |
| `maxItems` | Integer | Stop after this many delivered profiles. Default `0` = the whole list. |
| `compact` | Boolean | Core fields only, sized for AI agents and MCP. |
| **⚙️ Advanced** | | |
| `proxyConfiguration` | Proxy | Default: no proxy, with automatic fallback to the Apify datacenter and residential pools if X refuses a request. |
| `maxConcurrency` | Integer | Profiles loaded in parallel, 1-20. Default `8` |

#### Input JSON

```json
{
  "handles": ["nasa", "@apify", "https://x.com/stripe", "id:12"],
  "minFollowers": 1000,
  "withWebsiteOnly": true,
  "includeLatestTweets": true,
  "tweetsPerProfile": 3,
  "maxItems": 500
}
```

#### Paste Twitter handles, URLs or ids in one list

Every line is resolved on its own, so a spreadsheet column works as it is. **Do:** `nasa`, `@nasa`, `https://twitter.com/nasa`, `https://x.com/nasa/status/123` (the handle is read from the URL). **Don't:** paste search or hashtag links such as `x.com/search?q=nasa`; they are reported as invalid input.

#### Prefix short numeric Twitter ids with id:

X handles can be all digits, so a short number like `12345` is looked up as a handle. A 16-20 digit number is read as a user id automatically; for older, shorter ids write `id:11348282` or paste `x.com/i/user/11348282`. If you list a handle and its id, the profile is delivered once.

#### Use filters to keep only the Twitter profiles you want

`minFollowers`, `verifiedOnly`, `withWebsiteOnly`, `bioKeywords`, `excludeProtected` and `activeWithinDays` run after the profile is read. A list of 1,000 handles filtered down to 200 delivers 200 profiles.

### ⬆️ Output

Every X account becomes one dataset item. Here is the table view of a real run:

<a href="https://console.apify.com/actors/7WTqvvkL6e0zXIHkR"><img src="https://api.apify.com/v2/key-value-stores/qNQ9zP0xaj2yxGeMY/records/x-profile-scraper-output.png" alt="Twitter Profile Scraper output table with followers, verification and activity" style="width:70%"></a>

And one row as JSON (shortened):

```json
{
  "status": "active",
  "id": "3510729917",
  "userName": "apify",
  "name": "Apify",
  "url": "https://x.com/apify",
  "description": "Thousands of Actors to automate your business, get real-time web data, and integrate your apps and agents. ...",
  "website": "https://apify.com",
  "location": "The Interwebz",
  "followers": 17657,
  "following": 301,
  "statusesCount": 4986,
  "favouritesCount": 4470,
  "listedCount": 150,
  "mediaCount": 1266,
  "createdAt": "2015-09-01T08:38:01.064Z",
  "isBlueVerified": false,
  "verifiedType": "Business",
  "protected": false,
  "profilePicture": "https://pbs.twimg.com/profile_images/2036008913192316928/yuW3cobE_400x400.png",
  "pinnedTweetId": "2087572956683567110",
  "lastPostAt": "2026-10-03T12:19:29.000Z",
  "recentEngagementRatePct": 0.0411
}
```

#### Fields

Fill is measured on a 22-profile platform run (big brands, government accounts, small personal accounts and one protected account).

| Field | Type | What it is | Fill |
|---|---|---|---|
| `id`, `userName`, `name`, `url` | string | Identity; `id` stays stable when a handle changes | 100% |
| `followers`, `following`, `statusesCount` | integer | Follower, following and post counts | 100% |
| `favouritesCount`, `listedCount`, `mediaCount` | integer | Likes given, public lists, media posts (`countsSource` says where they came from) | 82% |
| `description`, `descriptionUrls`, `descriptionMentions` | string, list | Bio with t.co links expanded, plus its links and @mentions | 86% |
| `website`, `websiteDisplay` | string | Profile link field | 73% |
| `location` | string | What the owner typed | 55% |
| `createdAt`, `accountAgeDays` | string, integer | Join date (ISO 8601) | 100% |
| `isBlueVerified`, `isVerified`, `verifiedType` | boolean, string | Check mark; `Business` or `Government` when gold or grey | 100% (type 41%) |
| `protected`, `possiblySensitive` | boolean | Locked account, sensitive-media flag | 100% |
| `profilePicture`, `coverPicture`, `profileImageShape` | string | Avatar 400x400, banner, Circle or Square | 100% / 86% / 100% |
| `affiliation`, `businessAffiliatesCount` | object, integer | Affiliate badge, a verified organisation's affiliate count | 9% / 41% |
| `pinnedTweetId`, `pinnedTweetIds` | string, list | The pinned post | 50% |
| `birthdate` | string | Only when the owner made it public | 5% |
| `lastPostAt`, `daysSinceLastPost` | string, integer | Latest original post or reply | 91% |
| `recentAvgLikes`, `recentAvgReplies`, `recentAvgReposts`, `recentAvgViews` | number | Averages over the latest posts | 91% (views 77%) |
| `recentEngagementRatePct` | number | (likes + replies + reposts + quotes) / followers x 100 | 91% |
| `followersToFollowingRatio`, `postsPerDay` | number | Derived ratios | 100% |
| `latestPosts`, `pinnedPost` | list, object | With the posts add-on | 91% / 50% |

#### Latest and pinned Twitter posts (add-on)

With `includeLatestTweets`, each profile gets the latest original posts and replies (no reposts) that its public page shows: 5, or 4 when the account has a pinned post, which arrives separately as `pinnedPost`.

```json
{
  "id": "2106358473772408931",
  "url": "https://x.com/apify/status/2106358473772408931",
  "text": "Did your last “agent” actually need to be an agent? 👀",
  "createdAt": "2026-10-03T12:19:29.000Z",
  "lang": "en",
  "likes": 6, "replies": 1, "reposts": 0, "quotes": 0, "bookmarks": 0, "views": 558,
  "isReply": false, "isQuote": false, "isLongPost": false,
  "hashtags": [], "mentions": [], "urls": [], "media": []
}
```

### How can I use Twitter profile data?

- 🎯 **Influencer marketers:** shortlist creators by follower range, engagement rate and last post date, and skip dormant accounts.
- 💼 **Sales and lead-gen teams:** enrich a list of company or founder handles with website, location and verified status.
- 📊 **Brand and competitor analysts:** track follower growth and posting cadence of competitors with monitor mode and a daily schedule.
- 🔎 **Researchers and journalists:** check account age, verification type, affiliate badges and suspension status in bulk.
- 🤖 **AI and data teams:** feed compact profile rows to an LLM agent through the API or MCP.
- 🧹 **CRM hygiene:** find handles that were renamed (`id` stays the same), suspended or deleted.

### How much does it cost to scrape Twitter profiles?

Twitter Profile Scraper is pay-per-result: **$0.00014 per profile** ($0.14 per 1,000 profiles), no start fee. Latest and pinned posts are an optional add-on at **$0.00065 per profile** that receives them.

| Profiles | Profile cost | With posts add-on |
|---:|---:|---:|
| 10 | $0.0014 | $0.0079 |
| 100 | $0.014 | $0.079 |
| 1,000 | $0.14 | $0.79 |
| 10,000 | $1.40 | $7.90 |

There is nothing else to pay: Apify platform usage is included in these prices. A 25-profile run took 15 seconds on 256 MB.

### Integrations, API, scheduling & MCP

- **Schedules:** run Twitter Profile Scraper hourly, daily or weekly from the **Schedules** tab; turn on `monitorMode` to get only changed profiles.
- **Webhooks:** fire a URL when a run finishes and push new rows to your CRM, a sheet or Slack.
- **No-code:** Make, Zapier, n8n, Google Sheets, Airtable and Slack via [Apify integrations](https://docs.apify.com/integrations).
- **API:** call it from Node.js or Python with `apify-client`; code is on the [API tab](https://apify.com/topapi/x-profile-scraper/api/python) and in the [Apify API reference](https://docs.apify.com/api/v2).
- **MCP / AI agents:** connect Claude, Cursor or any MCP client through the [MCP tab](https://apify.com/topapi/x-profile-scraper/api/mcp) and ask for Twitter profiles in plain language; `compact` keeps the payload small.

A daily follower tracker is one API call: `{"handles": ["competitor1", "competitor2"], "monitorMode": true, "monitorStoreName": "competitors"}` on a schedule. Each run returns only the accounts that changed and adds `previousStats`, `deltas` and `changedFields`.

### More social media scrapers from TopApi

<table>
<tr>
<td>📸 <a href="https://apify.com/topapi/instagram-scraper">Instagram Scraper</a></td>
<td>🎵 <a href="https://apify.com/topapi/tiktok-scraper">TikTok Scraper</a></td>
<td>🎬 <a href="https://apify.com/topapi/tiktok-video-scraper">TikTok Video Scraper</a></td>
</tr>
<tr>
<td>📣 <a href="https://apify.com/topapi/facebook-search-posts-scraper">Facebook Search Posts Scraper</a></td>
<td>📍 <a href="https://apify.com/topapi/google-maps-reviews-scraper">Google Maps Reviews Scraper</a></td>
<td>🌐 <a href="https://apify.com/topapi/similarweb-scraper">SimilarWeb Scraper</a></td>
</tr>
<tr>
<td>💼 <a href="https://apify.com/topapi/indeed-jobs-scraper">Indeed Jobs Scraper</a></td>
<td colspan="2">🧭 <a href="https://apify.com/topapi">All TopApi scrapers</a></td>
</tr>
</table>

### Twitter profile data limits & empty runs

- **Speed:** about 0.15-0.5 seconds per profile at the default 8 in parallel; 25 profiles took 5-15 seconds on 256 MB.
- **Likes, listed and media counts** come from X's public embedded timeline, which answers about 30 lookups per IP every 15 minutes and shows no timeline for some accounts. When it does not answer, those three fields are null (never 0) and `countsSource` is null. Every other field comes from the profile page itself. On the test runs they filled for 82% of profiles in a fresh run and 48% in a run made right after another.
- **Latest posts:** the public profile page shows the 5 most recent original posts and replies; reposts are not included, and protected accounts show none.
- **Not available signed out:** professional category, "can DM", the "About this account" panel (account based in, username changes, verified since, identity verification) and follower lists. X shows these only to logged-in users, so they are not in the rows.
- **Monitor memory:** one memory name holds about 8,000 accounts (about 850 bytes each); for bigger lists use several names, one per list.
- **Empty dataset:** the handles did not exist, were suspended, were invalid or were all filtered out. Turn on `includeUnavailable` to get a status row for each.

### FAQ

#### How many Twitter profiles can Twitter Profile Scraper collect in one run?

As many as you paste. Each profile is its own lookup, so a run of thousands of handles works; use `maxItems` as a cost cap and `maxConcurrency` for speed.

#### Can I run Twitter Profile Scraper on a schedule to track follower growth?

Yes. Save your handles as a task, open **Schedules**, pick the cadence and turn on `monitorMode`. Each run delivers only accounts whose followers, posts, bio, website, name or badge changed, with `deltas`. Large accounts gain followers almost every hour, so they will appear on most runs.

#### Does Twitter Profile Scraper work for protected or suspended accounts?

Protected accounts still publish their name, bio and counts, so they are delivered with `protected: true` and no posts. Suspended and deleted handles return a status row with `includeUnavailable`.

#### Can I get tweets with Twitter Profile Scraper?

Yes, the latest original posts and the pinned post, through the posts add-on. For keyword or hashtag search, or a full tweet history, use a dedicated tweet scraper.

#### Can I integrate Twitter Profile Scraper with other apps?

Yes: Make, Zapier, n8n, Google Sheets and Slack via [Apify integrations](https://docs.apify.com/integrations), or [webhooks](https://docs.apify.com/integrations/webhooks) when a run finishes.

#### Can I use Twitter Profile Scraper with the Apify API?

Yes. Start runs and fetch datasets with `apify-client` for [Node.js](https://apify.com/topapi/x-profile-scraper/api/javascript) or [Python](https://apify.com/topapi/x-profile-scraper/api/python).

#### Can I use Twitter Profile Scraper through an MCP server?

Yes. Open the [MCP tab](https://apify.com/topapi/x-profile-scraper/api/mcp), connect your MCP client and ask for X profiles in plain language. Turn on `compact` for smaller rows.

#### Do I need an X account, cookies or an X API key for Twitter Profile Scraper?

No. It reads only what X shows to signed-out visitors; you pass handles, URLs or ids and nothing else.

#### Why did my Twitter Profile Scraper run return no results?

The handles did not exist or were suspended, the inputs were not X handles or URLs, or your filters removed every profile. Turn on `includeUnavailable` and check the run summary.

#### Is it legal to scrape Twitter profiles?

Twitter Profile Scraper extracts only publicly available profile data and does not log in or collect private data. Results may still contain personal data, which is regulated (for example by GDPR), so make sure you have a legitimate purpose before you use it.

#### Your feedback

We keep improving Twitter Profile Scraper. Found a bug or missing a field? Open an issue on the [Issues tab](https://apify.com/topapi/x-profile-scraper/issues/open).

# Actor input Schema

## `handles` (type: `array`):

e.g. "nasa", "@elonmusk", "https://x.com/apify", "twitter.com/jack", "id:11348282". A 16-20 digit number is read as a user id; prefix shorter ids with id:.

## `minFollowers` (type: `integer`):

Keep only accounts with at least this many followers, e.g. 1000. 0 = no minimum.

## `maxFollowers` (type: `integer`):

Keep only accounts with at most this many followers, e.g. 50000 for micro-influencers. 0 = no maximum.

## `verifiedOnly` (type: `boolean`):

Keep only accounts with a blue, gold (business) or grey (government) check mark.

## `withWebsiteOnly` (type: `boolean`):

Keep only accounts that list a website on their profile, e.g. for lead lists.

## `bioKeywords` (type: `array`):

Keep only accounts whose bio or display name contains one of these words (case-insensitive), e.g. "founder", "podcast", "agency". Empty = any bio.

## `excludeProtected` (type: `boolean`):

Protected (locked) accounts still publish name, bio and counts and are delivered by default. Tick to drop them.

## `activeWithinDays` (type: `integer`):

Keep only accounts whose latest original post or reply is at most this many days old, e.g. 30. 0 = any activity (also keeps accounts with no visible posts).

## `includeLatestTweets` (type: `boolean`):

Adds the account's latest original posts and replies (text, date, likes, replies, reposts, quotes, bookmarks, views, media) as latestPosts. Charged as the posts event.

## `tweetsPerProfile` (type: `integer`):

How many latest posts to attach, 1-5 (the public profile page carries the 5 most recent original posts).

## `includePinnedTweet` (type: `boolean`):

Adds the full pinned post (text, date, counts, media) as pinnedPost. The pinned post id is always in pinnedTweetId. Charged as the posts event.

## `includeUnavailable` (type: `boolean`):

Write a status row for handles that do not exist, are suspended, or are not valid input, so a bulk list comes back complete. Off: they appear only in the run summary.

## `monitorMode` (type: `boolean`):

Remembers each account's followers, following, posts, likes, bio, name, website, verification and avatar. A re-run delivers an account only when it is new or one of those changed, with previousStats, deltas and changedFields.

## `monitorStoreName` (type: `string`):

Name of the key-value store that keeps the per-account memory for monitor mode, e.g. "competitors-q4". Give each list its own name. Letters, digits and hyphens.

## `maxItems` (type: `integer`):

Stop after this many delivered profiles (your cost cap; you pay per delivered profile). 0 = every account in the list.

## `compact` (type: `boolean`):

Core fields only (handle, name, bio, website, location, the five counts, join date, verification, last post, engagement): sized for AI agents and MCP clients.

## `proxyConfiguration` (type: `object`):

X serves public profile pages without a proxy; the scraper switches to the Apify datacenter and then residential pool on its own if a request is refused. Set a proxy here only to force one.

## `maxConcurrency` (type: `integer`):

How many profiles to load at the same time. 8 is the tested default; raise it for lists of thousands.

## Actor input object example

```json
{
  "handles": [
    "nasa",
    "apify"
  ],
  "minFollowers": 0,
  "maxFollowers": 0,
  "verifiedOnly": false,
  "withWebsiteOnly": false,
  "bioKeywords": [],
  "excludeProtected": false,
  "activeWithinDays": 0,
  "includeLatestTweets": false,
  "tweetsPerProfile": 5,
  "includePinnedTweet": false,
  "includeUnavailable": false,
  "monitorMode": false,
  "monitorStoreName": "x-profile-monitor",
  "maxItems": 0,
  "compact": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "maxConcurrency": 8
}
```

# Actor output Schema

## `profiles` (type: `string`):

The dataset of X account profiles (one item per account).

## `summary` (type: `string`):

Per-input outcome (delivered, filtered, unchanged, not found, suspended, blocked), counts-enrichment fill and bytes moved.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "handles": [
        "nasa",
        "apify"
    ],
    "bioKeywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("topapi/x-profile-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "handles": [
        "nasa",
        "apify",
    ],
    "bioKeywords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("topapi/x-profile-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "handles": [
    "nasa",
    "apify"
  ],
  "bioKeywords": []
}' |
apify call topapi/x-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,topapi/x-profile-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/7WTqvvkL6e0zXIHkR/builds/s4u0dlaJg8zoj4THK/openapi.json
