Skip to content

Python guide

Scrape X (Twitter) posts
with Python.
One script. No developer account.

Text, likes, reposts, replies, views and dates for a public X account’s recent posts, saved to CSV. One API key. No X login, developer account or browser.

  • 3 creditsper page
  • 17posts on the recorded page
  • 0developer accounts
import csv
import os
import requests

API_URL = "https://www.monocrawl.com/v1/x/tweets"
HEADERS = {"x-api-key": os.environ["MONOCRAWL_API_KEY"]}


def get_posts(handle, max_pages=5):
    params = {"handle": handle}
    for _ in range(max_pages):
        body = requests.get(API_URL, params=params, headers=HEADERS, timeout=60).json()
        if not body.get("success"):
            raise RuntimeError(body["error"]["message"])
        yield from body["data"]["items"]
        if not body["data"].get("has_more"):
            break
        params = {"handle": handle, "cursor": body["data"]["cursor"]}


with open("posts.csv", "w", newline="", encoding="utf-8") as file:
    writer = csv.writer(file)
    writer.writerow(["id", "created_at", "likes", "reposts", "replies", "views", "url", "text"])
    for post in get_posts("redbull"):
        stats = post["stats"]
        writer.writerow([post["id"], post["created_at"], stats["likes"], stats["retweets"],
                         stats["replies"], stats["views"], post["url"], post["text"]])

$ python posts.py

GET /v1/x/tweets handle=redbull · page 1

✓ 17 posts · 3 credits · has_more: true

↻ following the cursor until has_more is false or max_pages

✓ posts.csv · each further page ≈ 17 posts for 3 credits (estimate)

Replay of a real call, recorded 26 Sep 2026

Four steps

Copy, paste, run.
See what each step returns.

Terminal
export MONOCRAWL_API_KEY="mn_your_key_here"
pip install requests

What you get

MONOCRAWL_API_KEY=mn_••••••••Free plan · 1,000 credits a month · No card

What comes back

One page.
Real posts.

A real page of Red Bull’s posts on X: 17 posts for 3 credits. 6 are below, with their likes, reposts, replies and views.

  • idThe post’s X id
  • textThe post’s full text
  • created_atWhen, as an ISO timestamp
  • statsLikes, reposts, replies, quotes, bookmarks and views
  • urlThe post on x.com
  • media_urlsImages and video attached to it
  • hashtags, mentions, linksWhat the text contains
  1. anything is a ramp, even an 88.91m-tall building 😮‍💨 it's been 365 days since this INSANE world record, let's go!!! @diassandro 🔥 🛹: @redbullskate 🤝: @Prada https://t.co/y0Jj6KaOhk

    7612719,37225 Sept 2026
  2. what’s the ultimate sign of confidence? 😎

    345729,51423 Sept 2026
  3. what deserves a Red Bull right now? 👀

    196179151,32722 Sept 2026
  4. that's just the training? 🤯 💪: Noa Diorgina https://t.co/3zE8cmIpfK

    36014867,56821 Sept 2026
  5. ever wanted to be behind the booth? 👀 🎧: @JamesHYPE 🤝: @oakley https://t.co/6HDO105mwf

    12617836,12617 Sept 2026
  6. what’s the biggest flex?

    3141732,11416 Sept 2026
