Skip to main content

X Articles

Retrieve the full content and metadata of any public X Article in a single request. An Article is a long-form post on X with a cover image, rich text body (up to ~100,000 characters), and engagement metrics separate from its announcement tweet.
Note: For a fuller guide on working with long-form X posts, see X Articles API: Retrieve Long-Form X Posts on the blog.

Quickstart

curl -X POST https://api.sorsa.io/v3/article \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tweet_link": "https://x.com/SorsaApp/status/1234567890"}'
import requests

API_KEY = "YOUR_API_KEY"

def get_article(tweet_link):
    resp = requests.post(
        "https://api.sorsa.io/v3/article",
        headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
        json={"tweet_link": tweet_link},
    )
    resp.raise_for_status()
    return resp.json()


article = get_article("https://x.com/SorsaApp/status/1234567890")
print(f"Author: @{article['author']['username']}")
print(f"Published: {article['published_at']}")
print(f"Views: {article['views']:,}")
print(f"Body length: {len(article['full_text'])} characters")

Endpoint

POST /v3/article

Request Body

ParameterTypeRequiredDescription
tweet_linkstringYesFull URL of the announcement tweet, or just the numeric tweet ID.

Response

{
  "full_text": "this isn't a cosmetic rebrand. it's a response to how crypto twitter actually works in 2026...",
  "preview_text": "this isn't a cosmetic rebrand. it's a response to how crypto twitter actually works in 2026.\nthe old model was simple...",
  "cover_image_url": "https://pbs.twimg.com/media/G-t2hYTaIAAstc8.jpg",
  "published_at": "2026-01-15T16:24:02Z",
  "views": 36538,
  "favorite_count": 315,
  "bookmark_count": 38,
  "quote_count": 37,
  "reply_count": 80,
  "retweet_count": 41,
  "author": {
    "id": "1934538036466810880",
    "username": "SorsaApp",
    "display_name": "Sorsa",
    "description": "Crypto social analytics made simple...",
    "followers_count": 6050,
    "verified": false
  }
}

Response Fields

FieldTypeDescription
full_textstringComplete article body. Can be tens of thousands of characters.
preview_textstringTruncated snippet shown in the timeline before “Read more.”
cover_image_urlstring | nullURL of the cover image. null if no cover was set.
published_atstring (ISO 8601)Publication timestamp (distinct from the announcement tweet’s created_at).
viewsintegerTotal impressions.
favorite_countintegerLikes.
bookmark_countintegerBookmarks.
quote_countintegerQuote tweets.
reply_countintegerReplies.
retweet_countintegerRetweets.
authorobjectFull author profile (same fields as the standard User object).
Field naming. The article response uses favorite_count and views, not likes_count and view_count as in the standard Tweet object. If you process both tweets and articles through the same pipeline, normalize these keys at ingestion. See Response Format for the full schema comparison.

Detecting an Article vs a Regular Tweet

Not every tweet link points to an Article. Try /article first and fall back to /tweet-info if the response lacks a substantive body:
def get_content(tweet_link):
    """Fetch a tweet or article, returning the appropriate object."""
    try:
        article = get_article(tweet_link)
        if article.get("full_text") and len(article["full_text"]) > 500:
            return {"type": "article", "data": article}
    except Exception:
        pass

    resp = requests.post(
        "https://api.sorsa.io/v3/tweet-info",
        headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
        json={"tweet_link": tweet_link},
    )
    resp.raise_for_status()
    return {"type": "tweet", "data": resp.json()}

Next Steps