---
title: "Sync an external post"
method: POST
path: "/v1/posts/sync-external"
tags: ["Analytics"]
---

# Sync an external post

`POST /v1/posts/sync-external`

Fetch an account's latest external posts (published directly on the platform, not through Zernio) on demand, so a just-published post is retrievable within seconds instead of waiting for the background sync (which refreshes each account at most every ~90 minutes).

Primary use case: verifying a submitted post. When a user publishes on the platform and immediately pastes the post URL into your app, call this with `accountId` plus `url` (or `postId`) to confirm the post exists and return its metadata.

Behavior:
- We check our stored copy first and return immediately if the post is already known (no platform call).
- Otherwise we fetch the account's latest posts live from the platform, then match and return the submitted post.
- Requests are debounced per account (~15s): if the account was just synced, the live fetch is skipped.

`accountId` is required — a post URL or id alone cannot be resolved to an account, and the account must be connected to Zernio (we use its token to read the platform). Supported for every platform with a listing API (Instagram, Facebook, TikTok, YouTube, X, Threads, Pinterest, Reddit, Bluesky, Google Business, and LinkedIn organization accounts).

LinkedIn personal profiles: LinkedIn has no listing API for personal profiles, so a `url` is REQUIRED and imports that single post. Pass any LinkedIn post URL (`linkedin.com/posts/…`, `linkedin.com/feed/update/urn:li:activity:…`) or a `urn:li:share:…` / `urn:li:ugcPost:…` URN. Works for posts published outside Zernio and before the account was connected, any age; the post must be authored by the connected member. Imported posts return full analytics (impressions, reach, reactions, comments, reshares, saves) and keep refreshing on the background analytics cycle, but carry no content/media (LinkedIn does not expose them for personal profiles).

`url` accepts any format the platform uses (e.g. `instagram.com/p/…`, `instagram.com/reel/…`, `youtu.be/…`, `youtube.com/shorts/…`, `tiktok.com/@user/video/…`, and `vm.tiktok.com` short links). Pass `postId` (the platform media/video id) as an alternative locator.

Note: post-level analytics (reach, impressions) still carry the platform's own delay (e.g. ~24h on Instagram). This endpoint confirms the post exists and returns its metadata plus basic engagement (likes, comments), not delayed insights.

## Request body

- object
  - `accountId` string, required — SocialAccount ID whose posts to sync. Must be connected to Zernio.
  - `url` string — The post URL to locate. Optional. Provide `url` or `postId` to return a specific post; omit both to just refresh and return the account's recent posts.
  - `postId` string — The platform post/media/video id to locate, as an alternative to `url`. Optional.

## Response `200`

Sync result. When `url` or `postId` is provided, returns the matched post (or `found: false`). When neither is provided, returns the account's freshly-synced recent posts.

- object
  - `synced` object
    - `postsFound` integer — Posts returned by the platform listing during the on-demand sync
    - `postsSynced` integer — Posts inserted or updated in Zernio
    - `skipped` boolean — True when no live fetch ran: the post was already stored, or the account was synced within the debounce window
  - `found` boolean — Present only when a locator (`url`/`postId`) was provided — whether the post was found.
  - `post` ExternalPostSummary — A post synced from a platform (published directly on the platform, not through Zernio). Returned by GET /v1/posts?source=external and POST /v1/posts/sync-external. Analytics are exposed separately via GET /v1/analytics?source=external.
    - `platform` string — Platform the post belongs to (e.g. instagram, youtube, tiktok)
    - `platformPostId` string — The platform's own post/media/video id
    - `platformPostUrl` string — Canonical URL (permalink) of the post on the platform
    - `content` string — Post caption / text
    - `publishedAt` string, date-time — When the post was published on the platform
    - `mediaType` string — Media type (e.g. image, video, carousel)
    - `mediaUrl` string — Primary media URL
    - `thumbnailUrl` string — Thumbnail URL
    - `mediaItems` object[] — Per-item media (for carousels / multi-media posts)
    - `analytics` object — Engagement + insights for the post. `likes` and `comments` are available immediately after an on-demand sync (they come from the platform listing). `reach`, `impressions`, `views` depend on the platform's insights, which carry their own delay (e.g. ~24h on Instagram) and read 0 until the platform makes them available.
      - `likes` integer
      - `comments` integer
      - `shares` integer
      - `saves` integer
      - `sends` integer
      - `clicks` integer
      - `views` integer
      - `reach` integer
      - `impressions` integer
      - `engagementRate` number
      - `lastUpdated` string, date-time — When these metrics were last refreshed
  - `posts` ExternalPostSummary[] — The account's recent external posts. Present only when no locator was provided.
    - `platform` string — Platform the post belongs to (e.g. instagram, youtube, tiktok)
    - `platformPostId` string — The platform's own post/media/video id
    - `platformPostUrl` string — Canonical URL (permalink) of the post on the platform
    - `content` string — Post caption / text
    - `publishedAt` string, date-time — When the post was published on the platform
    - `mediaType` string — Media type (e.g. image, video, carousel)
    - `mediaUrl` string — Primary media URL
    - `thumbnailUrl` string — Thumbnail URL
    - `mediaItems` object[] — Per-item media (for carousels / multi-media posts)
    - `analytics` object — Engagement + insights for the post. `likes` and `comments` are available immediately after an on-demand sync (they come from the platform listing). `reach`, `impressions`, `views` depend on the platform's insights, which carry their own delay (e.g. ~24h on Instagram) and read 0 until the platform makes them available.
      - `likes` integer
      - `comments` integer
      - `shares` integer
      - `saves` integer
      - `sends` integer
      - `clicks` integer
      - `views` integer
      - `reach` integer
      - `impressions` integer
      - `engagementRate` number
      - `lastUpdated` string, date-time — When these metrics were last refreshed

## Other responses

- `400` — Invalid request (e.g. `accountId` missing or malformed)
- `404` — Account not found (or not owned by the authenticated user)

---

[API](https://skmtc.net/zernio/apis/zernio-api.md) · [All operations](https://skmtc.net/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/zernio/zernio-api/revisions/f81ca70ea6b9/schema)
