# Changelog of X (Twitter) Watchlist 🔔 (new posts, all-in price) (`tagadanar/x-account-watchlist`) Actor

- **URL**: https://apify.com/tagadanar/x-account-watchlist/changelog.md
- **Full Actor documentation**: https://apify.com/tagadanar/x-account-watchlist.md

## Changelog

### 0.1.13 (2026-09-19)

- **Correction to 0.1.12, same day.** The pause-and-continue behaviour was tried
  on a real 80-account run and did not work: X's announced reset time came, and
  the next request was refused again. It is switched off. A long list behaves as
  it did before — the run stops once X refuses, marks the remaining accounts
  `rate-limited` and never charges for them. The README and the input help now
  state the measured limit (about 25 to 40 accounts per run) and the dependable
  workaround: schedules of about 25 accounts, at least 15 minutes apart.

### 0.1.12 (2026-09-19)

- **Long watchlists now finish in one run.** X serves about 25 accounts per 15
  minutes on this surface, whatever connection asks. Until now a run that hit
  that limit stopped and marked the rest `rate-limited`. It now pauses until the
  reset time X announces, then carries on with the same account — when the run
  timeout leaves room and enough accounts are left to be worth the wait. The
  waiting is never charged, and the final status says how long the run paused.
- If X refuses again right after the announced reset, the run stops as before
  rather than waiting a second time on a promise X did not keep.

### 0.1.10 (2026-09-06)

- **A cheaper route is now tried before the expensive one, on every run.** X
  serves this data to ordinary residential connections only, which is why runs
  go through a residential exit. That block is not permanent — it lifted for a
  few hours on 6 September — so each run now spends one free request checking
  whether the cheap route is open, and uses it when it is. Nothing about your
  input, output or price changes; the run log says which route it used.
- The check can only ever *add* a route. Its answer is accepted solely when it
  returns a real timeline, and an account is never reported as missing or
  suspended on the strength of it, because X's block and a deleted account look
  identical from a blocked connection.

### 0.1.6 (2026-08-29)

- **Fixed: a short run gave up after one attempt per account.** The time guard
  priced every retry at its worst case — a full 60-second timeout — and refused
  to start a retry it could not fit four times over. On a 150-second run that
  left room for exactly one attempt, so an account was asked once, from one
  exit, on one of X's four rate-limit buckets; if that bucket happened to be
  spent the account came back empty and the run stopped there. It now measures
  the time each attempt actually takes — a refusal costs a fraction of a second,
  not a minute — so every exit and every bucket is tried while the clock allows,
  and only a genuinely spent run stops early.
- **Fixed: a run that ran out of time said X had refused it.** The status
  message claimed "refused on all 4 attempts" when a single attempt had been
  made, which sent you away to wait fifteen minutes for a rate limit that was
  never spent. An account the clock cut short now reports the clock — "N of M
  attempts tried before the crawl box closed" — is never charged, ends the run
  successfully rather than red, and the rate-limit verdict is reserved for an
  account that really was asked from every exit.

### 2026-08-29

- The run now watches its own clock. A long watchlist used to be killed by the
  platform timeout mid-account, losing every post that had not been pushed yet.
  The actor now stops starting new accounts while there is still time to charge
  and deliver what it collected, and ends **successfully** with a status message
  saying "Stopped at the run time limit: N post(s) delivered, raise the run
  timeout or watch fewer accounts."
- The retry ladder is bounded by the time actually left, not by a fixed four
  attempts. One throttled account could previously burn four minutes of retries
  past the point where the run had time for it. No residential exit is drawn
  when there is no time left to use it — on this site the connection itself is
  most of the cost.
- Honest limit in the input form: **X accounts to watch** now accepts up to 200
  entries per run, which is what a default 3600-second run finishes with room to
  spare, instead of being silently unbounded.
- Every run now ends with a status message built from what was really delivered.
  "No posts matched" is only ever said about accounts whose timeline X actually
  served — a run X rate-limited now leads with the refusal, and monitor mode
  reports "no new posts since the last run" as the ordinary result it is.

### 0.1.0

First release.

- Watches a list of X (Twitter) accounts and returns their public posts, read from the logged-out embed timeline. No login, no API key, no developer account.
- Monitor mode: turn on "only posts published since the last run", schedule it, and each run brings back only what is new. Each account keeps its own position, so editing the list does not reset the others.
- Per post: full text (the original text on a repost, not the truncated "RT @" form), ISO date, likes, reposts, replies and quotes, media with direct image and MP4 URLs, links resolved past `t.co`, hashtags, mentions, cashtags, link card, reply and quote targets, and the author's follower count at read time.
- Per account: the full profile (bio, followers, following, posts all time, verification, account age) plus a plain status saying whether it was read, has no public timeline, or was refused by X.
- You get the "Posts" tab: originals, self-threads, reposts and quote posts. Reposts can be switched off to keep only original posts.
- Results are sorted by real posting date, never by feed order: the public timeline mixes pinned and old high-engagement posts in with the recent ones.
- Post ids are handled as strings and compared as 64-bit integers, so the new-since-last-run mark is exact.
- Optional Slack webhook digest of what a run found. Never billed.
- Accounts that do not exist, are suspended, are protected or could not be reached are reported and never charged. X answers a misspelled handle with an ordinary-looking page rather than an error, so this is checked explicitly rather than assumed.
- Every run ends with a status message saying how many accounts were read, how many were not, and why.
