Analytics API
The analytics endpoints expose the insight data post.buzz collects per account and per post, plus computed recommendations. This is the API counterpart of Analytics.
Requires authentication.
Insights summary
GET /api/v1/analytics/summary?windowDays=30
Returns the latest insight row per account for the requested window, as a
plain array inside data.
| Parameter | Type | Default | Description |
|---|---|---|---|
windowDays | integer | 30 | Look-back window in days |
Example
curl "https://<your-api-origin>/api/v1/analytics/summary?windowDays=7" \
-H "Authorization: Bearer sx_live_YOUR_API_KEY"
Response — 200 OK
{
"data": [
{
"accountId": "acc_abc123",
"platform": "instagram",
"impressions": 48200,
"likes": 1240,
"comments": 86,
"capturedAt": "2026-07-12T00:00:00.000Z"
}
]
}
Field availability varies by platform — rows contain what each platform reports.
Best posting times
GET /api/v1/best-times?accountId=<id>
Returns computed recommendations for when to post, based on your accounts' historical engagement.
| Parameter | Type | Required | Description |
|---|---|---|---|
accountId | string | no | Restrict analysis to one account |
accountIds | string | no | Comma-separated list; combine specific accounts |
Response — 200 OK
{
"data": {
"hasEnoughData": true,
"modelVersion": "bt-2",
"timeZone": "America/New_York",
"confidence": "medium",
"sampleCount": 42,
"windows": [
{
"dow": 2,
"startHour": 18,
"endHour": 21,
"score": 0.31,
"reason": "Based on your mature post performance"
}
],
"nextSlots": [
{ "at": "2026-10-27T22:40:00.000Z", "score": 0.31, "windowIndex": 0 }
],
"dailySlots": [
{ "at": "2026-10-25T20:00:00.000Z", "score": 0.12, "windowIndex": -1 }
],
"grid": [{ "dow": 2, "hour": 18, "score": 0.31, "n": 6.2 }],
"recommendations": [
{
"day": "Tuesday",
"hour": 22,
"reason": "Based on your mature post performance"
}
]
}
}
Scores come from a per-account model that compares each post's engagement
against the account's own baseline (see grid for the full 168-cell week,
windows for merged posting windows in the audience's timezone, and
nextSlots for the strongest upcoming UTC instants over the next two weeks,
and dailySlots for each audience-local day's single strongest open instant,
including days with no top pick). recommendations keeps the
legacy shape for compatibility: the next five slots' UTC day name and hour.
With little or no history the model falls back to platform benchmark priors:
confidence is "low" and hasEnoughData is false, while windows and
nextSlots still return prior-driven suggestions. confidence rises to
"medium" and "high" as the account's own mature posts dominate the
recommended windows.
When you pass accountId or accountIds, every nextSlots and dailySlots entry respects each
selected account's minimum post gap and daily cap, so it is safe to schedule
one cross-post at that instant. Without a selection, the response combines all
connected accounts into one grid, expressed in the timezone most of them use,
and both slot lists reflect only that combined audience's timing.
Post analytics
GET /api/v1/posts/{id}/analytics
Returns the insight row recorded for one published post inside data; 404
with { "error": "Insight not found" } if none exists yet. See
Posts API.
Account analytics
GET /api/v1/accounts/{id}/analytics
Returns post.buzz's computed analysis of one account's recent performance —
for example its bestTone and bestPostType — inside data.
Force an insight refresh
POST /api/v1/accounts/{id}/analytics/refresh
Queues an immediate re-fetch of platform insights for one account (normally
insights sync on a schedule). Returns a job descriptor inside data.
Request body
| Field | Type | Default | Description |
|---|---|---|---|
windowDays | integer | 90 | How far back to fetch |
limit | integer | 50 | Max posts to fetch insights for |
Response — 200 OK
{
"data": {
"jobId": "job_...",
"status": "queued"
}
}
Rate limit — 429
Manual refreshes are capped at 3 per rolling 24 hours per account
(configurable per account; 0 disables). Exceeding the cap:
{
"error": {
"code": "rate_limited",
"message": "Daily insight refresh limit reached for this account (3/3). Next slot in 14h 2m."
}
}
The message always reports your usage count and when the next slot opens.
404 not_found for an unknown account; 500 server_error if queuing fails.
Don't poll-refresh on a timer — scheduled syncs keep insights fresh on their own. Use forced refresh after a known viral spike or an import.
Related
- Analytics — the user-facing dashboards.
- Limits — the full rate-limit story.
- Accounts API — list account IDs.