Data sources, freshness & retention
Where every number comes from, how often it refreshes, what is stored per post, how long data is kept, and what is not built yet.
10 min read
Every metric in the API traces back to a platform. This page explains, platform by platform, how Listener gets the data, what it stores, when it refreshes and how long it keeps it. Where something is not built yet, it says so.
How Listener gets each platform’s data#
There are four ways data reaches Listener. A show can mix them.
| Method | What it means | Platforms |
|---|---|---|
| Authorized API (OAuth) | The show owner signs in to the platform and grants read access. Listener calls the platform’s official API with that grant. | YouTube (YouTube Data and YouTube Analytics APIs), Instagram professional accounts (Instagram API with Instagram Login), Blubrry, Eventbrite |
| Public profile | The show adds a public profile URL or handle. Listener reads the public counters through third-party data providers. No sign-in, so no private insights. | Instagram (accounts not connected with Instagram Login), TikTok, Facebook pages and groups, X, Threads, LinkedIn |
| API key | The show pastes a key or token from the hosting or newsletter platform. Listener calls that platform’s API. | Simplecast, Transistor, Omny Studio, Art19, Captivate, Beehiiv, Substack, Facebook page insights through a Sprout Social token |
| Listener Sync (browser extension) | The show connects Spotify for Creators, Apple Podcasts Connect or Megaphone through the Listener Sync extension. Listener stores the resulting session encrypted and reads the same dashboards the show sees. | Spotify, Apple Podcasts, Megaphone |
When a show has not connected Sync, Spotify and Apple Podcasts numbers can be requested from the Listener team (POST /v1/data-requests); a person pulls them, so they arrive later than automated data. Substack podcast downloads can also be imported from Substack’s stats export.
X is read through a data provider first; when that returns nothing recent, Listener falls back to the official X API with its own credentials (not the show’s).
Public-profile data is public data
For platforms read from a public profile, Listener only sees what the platform shows publicly: views, likes, comments and shares where the platform exposes them. Private insights such as reach, saves or audience demographics need the authorized connection, which today exists for YouTube and Instagram professional accounts.
Posts added by URL#
Anyone with access to a cluster can paste a post URL to add it. Listener fetches the post right away and stores the numbers on the cluster node.
| URL | Fetched through | Captured when added |
|---|---|---|
| YouTube video or Short | Data provider; on refresh, live YouTube API counters when the channel is connected | views, likes, comments |
| YouTube community post | Data provider | likes, comments where available |
| Instagram post or reel | Data provider | views (Instagram’s play count) for reels and videos, likes, comments, shares. Image posts have no views. |
| Instagram story | Entered by hand | views |
| Archived Instagram or Facebook post | Entered by hand | views (reels) or impressions (feed posts) |
| TikTok | Data provider | views, likes, comments, shares |
| Data provider | views, likes (reactions), comments, shares | |
| X | Data provider | views (stored as impressions), likes, reposts, replies, quotes, bookmarks |
LinkedIn (including lnkd.in links) | Data provider | reactions, comments, reposts. No impressions. |
| Threads | Data provider | likes and total engagement. No views. |
| Spotify episode | Data provider | episode details only; plays come from the show’s connected Spotify data |
| Apple Podcasts episode | Apple’s public lookup API | episode details only; plays come from the show’s connected Apple data |
| Data provider | upvotes, comments | |
| Any other web page | Page metadata and a traffic data provider | the site’s monthly visits and rank, not per-article views |
Megaphone URLs can’t be dropped; add Megaphone episodes from the show’s connected Megaphone library. The creator app (listener.com) recognises the same URLs, plus Substack posts.
Added posts refresh with their cluster, as described in Refresh schedule.
What is stored per post#
Each cluster node stores the latest value of each metric, not a history per post.
| Platform | Fields stored | Counted as reach |
|---|---|---|
| YouTube | views, likes, comments; engaged views when the channel is connected | views. Engaged views are reported separately and never added to reach. Long-form and Shorts are split by the show’s duration rule or a format set by hand. |
| views (from Instagram’s play count), likes, comments, shares | views. Image posts have no views, so their engagement stands in. | |
| TikTok | views (TikTok’s play count), likes, comments, shares | views |
| views (play count), likes (reactions), comments, shares | views | |
| X | impressions (X’s view count), likes, reposts, replies | impressions |
| reactions, comments, reposts | LinkedIn does not expose impressions to Listener, so reactions stand in | |
| Threads | likes, total engagement | Threads views are not captured today, so engagement stands in |
| Beehiiv, Substack posts | unique opens, delivered | opens |
| Spotify episode | plays, streams, audience size (Spotify app only) | plays |
| Apple Podcasts episode | plays, listeners, engaged listeners | listeners, then plays |
How a platform defines a view is the platform’s own definition: Listener stores the counter the platform reports and does not recompute it. Instagram now calls its play count “Views”; X reports views as impressions; Spotify numbers cover the Spotify app only.
For account-level LinkedIn analytics, where LinkedIn reports no impressions, Listener estimates impressions from reactions and flags the figure as estimated (impressions_estimated). Cluster reach never uses that estimate.
Refresh schedule#
Account data (a show’s channel or profile) and cluster posts refresh in different ways. All times are UTC.
Account data#
| Trigger | What refreshes |
|---|---|
| Opening Listener | Opening the network dashboard or the public network page refreshes connected platforms for shows whose data is older than 4 hours, a limited number of shows per visit on large networks. |
| Refresh button or API | Refreshes one show and platform now. In the API: POST /v1/shows/{show_id}/platforms/{platform}/refresh. Public-profile platforms (TikTok, X, Facebook, Instagram, Threads, LinkedIn) spend data-provider credits and need confirm: true. |
| Before a scheduled report | 07:00 daily, Listener refreshes the data that reports due in the next two hours will use. Reports send at 08:00. |
| Listener Sync | Spotify, Apple Podcasts and Megaphone accounts connected through Sync refresh automatically once a day (the job works through shows hourly at :20). |
| Daily history capture | Hourly at :40, Listener folds stored data into daily history (no platform calls). |
There is no fixed timer that refreshes every social account every day. Account data moves when someone opens Listener, presses Refresh, calls the refresh endpoint, or when a scheduled report is due. Spotify and Apple data without Sync arrives when the Listener team fulfils a data request.
Cluster posts#
| Trigger | Rule |
|---|---|
| Viewing a public campaign page | Clusters whose last refresh is more than 5 hours old refresh in the background, up to 40 per page view. |
| Refresh button or API | The cluster’s Refresh action, or POST /v1/shows/{show_id}/clusters/{cluster_id}/refresh with confirm: true, refreshes every post in the cluster now. Merged clusters refresh through their source clusters. |
| Nightly job | Not running. A nightly refresh of recent clusters is built but switched off, so clusters refresh on view and on demand only. Use the refresh endpoint when you need fresh numbers. |
Cluster posts therefore refresh only when a public page that shows them is viewed, or when someone refreshes them.
History and retention#
| Data | What is kept | How long |
|---|---|---|
| Daily history | One value per platform per day (reach and engagement), stored per show in yearly shards. Written whenever platform data is saved and re-folded daily. | No expiry. Coverage starts when Listener first saw the platform; some platforms backfill further (for example up to 400 days for Spotify, the full series for Simplecast and Transistor). |
| Recent detail | Each platform’s recent daily series and recent posts on the show record, about the last 30 days. | Rolling; older days live on in daily history. |
| Episode lists | Audio connectors keep at least the 30 most recent episodes; trimming only happens when a show’s record nears its size limit. | Rolling |
| Cluster posts | The latest value of each metric per post. | Until the cluster is deleted |
| Cluster reach per day | A daily total per cluster (all, long-form, short-form), captured once a day and after refreshes. | No expiry |
| Shared reports | A snapshot frozen when shared, or a live report rebuilt at most hourly. | Until deleted |
| API events and webhook deliveries | Event payloads and delivery attempts. | 30 days |
| API request logs | Method, path, status, timing, credential; never bodies. | 14 days |
| Idempotency records | The first response for each key. | 24 hours |
Windows longer than about 30 days read from daily history. Responses say so in coverage.history_used and explain gaps in coverage.warnings (see Time windows).
Disconnecting, deleting and leaving#
- Disconnecting a platform in Listener Networks removes that platform’s current data from the show. In the Listener creator app the data is kept and marked disconnected. In both apps, daily history for that platform is kept, and any Sync session is revoked first.
- Deleting a cluster, campaign or report deletes that document right away. Daily cluster reach entries already captured are not removed.
- Deleting a show removes the show record. Its daily history, clusters and other stored sub-records are not removed automatically today.
- Deleting an account is not self-serve yet. Email tech@listener.com to have an account and all of its data deleted.
Storage and security#
- Where data lives: Google Cloud Firestore in the
nam5location, a United States multi-region. Google encrypts Firestore data at rest by default. - API keys and OAuth tokens issued by Listener are stored only as SHA-256 hashes and compared in constant time. A leaked database copy can’t be used to call the API.
- Webhook signing secrets are encrypted with AES-256-GCM before they are stored.
- Listener Sync sessions (Spotify, Apple Podcasts, Megaphone) are encrypted with AES-256-GCM and kept apart from the show record.
- Request logs never contain request or response bodies.
Restatements, deleted posts and shared accounts#
Restatements. When a platform revises a post’s numbers, the next refresh stores the new value, with two guards:
- A metric that comes back as
0after being positive keeps its previous value, because a zero is far more often a provider hiccup than a real reset. - Views, impressions and reach on a cluster post never move down. A platform lowering one of these (for example after removing invalid traffic) is not reflected on the post. Engagement counts such as likes can move down.
Daily history is re-folded from the latest stored series, so a revised day replaces the old value there.
Deleted or private posts. When a post can no longer be fetched (deleted, made private or blocked), its last numbers stay on the cluster and the cluster records a refresh error for that post. Deleted Instagram and Facebook posts are kept as archived posts with their last known numbers. Remove a post from a cluster with POST /v1/shows/{show_id}/clusters/{cluster_id}/nodes/remove if it should no longer count.
One account on several shows. A network can link the same Instagram, TikTok, Facebook or YouTube account to several shows. By default each show counts its own accounts. With social_count_mode=unique, network totals, timelines and platform splits count each shared account once, attributed to one show (suppressed_platforms_by_show says which copies were skipped). Per-show rankings and comparisons always use each show’s own accounts. Cluster reach does not deduplicate accounts. See Metrics glossary.
Platform limits and how staleness shows up#
Platforms and data providers limit how often Listener can call them. Listener spaces its calls, retries after 429 responses using the platform’s Retry-After, waits for YouTube’s daily quota to reset when it runs out, and budgets data-provider credits. When a limit or an outage stops a refresh, the previous numbers stay and the data simply ages.
The API reports that age instead of hiding it:
freshness: for each platform,last_updated,age_hoursandstale. A platform is stale when its data is more than 36 hours old or has never been updated. For several shows, the summary reports the oldest.stale_platforms: the platforms that are stale in the result.coverage.warnings: plain-language notes when growth was left out (fewer than half the previous window’s days have data), or when a window reaches before the data Listener holds.- Cluster freshness: when each cluster was last refreshed, plus its refresh errors.
The Data freshness guide shows how to read these, and the analytics.refreshed and integration.stale events tell you when data moves or stops moving. The Listener API’s own limits are in Rate limits.