Skip to content

Build1 publisher3 min readPublished

News bot's OpenPageRank gate lets 5 of 270 daily stories reach X at $0.20 each

One news bot built on APITube's feed sent X only 5 of a day's 270 stories, because X bills $0.200 for every post carrying a URL. Its X budget is a source-rank threshold. The $30 monthly bill moves with how many top-ranked outlets publish each day.

The Engineer · Build desk

Illustration accompanying News bot's OpenPageRank gate lets 5 of 270 daily stories reach X at $0.20 each

What happened

  • X charges $0.015 per post and $0.200 per post with a URL, with no free tier, while Bluesky charges nothing, according to the bot's authors citing X's pricing page.
  • One day of English Renewable Energy news on APITube's feed, 16 September 2026, came to 270 articles, and 5 survived every filter from sources with an OpenPageRank of 6 or more.
  • The bot sends every surviving story to Bluesky and forwards to X only those whose source has an OpenPageRank of at least 6, set by X_MIN_OPR.
  • By the authors' figures, posting all 34 daily stories to X would cost $204 a month, while the top five cost $30.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • exposure The source-rank gate sets eligibility and only the per-run cap bounds the count. A busy news day can push X charges toward the loop's ceiling of 144 posts and $28.80 a day.
  • cost Most of an X news bot's bill is the link surcharge. Any pipeline that posts links pays about 13 times the base rate on each post it sends.
  • decision Teams copying the design hand X selection to a domain ranking. A strong story from a low-ranked outlet then stays off the paid channel however good it is.
  • constraint On X each syndicated copy that slips past dedupe is a $0.200 charge. For any paid channel, title normalisation becomes part of the budget code.

The spending policy for X is one line of bot.py: `X_MIN_OPR = int(os.environ.get("X_MIN_OPR", "6"))`, commented "X costs money per post; only the best go there" [5]. A story reaches X only when its source has an OpenPageRank of 6 or more. Everything else goes to Bluesky alone [4]. "That threshold is the difference between a $204 and a $30 monthly bill, and it comes from the feed's own numbers, not from taste," the authors wrote [6].

The score belongs to the publisher, not the article. Under this rule a strong story from a small trade site stays on Bluesky, while a thin rewrite from a high-ranked domain goes to X [4]. For a single-industry feed I think that is a fair proxy.

The number of stories that qualify for X under the threshold changes daily. Each run posts up to three new stories to Bluesky and forwards the qualifying ones to X [8], with the limit set by MAX_PER_RUN, default 3 [9]. One run every 30 minutes is 48 runs a day [1]. The ceiling is 144 X posts a day, or $28.80, about $864 over a 30-day month [2]. Arrivals are uneven: the busiest 30-minute slot in the raw pull had 21 articles, the median slot 4 [10]. The measured day produced 5 X posts and $1.00 of charges [3]. The $30 monthly figure [7] comes from one day, 16 September 2026, of English-language Renewable Energy news [3]. In the five steps the post lists, the per-run cap is the only limit on X spend [8].

The URL is where the money goes. According to the X pricing page the post quotes, a link raises the per-post price from $0.015 to $0.200, about 13.3 times [1][4]. Sending all 34 stories without links would cost $15.30 a month, against $204 with them [5][7].

On a paid network, each duplicate that gets past dedupe is billed. The authors measured the API's `is_duplicate` flag and URL matching, and together they removed 0 of 270 articles [11]. Syndicated copies arrive with different URLs on different domains [11]. Lowercasing titles and stripping punctuation removed 18, including one story, "Egypt's wind power push", published six times [11]. Posted to X, those six copies would have been billed six times, $1.20 for one headline [6].

The image flags got the same scrutiny. `has_social_share_image=1` is meant to keep only images of at least 1200x630, and it cut the 270 articles to 35 [12]. Of 29 share images the bot fetched, 5 were over Bluesky's 1,000,000-byte blob limit and 6 were below 1200x630 despite the flag [14]. The script prepares each thumbnail itself with Pillow so every Bluesky card carries an image under 1,000,000 bytes [16]. Checking a vendor's flags against the actual files is the part of this build I would copy first. The flag choice also sets volume, since `has_image=1` would have passed 147 articles [12]. "A bot posting 147 stories a day is spam; 35 is a feed," the authors wrote [13].

For the $30 to hold in another team's pipeline, its feed needs a similar shape: 270 raw articles a day, with 5 of them, under 2%, from sources at OpenPageRank 6 or above [3][7]. The evidence is a single day of a single industry feed, with flags and articles from APITube's news API [15]. The counts also do not line up. The funnel ends at 35 share-image stories, the all-to-X cost line uses 34, and only 29 images were fetched [3][7][14]. The post does not reconcile them.

What to watch

  • A multi-day run of the same funnel showing how often more than five OpenPageRank-6 stories arrive in a day, and what the real monthly X bill comes to.
  • Any change to X's $0.200 URL rate or the addition of a free tier, either of which moves where the X_MIN_OPR threshold should sit.
  • Whether the authors add a daily X spend limit alongside X_MIN_OPR.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories