X (Twitter) Ads Change Monitor avatar

X (Twitter) Ads Change Monitor

Pricing

from $5.00 / 1,000 ad changes

Go to Apify Store
X (Twitter) Ads Change Monitor

X (Twitter) Ads Change Monitor

Monitor X (Twitter) Ads Repository advertisers on a schedule and emit only NEW, CHANGED, or ENDED ads. Stateful delta monitoring with a silent BASELINE first run; no login or user cookies.

Pricing

from $5.00 / 1,000 ad changes

Rating

0.0

(0)

Developer

xinyao a

xinyao a

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a month ago

Last modified

Categories

Share

X Ads Daily Delta Monitor

Stateful monitoring for the public X Ads Repository. Give it advertiser screen names; the Actor stores a fingerprinted snapshot in an Apify named Key-value store and emits changes to the Dataset.

Output semantics

  • First run with firstRunMode: "BASELINE" (default): save the baseline without Dataset rows, avoiding an unexpected per-item charge for every current ad.
  • First run with CURRENT: emit every observed ad as CURRENT, then save the baseline.
  • Later fully successful runs: emit NEW, CHANGED, or ENDED only.
  • ENDED is an inference: an ad is absent from the rolling query window for missingRunsToEnd consecutive complete runs (default 2). X's route does not expose an explicit end timestamp.
  • If any country/date page fails, a request/ad cap is reached, or all changes do not fit maxItems, that advertiser's state is not advanced. A partial scrape therefore cannot mark every prior ad ENDED.

CHANGED includes changes in public metadata, targeting, reach, or impressions. Each row contains the previous/current SHA-256 fingerprints.

Example

{
"advertisers": ["Apple"],
"countries": ["FR", "DE"],
"lookbackDays": 2,
"firstRunMode": "CURRENT",
"missingRunsToEnd": 2,
"maxItems": 1000
}

Start monitoring in 2 minutes

  1. Leave firstRunMode as BASELINE and click Start once. This saves the initial snapshot with zero Dataset rows, so the first inventory is not billed per ad.
  2. On the finished run page, click ScheduleCreate new schedule, select a daily interval, and keep the same named Key-value store.
  3. Future complete runs emit only NEW, CHANGED, or ENDED rows. Add a Dataset-item webhook or export the Dataset as JSON/CSV for alerts and reporting.

Use a distinct stateStoreName for each independent advertiser monitoring job. Do not change or purge that named store between scheduled runs.

For a reproducible historical source check:

{
"advertisers": ["Apple"],
"countries": ["FR"],
"startDate": "2023-08-26",
"endDate": "2024-08-25",
"pageDays": 366,
"firstRunMode": "CURRENT",
"stateStoreName": "x-ads-monitor-demo"
}

Dataset fields

advertiser, tweetId, lineItemId, accountId, creativeUrl, country, account, fundingInstrument, approvalStatus, targeting, impressions, reach, changeType, firstSeenAt, lastSeenAt, observedAt, fingerprints, and sourceUrl.

Source and privacy

The Actor first loads https://ads.x.com/ads-repository, retaining only the anonymous guest/CSRF session issued by X, then calls the exact public frontend user-search and ads-search POST payloads. These are undocumented frontend routes, not a supported X API; schema validation fails closed if they drift. No X login, user-supplied cookie, proxy bypass, or personal-data collection is used. Respect X's terms, public-data policy, and applicable law.

Pagination and limits

The live route returns an array and exposes no continuation token. The Actor creates deterministic pages by country × inclusive date window (pageDays), deduplicates (tweetId, lineItemId, country), retries 429/5xx/network errors, and enforces maxRequests, maxAdsPerAdvertiser, and maxItems.

Local development

python -m venv .venv
. .venv/bin/activate
pip install -r requirements-dev.txt
PYTHONPATH=src pytest -q
APIFY_LOCAL_STORAGE_DIR=./storage python -m src

Live request evidence and the observed schemas are recorded in research/live-endpoint-evidence.json. The included sample is a real public ad identity and contains no private data.