WEIR

Tweet JSON Example: A Real X Post, Field by Field (2026)

A real tweet JSON example from X, explained field by field and mapped to X API v2 and v1.1 names, with reposts, quotes, media and a tested parse script.


Published · Updated · 7 min read

Cover image: One post, three JSON dialects

Here is a real tweet JSON example: a NASA post we fetched on 22 October 2026, with every field explained.

It's for developers who parse X (Twitter) posts from an API, an old export or a scraper. You also get each field's name in X API v2 and v1.1, plus reposts, quotes and media. We run Weir, the API that returned it.

Fetch the same post yourself:

curl --request GET \
  --url https://api.weirapp.io/v1/x/posts/2041557036274475228 \
  --header "Authorization: Bearer $WEIR_API_KEY"

The tweet JSON example, in full

Weir returned this for NASA's "Hello, Moon" post, under data. We cut three of the four photos, two empty lists and the profile picture:

{
  "id": "2041557036274475228",
  "text": "Hello, Moon. It’s great to be back.\n \nHere’s a taste of what the Artemis II astronauts photographed during their flight around the Moon. Check out more photos from the mission: https://t.co/rzM1P0QbOl https://t.co/6jWINHkDLh",
  "url": "https://x.com/NASA/status/2041557036274475228",
  "lang": "en",
  "createdAt": "2026-04-07T16:41:42.000Z",
  "conversationId": "2041557036274475228",
  "inReplyToId": null,
  "author": { "id": "11348282", "username": "NASA", "followersCount": 92311207 },
  "likeCount": 794766,
  "retweetCount": 169435,
  "replyCount": 9746,
  "quoteCount": 9052,
  "bookmarkCount": 59698,
  "viewCount": 30495055,
  "media": [{ "type": "photo", "url": "https://pbs.twimg.com/media/HFURRWmXYAEcq7c.jpg" }],
  "entities": { "urls": ["https://www.nasa.gov/artemis-ii-multimedia/"] },
  "quotedPost": null,
  "retweetedPost": null
}

The call cost 2 credits: 1 for the call and 1 for the post. Five of its counts, as they stood that day:

NASA's "Hello, Moon" post on 22 October 2026
Likes794,766
Reposts169,435
Bookmarks59,698
Replies9,746
Quotes9,052

Views, at 30,495,055, would flatten every other bar.

What each field in the tweet object means

Every field has one job:

  • id is the post's number, sent as a string. url is its link on x.com.
  • text is the whole post. Its last t.co link opens the photos, so entities.urls lists only the NASA page.
  • lang is the language X detected, as a tag like en.
  • createdAt is the posting time in UTC, in ISO 8601.
  • conversationId names the thread. inReplyToId is null because this post isn't a reply.
  • author is an object: id, username, name, a verified flag and followersCount.
  • The six counts are likes, reposts, replies, quotes, bookmarks and views.
  • media lists photos, videos and GIFs in order. A video's url is its best MP4.
  • entities holds hashtags and mentions without # or @, and links already expanded.
  • article, quotedPost and retweetedPost stay null unless the post is an X Article, a quote or a repost.

The id also carries the posting time. Our Tweet ID to date tool reads it out.

Why tweet ids are strings in JSON

X's post ids are bigger than 2^53, the largest whole number a JavaScript number holds exactly. X's archived v1.1 docs warn that some languages "may have difficulty/silent defects" with them.

Here is what happens to NASA's id when it arrives as a number:

JSON.parse('{"id": 2041557036274475228}').id; // 2041557036274475300
JSON.parse('{"id": "2041557036274475228"}').id; // "2041557036274475228"

That's why v1.1 sent both id and id_str. Use id_str there. Weir and v2 send only strings.

Twitter API JSON response: v2 and v1.1 names

The same post comes back with different names in each API. These are the fields most code reads:

Weir X API v2 v1.1
id id id_str
text text full_text or text
createdAt created_at created_at
author.username username in includes.users user.screen_name
likeCount public_metrics.like_count favorite_count
retweetCount public_metrics.retweet_count retweet_count
replyCount public_metrics.reply_count reply_count
bookmarkCount public_metrics.bookmark_count none

The formats differ too. v1.1 wrote created_at as "Wed Oct 10 20:19:24 +0000 2018", while v2 and Weir use ISO 8601.

