---
title: "Refresh one account now instead of waiting for the nightly pass"
method: POST
path: "/analytics/{connectedAccountId}/sync"
tags: ["Analytics"]
---

# Refresh one account now instead of waiting for the nightly pass

`POST /analytics/{connectedAccountId}/sync`

## Request

- Base URL: `https://api.multi-upload-tool.com/api/v1`
- URL: `https://api.multi-upload-tool.com/api/v1/analytics/{connectedAccountId}/sync`
- Auth: API key in header `x-api-key`

Reads the platform inside the request, writes the snapshots, then returns the refreshed analytics. Covers up to the 1000 most recent posts.

This is a write: it rotates OAuth tokens, stores snapshots and consumes the platform's rate limit, so it needs manage access to the account, not read access. Use it when someone has just published from the platform's own app — the collector otherwise runs once a night.

## Path parameters

- `connectedAccountId` string, required

## Query parameters

- `timezone` string

## Headers

- `X-Team-ID` integer

## Response `200`

Analytics as of the sync that just ran.

- object
  - `success` unknown
  - `data` Analytics: What the collector holds for the accounts in scope. Every metric is a running total read from the platform, not a per-day figure.
    - `overview` object
      - `totalViews` integer
      - `totalLikes` integer
      - `totalComments` integer
      - `totalShares` integer
      - `videoCount` integer
      - `accountCount` integer
      - `bestAccount` object, nullable
        - `name` string
        - `platform` 'tiktok' | 'youtube' | 'instagram' | 'facebook' | 'linkedin' | 'pinterest' | 'bluesky' | 'threads' | 'x': A supported social platform.
        - `views` integer
    - `videos` object[]: One row per tracked post, with its metrics, an `isTrending` flag and `source`: `mut` if it was published through Multi Upload Tool, `external` if it was posted directly on the platform.
    - `bestPerforming` object, nullable
      - `mostViewed` object
      - `mostEngaging` object
    - `topHashtags` object[]
    - `postingInsights` PostingInsights: When this account has published, and what those slots averaged. Derived from the posts already collected, so it says nothing until there are enough of them.
      - `timezone` string: The zone the buckets were read in — whatever you asked for, or `UTC`.
      - `minSamples` integer: Posts a bucket needs before it can be ranked.
      - `byWeekday` PostingBucket[]: Always 7 entries, Sunday first, including the days with nothing in them.
        - `weekday` integer: 0 = Sunday, following Postgres' `dow`. Present on `byWeekday` and `bestDay`.
        - `hour` integer: Hour of day in the requested timezone. Present on `byHour` and `bestHours`.
        - `posts` integer
        - `avgViews` integer
        - `ranked` boolean: False when `posts` is under `minSamples`. The bucket keeps its average — it is worth showing — but it is never eligible to win. One lucky post is a coincidence, not a slot, and it is the loudest one: a single viral video gives its bucket an average no honest bucket can beat.
      - `byHour` PostingBucket[]: Always 24 entries, 00:00 first.
        - `weekday` integer: 0 = Sunday, following Postgres' `dow`. Present on `byWeekday` and `bestDay`.
        - `hour` integer: Hour of day in the requested timezone. Present on `byHour` and `bestHours`.
        - `posts` integer
        - `avgViews` integer
        - `ranked` boolean: False when `posts` is under `minSamples`. The bucket keeps its average — it is worth showing — but it is never eligible to win. One lucky post is a coincidence, not a slot, and it is the loudest one: a single viral video gives its bucket an average no honest bucket can beat.
      - `bestDay` PostingBucket: One weekday or one hour of day, averaged over the posts that landed in it.
        - `weekday` integer: 0 = Sunday, following Postgres' `dow`. Present on `byWeekday` and `bestDay`.
        - `hour` integer: Hour of day in the requested timezone. Present on `byHour` and `bestHours`.
        - `posts` integer
        - `avgViews` integer
        - `ranked` boolean: False when `posts` is under `minSamples`. The bucket keeps its average — it is worth showing — but it is never eligible to win. One lucky post is a coincidence, not a slot, and it is the loudest one: a single viral video gives its bucket an average no honest bucket can beat.
      - `bestHours` PostingBucket[]: Up to 5 hours, best first. Ranked buckets only.
        - `weekday` integer: 0 = Sunday, following Postgres' `dow`. Present on `byWeekday` and `bestDay`.
        - `hour` integer: Hour of day in the requested timezone. Present on `byHour` and `bestHours`.
        - `posts` integer
        - `avgViews` integer
        - `ranked` boolean: False when `posts` is under `minSamples`. The bucket keeps its average — it is worth showing — but it is never eligible to win. One lucky post is a coincidence, not a slot, and it is the loudest one: a single viral video gives its bucket an average no honest bucket can beat.
      - `sampleSize` integer: Posts carrying a publication date, i.e. what the buckets were built from.
    - `dailyHistory` object[]
    - `platformHistory` object[]
    - `summary` object: The last 30 days against the 30 before. `null` means not measured, never zero.
      - `windowDays` 30
      - `views` object: Views gained in each period, summed from the daily series (gaps spread evenly, as on the chart). `measuredDays` says how many days of each period had data.
        - `current` integer, nullable
        - `previous` integer, nullable
        - `change` integer, nullable
        - `changePct` number, nullable
        - `measuredDays` object
          - `current` integer
          - `previous` integer
      - `followers` object: `total` = latest follower count summed over accounts. `change` only counts accounts that were also measured 30 days ago, so it stays `null` for the first 30 days of history.
        - `total` integer, nullable
        - `previous` integer, nullable
        - `change` integer, nullable
        - `changePct` number, nullable
      - `postsPublished` object
        - `current` integer
        - `previous` integer
        - `change` integer
    - `followerHistory` object[]: One point per day over the window: the sum of each account's last known follower count. Days before the first reading are omitted.
      - `date` string, date
      - `followers` integer
    - `accountTags` string[]: Only on the single-account route.
    - `lastRefreshedAt` string, date-time, nullable: When the collector last read the platform. Show it next to the numbers.
    - `neverSynced` boolean: `true` means nothing has ever been collected, as opposed to collected and empty. The two deserve different messages: "connect and wait for tonight" is not "you have no posts yet".
    - `syncErrors` object[]: Accounts whose last collection failed. A failing account never stops the others.
      - `accountName` string
      - `platform` 'tiktok' | 'youtube' | 'instagram' | 'facebook' | 'linkedin' | 'pinterest' | 'bluesky' | 'threads' | 'x': A supported social platform.
      - `error` string

## Other responses

- `401`: The API key is missing, invalid, revoked or expired.
- `403`: The token is valid but not permitted to act on this resource, usually because of team scoping or the caller's team role.
- `404`: No such resource, or it does not belong to the caller.

---

[API](https://skmtc.dev/multi-upload-tool/apis/multi-upload-tool-api.md) · [All operations](https://skmtc.dev/multi-upload-tool/apis/multi-upload-tool-api/llms.txt) · [OpenAPI document](https://skmtc.dev/multi-upload-tool/apis/multi-upload-tool-api/revisions/bb7e72abbb76?raw)
