← BulkPublishCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to BulkPublish
Snapshot Sep 30, 2026 · 23:08 UTC · version 2.0.5
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "get-analytics",
"description": "Pull analytics, engagement metrics, and performance data from BulkPublish. Use when the user asks about post performance or engagement.",
"included_files": [],
"skill_md_contents": "---\nname: get-analytics\ndescription: Pull analytics, engagement metrics, and performance data from BulkPublish. Use when the user asks about post performance or engagement.\n---\n\n# BulkPublish — Analytics Reference\n\n## Tools\n\n| Tool | Use for | Key params |\n|---|---|---|\n| `get_analytics` | Overall summary for a date range | `startDate`, `endDate` (ISO dates) |\n| `get_post_metrics` | Single post engagement | `postId` |\n| `view_analytics` | Same summary as an interactive dashboard | same as `get_analytics` |\n| `list_posts` | Find posts to analyze | `status`, `approvalStatus`, `from`, `to`, `channelId`, `search` |\n\n## get_analytics response shape\n\nReturns: total posts, status breakdown (any of the 7 post statuses: draft, scheduled, publishing, published, processing, failed, partial), per-platform counts, daily post counts for the range.\n\nPosts also carry `approvalStatus` (`none` default | `pending` | `approved` | `rejected`), which is separate from `status` — filter `list_posts` with `approvalStatus: \"pending\"` to see the team approval queue. Pending and rejected posts never publish on their own.\n\n## get_post_metrics response shape\n\nReturns per-platform: likes, comments, shares, impressions, reach, clicks, saves, videoViews, engagementRate.\n\nPlus `linkClicks` (and `totals.linkClicks` / `totalLinkClicks`): clicks on\nbulkpubli.sh short links, measured by BulkPublish rather than reported by the\nplatform.\n\n### Never report a 0 without checking `supportedMetrics` first\n\nEvery platform entry carries two support fields:\n\n- `metricsSupported` — `false` when the platform has no per-post statistics API at all.\n- `supportedMetrics` — the list of metric keys that platform *can* populate.\n\nAll metric columns are stored as integers defaulting to `0`, so a metric the\nplatform never reports is indistinguishable from a real zero **unless you read\n`supportedMetrics`**. A key that is not in that list is **not a measurement** —\nsay \"not reported by <platform>\" or show a dash. Reporting it as `0` tells the\nuser their post got zero engagement when the platform simply has no such metric.\n\n### `linkClicks` is the one metric every platform has\n\n`linkClicks` is measured by BulkPublish, not the platform, so it is populated\neven for the platforms in the \"reports nothing\" row below, and `supportedMetrics`\nalways contains it. Two rules when reporting it:\n\n- **Never add it to `clicks`/`totalClicks`.** Those are the platform's own click\n figures. One visit can register in both, so summing them double-counts.\n- **A 0 here is ambiguous in a specific way**: it means no tracked clicks, which\n also happens when the organization has link tracking switched off, when the\n post contained no links, or when shortening was skipped on that channel for\n exceeding its character limit. Bot and link-preview traffic is excluded by\n design. Say \"no tracked link clicks\" rather than \"nobody clicked\".\n\n| Platform | Reports | Never reports |\n|---|---|---|\n| X | impressions, likes, comments, shares, saves (bookmarks) | reach, clicks, video views |\n| YouTube | impressions, video views, likes, comments | reach, shares, saves, clicks |\n| Instagram | impressions, reach, likes, comments, shares, saves | clicks, video views |\n| Facebook | likes, comments, shares + impressions, reach, clicks¹ | saves, video views |\n| LinkedIn (company pages) | impressions, reach, likes, comments, shares, clicks | saves, video views |\n| TikTok | impressions, video views, likes, comments, shares | reach, saves, clicks |\n| Threads | impressions, likes, comments, shares | reach, saves, clicks, video views |\n| Pinterest | impressions, clicks, saves, likes, comments, video views | reach |\n| Bluesky | likes, comments, shares, saves (bookmarks) | impressions, reach, clicks, video views |\n| Mastodon | likes, comments, shares | everything else |\n| Discord | likes (reaction counts), comments (thread replies) | everything else |\n| Google Business, Telegram, Tumblr | *nothing* | — |\n| LinkedIn personal profiles | *nothing* | — |\n\n¹ Facebook's impressions/reach/clicks come from Page Insights and need the\n`read_insights` permission. Without it they stay `0` — \"may not be readable\",\nwhich is neither a dash nor a trustworthy figure.\n\n`engagementRate` is derived from impressions, so it exists only where\nimpressions do — it is always `0` for Bluesky and Mastodon.\n\n### Two more reasons a figure can legitimately be 0\n\n- **Not synced yet.** Figures come from a snapshot refreshed every 6 hours, not a\n live read. A just-published post appears immediately with zeros.\n- **Metrics sync switched off.** X reads are billed, so per-post sync is opt-in\n per channel and runs at most weekly. The engagement response lists affected\n channels in `metricsDisabledChannels`; until the user enables it on the\n Channels page, every X figure stays 0 and refreshing cannot change that.\n\n## Patterns\n\n- \"How did my posts do this week?\" → `get_analytics` with last 7 days\n- \"Which post got the most likes?\" → `list_posts` (status: \"published\") then `get_post_metrics` for each\n- Date params are ISO date strings: \"2026-04-01\", not datetime\n"
}SHA-256: fa850291589d37ce1f9fc9ed76111478ebdba3c4365a9b62e67e757441f7aa7a