Show the JSON
{
  "success": true,
  "data": {
    "count": 17,
    "has_more": true,
    "cursor": "mxc1.…",
    "items": [
      {
        "id": "2103489014393118964",
        "url": "https://x.com/redbull/status/2103489014393118964",
        "text": "anything is a ramp, even an 88.91m-tall building 😮‍💨\n\nit's been 365 days since this INSANE world record, let's go!!! @diassandro  🔥\n\n🛹: @redbullskate \n🤝: @Prada https://t.co/y0Jj6KaOhk",
        "created_at": "2026-09-25T14:17:16.000Z",
        "stats": {
          "likes": 76,
          "retweets": 12,
          "replies": 7,
          "views": 19372
        }
      },
      {
        "id": "2102759899335958774",
        "url": "https://x.com/redbull/status/2102759899335958774",
        "text": "what’s the ultimate sign of confidence? 😎",
        "created_at": "2026-09-23T14:00:02.000Z",
        "stats": {
          "likes": 34,
          "retweets": 5,
          "replies": 7,
          "views": 29514
        }
      },
      {
        "id": "2102397509003866351",
        "url": "https://x.com/redbull/status/2102397509003866351",
        "text": "what deserves a Red Bull right now? 👀",
        "created_at": "2026-09-22T14:00:01.000Z",
        "stats": {
          "likes": 196,
          "retweets": 17,
          "replies": 91,
          "views": 51327
        }
      },
      {
        "id": "2102035115870392394",
        "url": "https://x.com/redbull/status/2102035115870392394",
        "text": "that's just the training? 🤯\n\n💪: Noa Diorgina https://t.co/3zE8cmIpfK",
        "created_at": "2026-09-21T14:00:00.000Z",
        "stats": {
          "likes": 360,
          "retweets": 14,
          "replies": 8,
          "views": 67568
        }
      },
      {
        "id": "2100585573077450759",
        "url": "https://x.com/redbull/status/2100585573077450759",
        "text": "ever wanted to be behind the booth? 👀\n\n🎧: @JamesHYPE \n🤝: @oakley https://t.co/6HDO105mwf",
        "created_at": "2026-09-17T14:00:02.000Z",
        "stats": {
          "likes": 126,
          "retweets": 17,
          "replies": 8,
          "views": 36126
        }
      },
      {
        "id": "2100223380460904880",
        "url": "https://x.com/redbull/status/2100223380460904880",
        "text": "what’s the biggest flex?",
        "created_at": "2026-09-16T14:00:48.000Z",
        "stats": {
          "likes": 31,
          "retweets": 4,
          "replies": 17,
          "views": 32114
        }
      }
    ]
  }
}

Cost

3 credits a page.
Nothing for failures.

Every page of posts costs 3 credits; the recorded page returned 17. Keyword search costs 1 credit a page. Slide to see what a collection costs.

18credits, 3 per page
55collections like this a month on the free plan
555on Starter, $29 a month

Estimated at 17 posts a page, as on the recorded page. Failed calls are free.

Two more things

Keyword search,
errors and rate limits.

Search posts by keyword

To collect posts about a topic instead of from one account, call x/search-tweets with a query. X’s own operators work, such as from:handle, and mode picks latest or top. About 20 posts a page, 1 credit a page, same cursor.

search.py
SEARCH_URL = "https://www.monocrawl.com/v1/x/search-tweets"

params = {"query": "from:redbull pistachio", "mode": "latest"}
body = requests.get(SEARCH_URL, params=params, headers=HEADERS, timeout=60).json()
for post in body["data"]["items"]:
    print(post["created_at"][:10], post["text"].splitlines()[0])

Errors and rate limits

A failed call returns success: false with an error type and message, and costs nothing. On HTTP 429, wait and try again.

Rate limits by plan
posts.py
import time

def get_page(params, attempts=5):
    for attempt in range(attempts):
        response = requests.get(API_URL, params=params, headers=HEADERS, timeout=60)
        if response.status_code != 429:
            return response.json()
        time.sleep(2 ** attempt)
    raise RuntimeError("Still rate limited; try again later")

Other platforms

Same loop.
Swap the endpoint.

The same key collects an account’s posts on other platforms. Each endpoint’s reference lists its fields and paging.

Questions

Scraping tweets,
answered.

Do I need an X account or a developer account?

No. You call Monocrawl with your API key and get the posts back as JSON. It works for public accounts.

How many posts does one call return?

One page. The recorded page returned 17, with has_more set to true and a cursor for the next page.

What does it cost?

3 credits for each page of an account’s posts, and 1 credit a page for keyword search. The free plan’s 1,000 credits a month cover about 333 pages of posts, and failed calls are free.

Can I search posts by keyword or date?

Yes. x/search-tweets takes a query with X’s own operators, such as from:handle, plus from_date and to_date. It returns about 20 posts a page for 1 credit.

What comes back for each post?

The text, the time, likes, reposts, replies, quotes, bookmarks and views, the post’s URL, attached media, and the hashtags, mentions and links in it.

Does X have an official API?

X’s own API has paid tiers with their own access rules. Our X data API comparison sets out the official routes and the main providers side by side.

Start free

Posts from any public X account.
3 credits a page.

1,000 free credits every month. No card required.

Get a free API key