# Read post statistics Pickpost reads the statistics of every published post from the network it went to: views, likes, comments, shares and whatever else that network reports. People see them under a published post in the editor and on the **Analytics** page. Scripts and agents read them with two read-only tools, `posts.metrics` and `analytics.summary` (scope `posts:read`). ## When the numbers are read The server reads each post 1 hour, 6 hours, 24 hours, 3 days, 7 days and 30 days after it was published, then stops. The numbers you get are the network's own, as of `fetchedAt`. They do not change between two reads. When a network says to slow down (HTTP 429 or 503), that read moves a few hours later. X's read quotas are small on its lower API tiers, so X waits 3 hours. ## What each network reports | Network | Views | Reach | Likes | Comments | Shares | Quotes | Saves | Clicks | |---|---|---|---|---|---|---|---|---| | X | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | | | Threads | ✓ | | ✓ | ✓ | ✓ | ✓ | | | | Facebook Page | ✓ | ✓ | ✓ | ✓ | ✓ | | | | | Instagram | ✓ | ✓ | ✓ | ✓ | ✓ | | ✓ | | | TikTok | ✓ | | ✓ | ✓ | ✓ | | | | | YouTube | ✓ | | ✓ | ✓ | | | | | | Pinterest | ✓ | | | | | | ✓ | ✓ | | Bluesky | | | ✓ | ✓ | ✓ | ✓ | ✓ | | | Mastodon | | | ✓ | ✓ | ✓ | ✓ | | | | Pixelfed | | | ✓ | ✓ | ✓ | | | | Replies count as comments. Reposts, retweets and boosts count as shares. Bookmarks count as saves. Pinterest's pin clicks and outbound clicks add up to clicks. `providers.limits` returns the same list per network, as `constraints.metrics`. LinkedIn, LinkedIn Pages and Google Business Profile report nothing. LinkedIn keeps post statistics for its approved partner programs, and Business Profile has none for posts. Some details: - **Engagement** is likes, comments, shares, quotes and saves added up, the ones the network reports. Views and clicks are not engagement. - **Instagram stories** report views, reach and shares only, and nothing until 5 people saw them. - **Facebook Pages** get views and reach only once the Page has 100 likes. Smaller Pages still get likes, comments and shares. - **TikTok** returns a public id for a post only once it is public. A post that was still processing when publishing ended has no statistics. ## Reconnect accounts connected before statistics Threads, Facebook Pages, Instagram and TikTok ask for an extra permission to read statistics. Accounts connected before Pickpost asked for it show "Reconnect Threads to allow statistics" (or the network's name) instead of numbers. Go to **Social accounts** and connect the account again. Its posts are read right after that. Pickpost never disconnects an account because of statistics. A missing permission or a refused token only stops the statistics for that account until it is reconnected. Publishing keeps working as before. X, YouTube, Pinterest, Bluesky, Mastodon and Pixelfed need nothing new. ## One post: `posts.metrics` ```bash curl -s -X POST "$PICKPOST_URL/api/agent/tools/posts.metrics" \ -H "Authorization: Bearer $PICKPOST_TOKEN" \ -H "Content-Type: application/json" \ -d '{"id":"b409396fb0054c95"}' ``` ```json {"postId":"b409396fb0054c95","accounts":[ {"accountId":"17f610434e3f47ca","provider":"Bluesky","externalId":"dryrun-1790043000-b772df6c","publishedAt":"2026-09-22T02:10:00Z", "metrics":{"likes":77,"comments":11,"shares":9,"quotes":2,"saves":6,"fetchedAt":"2026-09-26T15:56:13.333152Z"}, "nextFetchAt":"2026-09-29T02:10:00Z"}, {"accountId":"98abf4aafd41458c","provider":"X","externalId":"dryrun-1790043000-37013a63","publishedAt":"2026-09-22T02:10:00Z", "metrics":{"views":4221,"likes":186,"comments":25,"shares":21,"quotes":5,"saves":15,"fetchedAt":"2026-09-26T15:56:13.333152Z"}, "nextFetchAt":"2026-09-29T02:10:00Z"}]} ``` The answer above comes from a dry-run server, so the `externalId` values are made up. On a real one they are the network's post ids. There is one entry per account the post was published to. A metric the network does not report is left out. `metrics` is missing until the first read, and `nextFetchAt` is missing once the schedule is over or the network reports nothing. When a read failed, `metrics.error` says why and the numbers are those of the read before. ## A time range: `analytics.summary` ```bash curl -s -X POST "$PICKPOST_URL/api/agent/tools/analytics.summary" \ -H "Authorization: Bearer $PICKPOST_TOKEN" \ -H "Content-Type: application/json" \ -d '{"from":"2026-09-01T00:00:00Z","to":"2026-09-27T00:00:00Z","timeZone":"Asia/Ho_Chi_Minh"}' ``` ```json {"from":"2026-09-01T00:00:00Z","to":"2026-09-27T00:00:00Z","timeZone":"Asia/Ho_Chi_Minh", "totals":{"posts":10,"views":52613,"reach":7508,"likes":2829,"comments":385,"shares":323,"quotes":64,"saves":139,"clicks":0,"engagement":3740}, "byAccount":[{"accountId":"98abf4aafd41458c","provider":"X","totals":{"posts":6,"views":27050,"likes":1191,"engagement":1616,…}},…], "byNetwork":[{"provider":"X","totals":{"posts":6,"views":27050,"likes":1191,"engagement":1616,…}},…], "topPosts":[{"postId":"e6b7b3568c214ee6","text":"Live music on Saturday night with Mai Linh Trio. Free entry, book a table.", "publishedAt":"2026-09-12T12:10:00Z","accountIds":["6c14be5439a046a2","82b832b1f86a41ef","98abf4aafd41458c"],"engagement":654,"views":11341},…], "bestTimes":[{"weekday":2,"hour":9,"posts":3,"engagement":1289,"average":429.67,"lowConfidence":false}, {"weekday":4,"hour":12,"posts":1,"engagement":530,"average":530.0,"lowConfidence":true},…]} ``` - `from` is inclusive and `to` exclusive, both ISO-8601 instants, at most 400 days apart. Posts count by when they were published. - `accountIds` limits the summary to those accounts. Leave it out for every account. - `topPosts` holds the 10 posts with the most engagement, added up over their accounts. - `bestTimes` has one entry per weekday (1 is Monday, 7 is Sunday) and hour in `timeZone` that had posts. A post sent to several accounts counts once. `average` is engagement per post. An hour with fewer than 3 posts is `lowConfidence`: too few to go by, so do not present it as a rule. An unknown time zone counts as UTC. A malformed range answers `400 BadInput`: ```json {"code":"BadInput","message":"from must be an ISO-8601 instant, such as 2026-09-01T00:00:00Z.","issues":[]} ``` The assistant in the app uses the same two tools to answer "which post did best last week?" and "when should I post?", in your time zone.