Tweet id to date
When an X post was made, to the millisecond, read from the number in its URL. It runs in your browser: nothing is sent anywhere, and it is free.
The time is inside the id: nothing is sent anywhere.
How it works
Since November 2010, every id X makes is a Snowflake: a 64-bit number whose top 41 bits count the milliseconds since X’s epoch, 4 November 2010 at 01:42:54.657 UTC. Shift the id right by 22 bits, add the epoch, and you have the moment the post was made. The low 22 bits say which machine made the id and in what order, so two ids made in the same millisecond still differ.
The same in your own code:
// an X id is a Snowflake: its top 41 bits are milliseconds since X's epoch
const EPOCH = 1288834974657n; // 4 November 2010, 01:42:54.657 UTC
const postDate = (id: string) => new Date(Number((BigInt(id) >> 22n) + EPOCH));
postDate('1930652241230168143').toISOString(); // '2025-06-05T15:45:38.750Z'The rest of the post
The id gives the time and nothing else. GET /v1/x/post gives the whole post: its text, author, replies, reposts, likes and views, with the field names X’s API v2 uses. A call costs 3 credits, $2.34 per 1,000 on the smallest pack, and with no key it answers from the demo. Every endpoint for X is on the ScrapeField X API page.
Questions
Does it work for a deleted post?
Yes. The time is in the id, and the id stays in every link to the post, whether the post is still up or not.
Why does it not work for an old post?
Posts from before 4 November 2010 have ids from a plain counter, with no time in them. For those, only the post itself says when it was made.
Is the time exact?
To the millisecond, as X recorded it. X’s own created_at rounds it down to the second.