<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: data show</title>
    <description>The latest articles on DEV Community by data show (@data_show_bf2f94f53118a25).</description>
    <link>https://dev.to/data_show_bf2f94f53118a25</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3986915%2F9d2f3331-03c4-41c9-977a-a1d2fd95aa1b.png</url>
      <title>DEV Community: data show</title>
      <link>https://dev.to/data_show_bf2f94f53118a25</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/data_show_bf2f94f53118a25"/>
    <language>en</language>
    <item>
      <title>Pull Public X (Twitter) Data in Python Without an X Developer Account, Then Hand It to Your AI Agent</title>
      <dc:creator>data show</dc:creator>
      <pubDate>Sat, 24 Oct 2026 15:10:28 +0000</pubDate>
      <link>https://dev.to/data_show_bf2f94f53118a25/pull-public-x-twitter-data-in-python-without-an-x-developer-account-then-hand-it-to-your-ai-agent-1bba</link>
      <guid>https://dev.to/data_show_bf2f94f53118a25/pull-public-x-twitter-data-in-python-without-an-x-developer-account-then-hand-it-to-your-ai-agent-1bba</guid>
      <description>&lt;p&gt;I keep running into the same small job: "grab the last few hundred posts about a topic, plus the followers of a couple of accounts, and put them in a spreadsheet." It's not a big data project. It's an afternoon script. But X data has become awkward for exactly this size of task. Browser scrapers need logged-in accounts and proxies and break whenever the site changes, and the official API bills every post and profile it returns.&lt;/p&gt;

&lt;p&gt;This post walks through a small Python script that does both jobs with a pay-as-you-go REST API, &lt;a href="https://twexapi.io/get-started" rel="noopener noreferrer"&gt;TwexAPI&lt;/a&gt;, and then shows how to give the same access to an AI agent through MCP. Everything here uses public data and endpoints that are documented in its API reference.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure and scope: TwexAPI is an independent third-party service. It is not affiliated with or endorsed by X Corp. Collect only public data, and check privacy law and X's terms for your own use case.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python 3 and &lt;code&gt;requests&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A TwexAPI API key. New accounts get 20,000 free Credits with no credit card, valid for 7 days. A typical post or profile read costs 5 Credits, so that's roughly 4,000 reads to experiment with.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;requests
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TWEXAPI_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"twexapi_xxx"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authentication is a single header, &lt;code&gt;Authorization: Bearer &amp;lt;your key&amp;gt;&lt;/code&gt;, sent to &lt;code&gt;https://api.twexapi.io&lt;/code&gt;. No OAuth dance and no app review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: A tiny cursor paginator
&lt;/h2&gt;

&lt;p&gt;Both endpoints we'll use are &lt;code&gt;POST&lt;/code&gt; endpoints with cursor paging. You send a JSON body, get back a page of results in &lt;code&gt;data&lt;/code&gt;, and keep going while &lt;code&gt;has_next_page&lt;/code&gt; is true, passing &lt;code&gt;next_cursor&lt;/code&gt; back in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.twexapi.io&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;TWEXAPI_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;POST a cursor endpoint until we have max_items or hit the last page.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;max_items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;API&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;next_cursor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;next_cursor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;has_next_page&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;max_items&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;delay=5&lt;/code&gt; matters on the free tier. The Starter plan is limited to 0.2 requests per second, i.e. one request every five seconds. Paid plans start at 5 QPS, so you can drop the delay once you upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Search posts with normal X search operators
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;POST /twitter/advanced_search/page&lt;/code&gt; takes a list of &lt;code&gt;searchTerms&lt;/code&gt; and a &lt;code&gt;sortBy&lt;/code&gt; of &lt;code&gt;"Latest"&lt;/code&gt; or &lt;code&gt;"Top"&lt;/code&gt;. Each page returns up to 20 posts. The search terms accept the same operators as the X search box, so you can combine a keyword with &lt;code&gt;lang:&lt;/code&gt;, &lt;code&gt;since:&lt;/code&gt;, &lt;code&gt;min_faves:&lt;/code&gt; and &lt;code&gt;-filter:replies&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tweets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/twitter/advanced_search/page&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;searchTerms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lang:en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;min_faves:50&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;since:2026-10-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-filter:replies&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sortBy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Latest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;max_items&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;posts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few operators I use constantly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;from:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;from:nasa&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only posts by one account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;since:&lt;/code&gt; / &lt;code&gt;until:&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;since:2026-10-01&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Date window&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lang:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lang:en&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Language filter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;min_faves:&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;min_faves:100&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Skip low-engagement noise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-filter:replies&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Drop replies&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Filtering on the query side is the cheapest optimization you have. You pay per item returned, so a tighter query is both faster and cheaper than pulling everything and filtering in pandas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Export a follower list
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;POST /twitter/followers/page&lt;/code&gt; takes a &lt;code&gt;screen_name&lt;/code&gt; and returns up to 200 followers per page. Because it uses the same cursor pattern, the helper works unchanged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;followers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/twitter/followers/page&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;screen_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nasa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;max_items&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a matching &lt;code&gt;POST /twitter/following/page&lt;/code&gt; if you want who an account follows instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Write both to CSV
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;posts.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8-sig&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tweet_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;created_at&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;likes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tweets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tweet_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;created_at&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;{}).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;screen_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;favorite_count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;followers.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8-sig&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;followers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bio&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;followers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;followersCount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;utf-8-sig&lt;/code&gt; is a small trick worth remembering: it writes a byte-order mark so Excel opens emoji and non-Latin names correctly instead of showing mojibake.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did that cost?
&lt;/h2&gt;

&lt;p&gt;200 posts plus 1,000 followers is 1,200 reads. At 5 Credits each that's 6,000 Credits, which fits comfortably inside the free 20,000. In dollar terms, 100,000 Credits is about $1, so the run is worth about six cents. Two billing details are useful to know when you're debugging: a request that comes back with no results still costs 5 Credits, and a request that fails with an error isn't billed. If you outgrow the trial, the &lt;a href="https://twexapi.io/pricing" rel="noopener noreferrer"&gt;pricing page&lt;/a&gt; lists one-time packs starting at $20 and monthly plans starting at $50.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Give the same access to an AI agent (MCP)
&lt;/h2&gt;

&lt;p&gt;Scripts are great for repeatable exports. For exploratory questions like "what are people in Japan posting about this launch?" it's often faster to let an agent figure out the calls. TwexAPI runs a hosted MCP server at &lt;code&gt;https://api.twexapi.io/mcp&lt;/code&gt; (Streamable HTTP), authenticated with your API key in an &lt;code&gt;x-api-key&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;For Cursor, add this to &lt;code&gt;.cursor/mcp.json&lt;/code&gt; in a project (or &lt;code&gt;~/.cursor/mcp.json&lt;/code&gt; globally):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"twexapi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.twexapi.io/mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"x-api-key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"twexapi_YOUR_KEY_HERE"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code uses the same shape in &lt;code&gt;.mcp.json&lt;/code&gt; with &lt;code&gt;"type": "http"&lt;/code&gt; added. Claude Desktop only speaks stdio, so the docs bridge it with the &lt;code&gt;mcp-remote&lt;/code&gt; npm package. The &lt;a href="https://docs.twexapi.io/mcp/overview" rel="noopener noreferrer"&gt;MCP setup docs&lt;/a&gt; have configs for Codex CLI, VS Code, Windsurf and others.&lt;/p&gt;

