SocialCrawl

Metric substitutions and structural nulls

Where a platform's upstream cannot supply a canonical field, SocialCrawl returns an honest null or a documented substitute rather than a fabricated value. This page lists every intentional substitution and structural null by platform.

Metric substitutions and structural nulls

SocialCrawl maps 43 platforms onto one canonical schema. Not every platform exposes every canonical field. When an upstream cannot supply a field, we follow one rule: return an honest null, never a fabricated value. In a few cases a platform exposes a closely-related metric that is genuinely useful, so we substitute it into the nearest canonical slot and document the swap here.

This page is the source of truth for those cases. If a field is listed here as a structural null for a platform, its absence is by upstream design, not a bug. If it is listed as a substitution, the value is real but comes from a different upstream metric than the field name implies.

For how the derived computed block (engagement_rate, language, content_category, estimated_reach) is calculated, see Computed fields.

Metric substitutions

A substitution puts a real upstream metric into a canonical slot whose literal name differs, because it is the closest honest fit.

PlatformCanonical fieldActually holdsWhy
Spotifyauthor.posts_countMonthly listenersThe artist object has no post count. Monthly listeners is Spotify's headline reach metric, so it fills the nearest count slot. author.following, author.likes_count, and author.verified stay null for artists (not exposed).

When you read author.posts_count on a Spotify artist, treat it as monthly listeners. Every other platform's author.posts_count is a real post count.

Structural nulls by platform

These canonical fields are null across a platform's surfaces because the upstream never exposes them. They will not populate no matter how you call the endpoint.

Instagram

  • post.engagement.saves is always null. Instagram exposes only a per-viewer viewer_has_saved boolean, never an aggregate count. This is platform-private.
  • post.engagement.shares is null on the base endpoints. A reshare count is only available on post/stats and the *-full composites (instagram/profile/reels/full, instagram/profile/posts/full), which pull the mobile reshare_count. Read shares from those surfaces.

YouTube

  • post.engagement.shares and post.engagement.saves are null. Both are owner-only analytics upstream.

Reddit

  • post.engagement.views, post.engagement.shares, and post.engagement.saves are null. Reddit does not expose view or share counts, and "saved" is a per-viewer flag upstream, never a count.
  • author.verified is null (not exposed).

Facebook

  • post.engagement.saves is null (not exposed).
  • On list surfaces, list-item author.avatar_url and post.media_urls can be null because the list-item shape is slimmer than the single-object shape.

Naver's Search corpora (blog, news, cafe, book, webkr, image, kin, shop, doc, encyc) are search indexes, not social feeds, so:

  • post.engagement.views, post.engagement.likes, and post.engagement.comments are null on every Naver Search corpus. There are no engagement signals to return.
  • author.avatar_url, post.media_urls, and post.published_at vary by corpus and are null on the corpora that do not carry them (for example news and image differ from blog).

Spotify

Beyond the monthly-listeners substitution above, artist objects return null for author.following, author.likes_count, and author.verified, and album/track/podcast rows carry no post.engagement.*.

Google Finance

  • quote.price.previous_close is null when the upstream quote omits it. It is a structural null, not a fixed value. It can be derived client-side from the current price and change when you need it.

Google Shopping

  • product.brand is null. Google Shopping does not return a clean brand field. Only Amazon products carry a populated brand. If you need the brand for a Shopping product, it can often be lifted from product.specifications[].

Other platforms

  • Rumble: search (SERP) rows carry no post.engagement.*, author.avatar_url, or post.published_at.
  • Threads: slim search-user rows omit author.avatar_url, author.bio, and author.followers.
  • Twitter/X: the single-tweet shape carries no post.pinned flag; it defaults to false.
  • GitHub: author.avatar_url is null on several archetypes, and there is no like primitive so post.engagement.likes is null.
  • TikTok: root comments carry no post.parent_id by design (only replies do).
  • Google Business: business/updates rows carry no author.username.

Changed defaults

Two endpoints apply a SocialCrawl-chosen default when you omit a sort/type parameter, so results are predictable:

  • google_play/app-reviews (and app_store/app-reviews) default sort_by to newest-first when you omit it. Google Play's own upstream default is "most relevant"; we override it so an unspecified sort returns the newest reviews. The per-store value is newest for Google Play and most_recent for the App Store. Passing an explicit sort_by always wins.
  • instagram/search/hashtag defaults type to top when you omit it. Pass type=recent or type=clips to change it.
Metric substitutions and structural nulls | SocialCrawl