# X (Twitter) Profile & Username Change Monitor (`arjun_code/x-twitter-profile-username-history-monitor`) Actor

Monitor X profiles for username, bio, avatar, verification, follower, and activity changes. Send change-only Webhook, Slack, or Discord alerts and export clear before/after history. No login required.

- **URL**: https://apify.com/arjun\_code/x-twitter-profile-username-history-monitor.md
- **Developed by:** [Arjun AI](https://apify.com/arjun_code) (community)
- **Categories:** Social media, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 account checkeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## X (Twitter) Profile & Username Change Monitor

Monitor X profiles over time and see exactly what changed. Track usernames, bios, avatars, verification, follower counts, activity, and account-origin signals with clear before/after results and optional change-only alerts—no X login, cookies, or API key required.

Unlike a one-time profile scraper, this Actor keeps a baseline between recurring Apify Task runs. It follows accounts by stable X user ID, so monitoring can continue even after a username change.

### Why use this Actor?

- Detect username, display name, bio, avatar, banner, website, and location changes
- Track follower, following, post, media, like, and list-count movements
- Monitor verification, protected status, account country, and account source
- Receive readable change summaries plus structured previous/current values
- Send one change-only digest to Discord, Slack, or any HTTP webhook
- Keep meaningful historical profile versions without storing a duplicate on every run
- Export results to JSON, CSV, Excel, webhooks, and other Apify integrations

### Quick start

For continuous monitoring, create an **Apify Task before the first run**:

1. Open this Actor and enter one or more X accounts.
2. Optionally paste a Discord, Slack, or generic Webhook URL.
3. Save the input as an Apify Task.
4. Run the Task once to create the baseline.
5. Add an hourly, daily, or weekly Apify Schedule to the same Task.
6. Review each run's dataset or wait for a change notification.

The first successful check returns `baseline_created`. Later checks return `changed` or `no_change`.

### Input

Accounts may be entered as plain usernames, `@handles`, or complete profile URLs:

```json
{
  "screenNames": [
    "OpenAI",
    "@github",
    "https://x.com/elonmusk"
  ],
  "maxHistoryVersions": 50,
  "includeHistory": false,
  "notificationWebhookUrl": "https://discord.com/api/webhooks/...",
  "notifyOn": "profile_changes"
}
```

| Field | Description | Default |
| --- | --- | --- |
| `screenNames` | X accounts to monitor. Accepts username, `@handle`, or profile URL. | Required |
| `maxHistoryVersions` | Meaningful profile versions retained per account. | `50` |
| `includeHistory` | Adds all retained profile versions to each result. | `false` |
| `notificationWebhookUrl` | Optional Discord, Slack, or generic HTTP webhook. Stored as an encrypted secret. | Empty |
| `notifyOn` | `profile_changes` or `all_changes`, including metrics. | `profile_changes` |
| `monitorId` | Advanced history-group identifier. Keep `default` when using a Task. | `default` |

The Task ID and `monitorId` identify a monitoring timeline. Keep both unchanged across scheduled runs. Changing the Monitor ID starts a separate history without deleting the old one.

### Change-only notifications

Paste one URL into **Notification webhook URL**. The Actor identifies the destination automatically:

- Discord Incoming Webhook URLs receive a Discord message.
- Slack Incoming Webhook URLs receive a Slack message.
- Every other URL receives a structured JSON `POST` request.

The first baseline does not send a notification. Runs with no selected changes also stay quiet. When several monitored accounts change in one run, the Actor sends one combined notification rather than one message per account.

Choose **Profile changes only** to monitor identity and profile information without follower-count noise. Choose **All changes, including metrics** to also receive audience and activity movements.

A generic webhook receives this structure:

```json
{
  "event": "x_profile_changes_detected",
  "monitor_id": "default",
  "notify_on": "profile_changes",
  "changed_accounts_count": 1,
  "actor_run_id": "RUN_ID",
  "actor_run_url": "https://console.apify.com/actors/runs/RUN_ID",
  "changes": [
    {
      "screen_name": "new_handle",
      "change_type": "profile",
      "change_summary": "Username: \"old_handle\" -> \"new_handle\"",
      "profile_url": "https://x.com/new_handle"
    }
  ]
}
```

The Webhook URL is encrypted by Apify when saved. A notification is attempted once and retried up to two times after temporary delivery failures. Delivery is recorded in the run log; a final delivery error does not remove the profile results already collected.

### Example change result

```json
{
  "status": "changed",
  "change_type": "profile_and_metrics",
  "screen_name": "new_handle",
  "profile_url": "https://x.com/new_handle",
  "check_number": 8,
  "profile_version": 3,
  "previous_profile_version": 2,
  "new_profile_version": true,
  "change_count": 2,
  "changed_fields": [
    "user_screen_name",
    "followers_count"
  ],
  "change_summary": "Username: \"old_handle\" -> \"new_handle\"; Followers: 12,480 -> 12,615 (+135)",
  "changes": {
    "user_screen_name": {
      "previous": "old_handle",
      "current": "new_handle"
    },
    "followers_count": {
      "previous": 12480,
      "current": 12615,
      "difference": 135
    }
  }
}
```

The default **Overview** dataset view shows the fields most users need. Choose **Full details** to inspect structured changes, raw profile data, storage identifiers, and optional history.

### Understanding checks and versions

| Field | Meaning |
| --- | --- |
| `check_number` | Increases after every successful check. |
| `profile_version` | Increases only when meaningful profile information changes. |
| `new_profile_version` | Tells you whether this run created a new historical profile version. |
| `retained_profile_versions` | Number of profile versions currently saved. |
| `change_type` | `baseline`, `profile`, `metrics`, `profile_and_metrics`, or `none`. |

Follower and activity changes are reported on every run but do not create a new full profile version. For example, `check_number` can be `20` while `profile_version` is still `3`.

### Tracked fields

#### Profile changes

- Username and display name
- Bio, location, website, avatar, and banner
- Verified, blue-verified, and protected status
- Account country and country-accuracy signal
- Account creation source and X-native username-change information
- Business account information

#### Metric changes

- Followers, normal followers, and following
- Posts and media posts
- Likes and list memberships
- Creator subscriptions

### Result statuses

| Status | Meaning | Charged |
| --- | --- | --- |
| `baseline_created` | The first successful snapshot was saved. | Yes |
| `changed` | One or more tracked fields changed. | Yes |
| `no_change` | No tracked values changed. | Yes |
| `not_found` | The requested account was not found before a baseline existed. | No |
| `unavailable` | A monitored account is currently unavailable; its previous state is retained. | No |
| `request_failed` | The current check failed after retries; its previous state is retained. | No |

One `account-check` event is charged for each successfully checked account. Failed or unavailable checks do not replace the latest successful snapshot. When the run reaches the user's maximum cost limit, the Actor keeps the last completed account and stops cleanly before performing another billable check.

### History retention

The latest successful snapshot is retained for comparison. Meaningful profile versions are stored in the Actor's named key-value store, with 50 versions per account by default and up to 500 when configured.

Leave `includeHistory` disabled for compact scheduled datasets. Enable it only when an API or export needs every retained version in the same result.

### Common use cases

- Monitor competitors, founders, creators, brands, and public figures
- Detect rebrands, username transfers, impersonation signals, or account takeovers
- Track creator and influencer audience growth
- Maintain current CRM, lead-enrichment, or OSINT profile records
- Send change-only alerts directly to Discord, Slack, Make, Zapier, n8n, or an internal service

### Ready-to-run examples

- [Monitor Competitor X Profile Changes](https://apify.com/arjun_code/x-twitter-profile-username-history-monitor/examples/monitor-competitor-x-profile-changes)
- [Track X Username and Bio Changes](https://apify.com/arjun_code/x-twitter-profile-username-history-monitor/examples/track-x-username-and-bio-changes)
- [Track X Follower Growth and Verification](https://apify.com/arjun_code/x-twitter-profile-username-history-monitor/examples/track-x-follower-growth-and-verification)

### Related X (Twitter) Actors

- [X (Twitter) People Search Scraper](https://apify.com/arjun_code/x-twitter-people-search-scraper) — find profiles by keyword
- [X (Twitter) Similar Accounts Finder](https://apify.com/arjun_code/x-twitter-similar-accounts-finder) — discover related accounts
- [X Followers & Following Scraper](https://apify.com/arjun_code/x-twitter-followers-followings-scraper) — export audience networks
- [X Twitter Account Origin Intelligence](https://apify.com/arjun_code/x-twitter-account-origin-scraper) — inspect origin and username-history signals

### Important notes

- Monitoring starts from the first successful baseline; historical changes from before that run cannot be reconstructed.
- Results contain public X profile metadata available at check time.
- X can change its internal interfaces, which may temporarily affect availability.
- This Actor is not affiliated with or endorsed by X Corp.

# Actor input Schema

## `screenNames` (type: `array`):

Enter one account per line as a username, @handle, or full X/Twitter profile URL.

## `maxHistoryVersions` (type: `integer`):

Number of meaningful profile versions retained for each account. Follower and activity changes do not create full profile versions.

## `includeHistory` (type: `boolean`):

Include all retained profile versions in every successful result. Leave disabled for smaller scheduled-run datasets.

## `notificationWebhookUrl` (type: `string`):

Paste a Discord or Slack Incoming Webhook URL, or any HTTP POST endpoint. The URL is encrypted when the input is saved.

## `notifyOn` (type: `string`):

Choose whether notifications cover meaningful profile changes only or also follower and activity metrics.

## `monitorId` (type: `string`):

Keep 'default' when using an Apify Task. Change this only to maintain separate histories for direct or API runs.

## Actor input object example

```json
{
  "screenNames": [
    "OpenAI"
  ],
  "maxHistoryVersions": 50,
  "includeHistory": false,
  "notifyOn": "profile_changes",
  "monitorId": "default"
}
```

# Actor output Schema

## `results` (type: `string`):

Current profiles, before/after changes, and history metadata stored in the default dataset.

# 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 = {
    "screenNames": [
        "OpenAI"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("arjun_code/x-twitter-profile-username-history-monitor").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 = { "screenNames": ["OpenAI"] }

# Run the Actor and wait for it to finish
run = client.actor("arjun_code/x-twitter-profile-username-history-monitor").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 '{
  "screenNames": [
    "OpenAI"
  ]
}' |
apify call arjun_code/x-twitter-profile-username-history-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,arjun_code/x-twitter-profile-username-history-monitor"
        }
    }
}

```

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/fyEJ5qg3TPePObK2c/builds/iP0ayG8m8JQ826kty/openapi.json
