User Analytics
GET/v1/twitter/user/analytics2 credits
Computes an account's engagement from its profile and recent posts: average and median likes, replies and views, engagement rates by followers and by views, and how often it posts, with the sample size and window.
01Query parameters
| Name | Type | Description |
|---|---|---|
| handlerequired | string | X username (a leading `@` is removed). |
| postsoptional | integer | How many recent posts to sample, 1 to 50. X gives one page: the 20 newest posts for most accounts (about 100 top posts for the largest), so more than that changes nothing.Default: 20 |
| tzoptional | string | IANA time zone the `posting_times` weekdays and hours are read in, e.g. `Europe/Istanbul` or `America/New_York`. Daylight saving time follows each post's own date. Any other value is a free 400.Default: UTC |
02Request
curl "https://api.scrapesocial.ai/v1/twitter/user/analytics?handle=NASA&tz=Europe%2FIstanbul" \ -H "x-api-key: $SCRAPESOCIAL_KEY"
03Responses
Real answers from the API. Lists are shortened to 2 items.
GET /v1/twitter/user/analytics?handle=NASA&tz=Europe/Istanbul
{
"success": true,
"credits_remaining": 4980,
"credits_charged": 2,
"platform": "twitter",
"owner": {
"id": "11348282",
"username": "NASA",
"display_name": "NASA"
},
"followers": 92312406,
"sample": {
"posts": 12,
"from": "2026-10-15T19:30:47Z",
"to": "2026-10-23T18:05:54Z",
"posts_read": 20,
"pinned_excluded": 1,
"reposts_excluded": 7
},
"likes": {
"posts": 12,
"missing": 0,
"total": 32527,
"average": 2710.58,
"median": 1866.5
},
"comments": {
"posts": 12,
"missing": 0,
"total": 2086,
"average": 173.83,
"median": 178.5
},
"views": {
"posts": 12,
"missing": 0,
"total": 9385952,
"average": 782162.67,
"median": 798296.5
},
"engagement_rate_by_followers": 0.0031,
"engagement_rate_by_views": 0.3688,
"posts_per_week": 9.7,
"posting_times": {
"timezone": "Europe/Istanbul",
"metric": "engagement",
"posts": 12,
"by_weekday": [
{
"weekday": "monday",
"posts": 0,
"average_engagement": null
},
{
"weekday": "tuesday",
"posts": 4,
"average_engagement": 2018.5
}
],
"by_hour": [
{
"hour": 0,
"posts": 0,
"average_engagement": null
},
{
"hour": 1,
"posts": 0,
"average_engagement": null
}
],
"best_weekday": "friday",
"best_hour": 18,
"best_slot": {
"weekday": "friday",
"hour_from": 21,
"hour_to": 24
},
"min_posts": 2
},
"formula_version": 2,
"formulas": {
"average": "total / posts, over the sampled posts that have the value",
"median": "the middle value of the sampled posts that have the value; the mean of the two middle values when their number is even",
"engagement_rate_by_followers": "100 * average(likes + comments) / followers, over the sampled posts whose likes and comments are both known; null when followers is 0 or unknown",
"engagement_rate_by_views": "100 * sum(likes + comments) / sum(views), over the sampled posts whose likes, comments and views are all known; null when that sum of views is 0",
"posts_per_week": "(sample.posts - 1) / ((sample.to - sample.from) in days / 7); null with fewer than 2 posts or when they share one timestamp",
"posting_times": "engagement = likes + comments of each sampled post whose likes, comments and exact time are known (a time worked back from \"3 weeks ago\" is not); each such post counts in its weekday, its hour and its weekday's 3-hour slot (00-03, 03-06, ... 21-24) in the asked time zone; average_engagement = total engagement / posts of the bucket, null without posts; best_weekday, best_hour, best_slot = the highe…"
}
}Common to every endpoint
Any route can answer these: a missing or wrong key, no credits left, the platform not answering, or a failure on our side. None of them costs credits.
GET /v1/cosmos/profile?handle=design
{
"success": false,
"message": "Invalid API key"
}04Notes
Our own endpoint: ScrapeCreators has no analytics route. Always 2 credits (the profile and the posts page), free on failure. The answer: `platform`, `owner` (`id`, `username`, `display_name`), `followers`, `sample` (`posts`, `from`, `to` in ISO 8601 UTC, `posts_read`, `pinned_excluded`, `reposts_excluded`), `likes`, `comments` and `views` (each `posts`, `missing`, `total`, `average`, `median`), `engagement_rate_by_followers` = 100 × average(likes + comments) / followers, `engagement_rate_by_views` = 100 × sum(likes + comments) / sum(views), `posts_per_week`, `formula_version` and `formulas` (every formula as text). Pinned posts and reposts are left out of the sample. A count the platform does not give (hidden likes, a photo's views) is left out and counted in `missing`, never taken as 0; a rate is `null` when followers or views are 0 or unknown. An account without posts answers its profile with an empty sample. `comments` are replies; retweets are reposts and left out. A protected account is a free 403, an unknown one a free 404. `posting_times` (formula_version 2) says when the sampled posts drew the most engagement, in the time zone `tz` names, from the same posts at no extra cost: `timezone`, `metric` (`engagement` = likes + comments of a post), `posts` (the sampled posts with both counts and a time), `by_weekday` (Monday to Sunday) and `by_hour` (0 to 23), each item with `posts` and `average_engagement` (null without posts), then `best_weekday`, `best_hour` and `best_slot` (`weekday`, `hour_from`, `hour_to`: one of the fixed 3-hour windows 00–03 … 21–24) and `min_posts`. The best bucket has the highest average among those with at least `min_posts` (2) posts; a tie goes to the bucket with more posts, then to the earlier one; null when none has enough. There is no weekday-by-hour grid: 168 cells for 12 to 50 posts would describe single posts. A sample this small is a hint, not a schedule.
05Errors & credits
Every error has success: false, a real HTTP status and costs no credits.
400missing_parameter
A required parameter is missing or invalid.
403private_account
The account is private or age-restricted.
404not_found
No such account.
503upstream_error
The platform did not answer; retry shortly.