&lt;p&gt;The server deliberately exposes just two tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;explore&lt;/code&gt; searches the endpoint catalog and returns names, methods, paths, parameter schemas, examples and a &lt;code&gt;read_only&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;twexapi_request&lt;/code&gt; executes an authenticated call with a &lt;code&gt;method&lt;/code&gt;, a relative &lt;code&gt;path&lt;/code&gt;, and an optional &lt;code&gt;query&lt;/code&gt; or &lt;code&gt;body&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the agent first discovers the right endpoint, then calls it. I like this design because the tool list stays tiny (it doesn't flood the context window with dozens of tool definitions), and the &lt;code&gt;read_only&lt;/code&gt; flag gives you something concrete to check before you let an agent run unattended.&lt;/p&gt;

&lt;p&gt;A prompt that works well for a first test:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Use twexapi to list the countries available for global trends, then show me the top trending posts for Japan."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Behind the scenes that maps to &lt;code&gt;GET /twitter/global-trending/countries&lt;/code&gt; and &lt;code&gt;GET /twitter/global-trending/tweets?country=...&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few practical notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keep the key server-side.&lt;/strong&gt; Don't ship it in front-end code or commit it. The SDKs and CLI read it from the &lt;code&gt;X_API_SCRAPER_KEY&lt;/code&gt; environment variable if you'd rather not hard-code anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Back off on 429s.&lt;/strong&gt; If you bump into rate limits, sleep and retry rather than hammering. The docs have an error-handling guide for this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reads don't need an X account.&lt;/strong&gt; Write actions (posting, liking, DMs) are a separate topic: they run with your own account's session, and I'd keep any agent on read-only endpoints unless a human reviews each action.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;For small and medium jobs, the pattern above covers most of what I need from X: a search, a follower export, and a CSV, in about 60 lines of Python. Then the same key can power an agent through MCP when the question is fuzzier. Start with a narrow query, check the Credits you used, and only then scale up.&lt;/p&gt;

</description>
      <category>python</category>
      <category>api</category>
      <category>twitter</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Why X (Twitter) Doesn't Show When Someone Followed an Account, and How to See Recent Follows Anyway</title>
      <dc:creator>data show</dc:creator>
      <pubDate>Tue, 20 Oct 2026 12:45:44 +0000</pubDate>
      <link>https://dev.to/data_show_bf2f94f53118a25/why-x-twitter-doesnt-show-when-someone-followed-an-account-and-how-to-see-recent-follows-anyway-569o</link>
      <guid>https://dev.to/data_show_bf2f94f53118a25/why-x-twitter-doesnt-show-when-someone-followed-an-account-and-how-to-see-recent-follows-anyway-569o</guid>
      <description>&lt;p&gt;If you've ever tried to answer a simple question like &lt;em&gt;"Who has this founder started following this month?"&lt;/em&gt;, you've probably hit a wall. X (formerly Twitter) will show you &lt;strong&gt;who&lt;/strong&gt; an account follows, but never &lt;strong&gt;when&lt;/strong&gt; they followed them. No sorting, no filters, no dates.&lt;/p&gt;

&lt;p&gt;I ran into this while doing creator discovery and competitive research. This post covers what is and isn't knowable about recent follows, practical ways to get at that data, and some ground rules for doing it responsibly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What X actually shows you
&lt;/h2&gt;

&lt;p&gt;Open any profile, click &lt;strong&gt;Following&lt;/strong&gt;, and you get a long, scrollable list of accounts. That's it. Here's what's missing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No follow timestamps.&lt;/strong&gt; Nothing in the UI tells you when a follow happened.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No sort options.&lt;/strong&gt; You can't sort by date, name, or follower count.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No filters or search inside the list.&lt;/strong&gt; You can't search one account's following list for a keyword or a specific handle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Login required.&lt;/strong&gt; Logged-out visitors are generally asked to sign in before they can browse following and follower lists.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the only built-in signal is the &lt;em&gt;order&lt;/em&gt; of the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ordering: roughly reverse-chronological, but not a guarantee
&lt;/h2&gt;

&lt;p&gt;In practice, following lists tend to show the most recently followed accounts near the top, which is why "scroll the top of their Following list" is the usual advice. But be honest about what that order does and doesn't tell you:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you can reasonably infer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accounts near the top were &lt;em&gt;probably&lt;/em&gt; followed more recently than accounts further down.&lt;/li&gt;
&lt;li&gt;If you check the same list at two points in time, new entries at the top are likely new follows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you can't know from the list alone&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The exact date or time&lt;/strong&gt; of any follow. Position isn't a timestamp.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whether the order is strictly chronological.&lt;/strong&gt; X doesn't document this as a guarantee, and behavior can change without notice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unfollow and re-follow history.&lt;/strong&gt; If someone unfollowed and followed again, you can't see that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Removed accounts.&lt;/strong&gt; Deactivated or suspended accounts can disappear from lists and shift positions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The only reliable way to learn &lt;em&gt;when&lt;/em&gt; a new follow appeared is to &lt;strong&gt;observe the list over time&lt;/strong&gt; and compare snapshots. Any tool or method claiming to show exact historical follow dates for arbitrary accounts should be treated with skepticism.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notifications don't help much either
&lt;/h2&gt;

&lt;p&gt;If it's &lt;em&gt;your&lt;/em&gt; account, you get a notification when someone follows you. But notifications aren't an archive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They only keep a limited number of recent events.&lt;/li&gt;
&lt;li&gt;Follow notifications are often grouped ("X and 12 others followed you").&lt;/li&gt;
&lt;li&gt;They only cover follows of &lt;strong&gt;your&lt;/strong&gt; account, not who other accounts are following.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why you might care: real use cases
&lt;/h2&gt;

&lt;p&gt;This isn't about snooping. There are practical reasons to look at recent follows on public accounts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Creator discovery.&lt;/strong&gt; People you trust in your niche are good filters. If a respected developer just followed five new accounts, those accounts are often worth a look.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Competitive research.&lt;/strong&gt; Watching who a competitor's official account follows can hint at new partnerships, hires, integrations, or markets they're paying attention to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trend monitoring.&lt;/strong&gt; When several VCs or well-known builders start following the same new project around the same time, that's an early signal worth noting. Not proof, but a useful prompt to dig further.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your own audience.&lt;/strong&gt; Seeing who recently followed &lt;em&gt;you&lt;/em&gt; helps you spot collaborators, customers, or communities you didn't know you were reaching.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Approach 1: Manual scrolling
&lt;/h2&gt;

&lt;p&gt;The free, zero-setup option.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in to X.&lt;/li&gt;
&lt;li&gt;Open the target profile and click &lt;strong&gt;Following&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Look at the first 20–50 entries.&lt;/li&gt;
&lt;li&gt;Optionally screenshot or copy the handles so you can compare later.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; free, no tools, works right now.&lt;br&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; tedious, needs an X login, and you have to keep your own snapshots to detect changes. It doesn't scale beyond a couple of accounts.&lt;/p&gt;
&lt;h2&gt;
  
  
  Approach 2: The official X API
&lt;/h2&gt;

&lt;p&gt;If you're a developer, the obvious move is the API. X offers endpoints for retrieving the accounts a user follows and the accounts following them.&lt;/p&gt;

&lt;p&gt;Things to know before you start:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;There are no follow timestamps here either.&lt;/strong&gt; The API returns lists of users, not dated follow events. You'd still have to poll and diff results yourself to detect new follows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access is paid and tiered.&lt;/strong&gt; X has changed its API pricing and plans several times. Free access is very limited, and follow-graph endpoints usually need a paid plan. Check the current developer portal before you design around it, since what's included at each level changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limits are tight.&lt;/strong&gt; If you're tracking many accounts, you'll hit limits fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You maintain the pipeline.&lt;/strong&gt; Auth, storage, scheduling, diffing, and handling deleted or suspended accounts are all on you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A minimal "detect new follows" loop looks something like this in pseudocode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;every N hours:
  current = fetch_following(user_id)        # list of user IDs
  previous = load_snapshot(user_id)
  new_follows = current - previous          # set difference
  save_snapshot(user_id, current)
  record(new_follows, detected_at=now())    # your timestamp, not X's
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the comment: the date you record is when &lt;strong&gt;you detected&lt;/strong&gt; the follow, not when it happened. That's the most accuracy you can honestly claim.&lt;/p&gt;

&lt;p&gt;For production monitoring this is the right path. For occasional research, it's a lot of overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach 3: Use a lookup tool
&lt;/h2&gt;

&lt;p&gt;If you just want to check what a public account has been following lately without writing code or logging into X, a lookup tool is the practical middle ground.&lt;/p&gt;

&lt;p&gt;Full disclosure: I built &lt;a href="https://recently-followed.online/" rel="noopener noreferrer"&gt;Recently Followed&lt;/a&gt;, a free web tool for researching public X accounts. You enter a username and review the newest following and follower data available for that account. A few details that matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No X login needed.&lt;/strong&gt; You sign in with a free Recently Followed account instead, which comes with a daily allowance of free searches.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The checked account isn't notified.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public accounts only.&lt;/strong&gt; Protected accounts aren't available, which is how it should be.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same honesty rules apply: you're seeing the &lt;em&gt;latest available&lt;/em&gt; data, not a timestamped history, so treat the order as a strong hint rather than a precise timeline.&lt;/p&gt;

&lt;p&gt;The site also has some &lt;a href="https://recently-followed.online/tools" rel="noopener noreferrer"&gt;free browser-based X tools&lt;/a&gt; that come in handy in research workflows: a video and GIF downloader, a thread-to-Markdown reader (nice if you keep notes in Obsidian or Notion), follower export, and trending topics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ethics and privacy: ground rules
&lt;/h2&gt;

&lt;p&gt;Follow data is public, but that doesn't mean anything goes. A few rules I stick to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public accounts only.&lt;/strong&gt; If someone has protected their account, respect that. Don't try to work around it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Research, not surveillance.&lt;/strong&gt; Looking at what industry accounts follow is normal market research. Obsessively tracking a private individual is not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't harass or call people out.&lt;/strong&gt; A follow isn't an endorsement, and inferring relationships or intentions from it can be wrong and hurtful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Respect platform terms and store less.&lt;/strong&gt; Use sanctioned access, and keep only the snapshot data you need.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick checklist
&lt;/h2&gt;

&lt;p&gt;Before you go researching recent follows, run through this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Is the account public?&lt;/li&gt;
&lt;li&gt;[ ] Do I have a clear, legitimate reason (discovery, research, trends)?&lt;/li&gt;
&lt;li&gt;[ ] Am I treating list order as a &lt;em&gt;hint&lt;/em&gt;, not a timestamp?&lt;/li&gt;
&lt;li&gt;[ ] For tracking over time, am I saving snapshots and diffing them?&lt;/li&gt;
&lt;li&gt;[ ] If using the API, have I checked the current plan limits and pricing?&lt;/li&gt;
&lt;li&gt;[ ] Am I avoiding conclusions about people based on a single follow?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;X doesn't show follow dates. The list's rough reverse-chronological order is the only built-in signal, and it's useful as long as you don't over-trust it. For a quick look, scroll manually. For serious monitoring, build on the API and diff snapshots. For everyday research without the setup, a lookup tool gets you most of the way there.&lt;/p&gt;

&lt;p&gt;Whatever you use, keep it to public accounts and keep it respectful. Have you found other good ways to spot what's new in someone's follow graph? Tell me in the comments.&lt;/p&gt;

</description>
      <category>twitter</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Building AI Agents? The LLM isn't your bottleneck—Data Ingestion is.</title>
      <dc:creator>data show</dc:creator>
      <pubDate>Tue, 16 Jun 2026 08:20:11 +0000</pubDate>
      <link>https://dev.to/data_show_bf2f94f53118a25/building-ai-agents-the-llm-isnt-your-bottleneck-data-ingestion-is-1edi</link>
      <guid>https://dev.to/data_show_bf2f94f53118a25/building-ai-agents-the-llm-isnt-your-bottleneck-data-ingestion-is-1edi</guid>
      <description>&lt;p&gt;As an indie developer, I’ve spent the last few months deep in the trenches building automation workflows and experimenting with different AI agent frameworks. &lt;/p&gt;

&lt;p&gt;But the further I got, the more I hit a frustrating wall. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Models are incredibly smart now, but if you can't feed them clean, real-time external data, they're practically useless.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The "Dirty Work" of AI Development
&lt;/h3&gt;

&lt;p&gt;This became painfully obvious when I needed to pull social data—specifically from X/Twitter (like targeted follower lists, engagement metrics, or structured comment threads)—to feed into my AI for context analysis. &lt;/p&gt;

&lt;p&gt;Here is what usually happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Official Route:&lt;/strong&gt; The official API is prohibitively expensive for indie hackers and side projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Custom Scraper Route:&lt;/strong&gt; Maintaining custom scrapers means fighting an endless, exhausting war against rate limits, proxies, and anti-bot systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Data Format Issue:&lt;/strong&gt; Even if you get the data, it's usually a messy HTML/JSON soup that eats up your LLM's context window and leads to hallucinations.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Scratching My Own Itch
&lt;/h3&gt;

&lt;p&gt;I got so tired of this "dirty work" stalling my core application logic that I paused my main project to just build the infrastructure I wished existed. &lt;/p&gt;

&lt;p&gt;My goal was simple: &lt;strong&gt;abstract away all the complex scraping and proxy routing, and just deliver clean, structured data.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I recently finished packaging it up, and it now fully supports &lt;strong&gt;CLI commands&lt;/strong&gt; and direct &lt;strong&gt;AI tool calling&lt;/strong&gt;. This means you can now seamlessly plug it directly into Cursor, Claude, or your custom agent scripts without writing a single line of scraping logic. It outputs clean JSON or CSV, ready for your LLM to digest.&lt;/p&gt;

&lt;p&gt;If you’re also building AI tools and banging your head against the wall trying to ingest X data reliably, you can check out the infrastructure I built here: &lt;strong&gt;&lt;a href="https://twexapi.io" rel="noopener noreferrer"&gt;Twexapi&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Let's Discuss
&lt;/h3&gt;

&lt;p&gt;Outsource the data extraction, and save your context window (and your sanity) for the actual application logic. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How are you all handling dynamic social data ingestion for your agents right now? &lt;/li&gt;
&lt;li&gt;Do you build your own scrapers or rely on third-party APIs? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love to hear your stack and experiences in the comments! 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>automation</category>
      <category>indiedev</category>
    </item>
  </channel>
</rss>