In v2 you ask for most fields. A bare request returns only id, text and edit_history_tweet_ids. Add tweet.fields=created_at,public_metrics and expansions=author_id for the rest.

In v1.1, reply_count and quote_count came only with the Premium and Enterprise tiers, says X's archived data dictionary. Weir's viewCount has no exact twin: v2's impression_count counts times a post "appeared on a user's screen."

How reposts, quotes and media look in tweet JSON

Each API nests the related post its own way:

Weir X API v2 v1.1
retweetedPost referenced_tweets, type retweeted retweeted_status
quotedPost referenced_tweets, type quoted quoted_status
inReplyToId referenced_tweets, type replied_to in_reply_to_status_id_str
media[].url includes.media[].url extended_entities.media
entities.mentions entities.mentions[].username entities.user_mentions
entities.hashtags entities.hashtags[].tag entities.hashtags[].text

In v2, the referenced post itself arrives in includes.tweets when you add expansions=referenced_tweets.id.

We saw Weir's repost wrapper in a real search of @XDevelopers on 22 October 2026. One repost, trimmed:

{
  "id": "2113062427566969325",
  "text": "RT @...: New to the X MCP ...",
  "likeCount": 0,
  "retweetCount": 14,
  "retweetedPost": { "id": "2113060281354240105", "likeCount": 133, "retweetCount": 14 }
}
  • The wrapper's own likeCount is 0. The original had 133 likes, so read counts from retweetedPost.
  • Its text is cut short and starts with "RT @". The full text is in retweetedPost.text, as v1.1 kept it in retweeted_status.
  • A quote is the other way round. In the same search, an @XDevelopers quote had 120 likes of its own, and its quotedPost had 128.

That quoted post was an X Article, so it carried an article object too. Our guide to reading X Articles via API covers that shape.

Media differs most. v1.1 listed every video bitrate in video_info.variants, and v2 does the same in variants. Weir picks the highest-bitrate MP4 and gives it as url, with the poster frame in previewImageUrl.

Parse a tweet JSON in Python

This script reads a saved response and handles each trap above. Save the curl output as post.json, then run it:

import json

def summarize(post):
    original = post["retweetedPost"] or post  # a repost wraps the real post
    return {
        "id": post["id"],  # a string: never int() or float() it
        "repost": post["retweetedPost"] is not None,
        "likes": original["likeCount"],  # None means X didn't report it
        "quotes": (post["quotedPost"] or {}).get("id"),
        "photos": sum(1 for m in original["media"] if m["type"] == "photo"),
        "links": original["entities"]["urls"],
    }

with open("post.json", encoding="utf-8") as f:
    print(summarize(json.load(f)["data"]))

On our saved NASA response it prints:

{'id': '2041557036274475228', 'repost': False, 'likes': 794766, 'quotes': None, 'photos': 4, 'links': ['https://www.nasa.gov/artemis-ii-multimedia/']}

Run on the three @XDevelopers results, it flagged both reposts, with 133 and 81 likes, and the quote's target id. To pull many posts at once, see how to get tweets with Python.

When not to use Weir

  • You need X's exact v2 shape. Weir uses its own camelCase names, so v2 code needs the table above.
  • You need to post or reply. Weir is read-only.
  • A contract with X is required. Weir reads public data and isn't licensed by X, so access can change.
  • You only parse old v1.1 files. You need no API at all, just the name tables.

FAQ

What does a tweet look like in JSON?

An X API post in JSON is one object with the post's id, text, time, author and counts. Media, links and mentions sit in lists, and reposts or quotes nest a second post inside. The example at the top shows every field Weir returns.

What is the difference between id and id_str in tweet JSON?

They hold the same number. In v1.1, id was a number, which JavaScript and other languages can round, and id_str was the same id as a string. v2 and Weir send only the string form.

How do I tell if a tweet is a retweet in the JSON?

Look for the original post nested inside. Weir sets retweetedPost, v1.1 sets retweeted_status, and v2 lists a referenced_tweets entry of type retweeted. A repost's own like count is 0 on Weir, so read the original's.

Where is the full text of a tweet in the API response?

In v2 and on Weir, text holds the full post. v1.1 could send a shortened text with truncated set to true, and the whole post came in full_text. For posts over 280 characters, v2 also adds note_tweet.

Sources

All checked on 22 October 2026: