# Entity Analytics Entity analytics are SDK-composed analytics for a single term, person, organization, hashtag, product, or incident. They exist because Socialhose analytics endpoints are campaign-scoped, while `/mentions/` supports `content_search` and returns an exact `count`. ## `getEntityBrief()` `getEntityBrief(term, campaignId?)` performs one mention search ordered by engagement. It returns: - exact total mention count - top mention sample - sample-derived sentiment split - sample-derived platform mix - `exact` flag indicating whether the sample covers the full population This is cheap enough for grids, tables, and autocomplete-like entity lists. ## `getEntityStats()` `getEntityStats(term, campaignId?)` expands a brief into a detail dashboard. It fetches: - engagement-ordered sample - newest mentions - sentiment facets - platform facets - cumulative date boundaries for a 14-day sparkline The first brief request is required. Subrequests are best-effort; failures return fallbacks instead of zeroing out the entity. ## Accuracy safeguards ### Sentiment reconciliation The SDK facets `/mentions/` by sentiment and accepts exact sentiment only when: ```txt positive + negative + neutral === total ``` If the sum does not match, the SDK assumes a filter was ignored or misapplied and falls back to sample-derived sentiment. ### Platform reconciliation The SDK facets `/mentions/` over known platform keys. If the platform facet sum exceeds the entity total, the SDK assumes the API ignored a filter and falls back to sample-derived platform mix. A sum below total is allowed because some mentions may be on platforms outside the SDK's known list. ### Timeline cumulative differencing The SDK avoids adjacent `[date_from, date_to]` daily windows because inclusive `date_to` can double-count boundary days. Instead it requests cumulative counts with `date_from` only: ```txt count(on/after day N) - count(on/after day N+1) = day N count ``` If the earliest cumulative count exceeds the known entity total, the SDK treats date-filtered `content_search` as untrustworthy and returns an empty sparkline rather than wrong bars. ## Rate-limit guidance A single `getEntityStats()` can perform approximately: - 1 brief request - 1 recent request - 3 sentiment facet requests - 6 platform facet requests - 15 timeline boundary requests Use caching and keep batch concurrency low. Recommended pattern: ```ts const stats = await socialhose.getEntityStats('cholera', campaignId, { revalidateSeconds: 900, }); ``` Use `getEntityBriefs()` for lists and call `getEntityStats()` only for selected detail views.