README.md

sensortowerR

sensortowerR is an R client for Sensor Tower's API with a tidyverse-first workflow: search apps and publishers, resolve IDs, fetch sales and active-user metrics, and chain everything with dplyr/tidyr.

Installation

remotes::install_github("econosopher/SensorTowerR")

Authentication

Store your Sensor Tower API token as an environment variable:

usethis::edit_r_environ()
# SENSORTOWER_AUTH_TOKEN="YOUR_SECRET_TOKEN_HERE"

Restart your R session after updating .Renviron.

Tidyverse Quick Start

library(sensortowerR)
library(dplyr)
library(tidyr)

# 1) Find the app once, keep a canonical ID
app <- st_app_info("Royal Match") %>%
  slice(1)

app_ids <- st_app_lookup(app$unified_app_id)

# 2) Pull active users (long format, ready for tidy pipelines)
active <- st_active_users(
  os = "unified",
  app_list = app$unified_app_id,
  metrics = c("dau", "mau"),
  date_range = list(start_date = "2025-01-01", end_date = "2025-12-31"),
  countries = "US",
  granularity = "monthly"
)

# 3) Pull sales for the same window
sales <- st_batch_metrics(
  os = "unified",
  app_list = app$unified_app_id,
  metrics = c("revenue", "downloads"),
  date_range = list(start_date = "2025-01-01", end_date = "2025-12-31"),
  countries = "US",
  granularity = "monthly"
)

# 4) Join and compute KPIs
active_wide <- active %>%
  group_by(original_id, app_name, date, country, metric) %>%
  summarise(value = sum(value, na.rm = TRUE), .groups = "drop") %>%
  pivot_wider(names_from = metric, values_from = value)

sales_wide <- sales %>%
  group_by(original_id, app_name, date, country, metric) %>%
  summarise(value = sum(value, na.rm = TRUE), .groups = "drop") %>%
  pivot_wider(names_from = metric, values_from = value)

kpis <- active_wide %>%
  left_join(sales_wide, by = c("original_id", "app_name", "date", "country")) %>%
  mutate(
    rev_per_dau = if_else(!is.na(dau) & dau > 0, revenue / dau, NA_real_),
    rev_per_mau = if_else(!is.na(mau) & mau > 0, revenue / mau, NA_real_)
  )

Endpoint and ID Management

The package is designed so users can think in terms of analysis, not raw endpoints.

| If you need... | Use... | Behavior | |---|---|---| | DAU/WAU/MAU for one or many apps | st_active_users() or st_batch_metrics() | Handles active-user retrieval and returns tidy long metrics for pipelines | | Revenue/downloads for platform-specific reporting | st_sales_report() | Use os = "ios" or os = "android" | | Revenue/downloads where IDs may vary (unified, iOS, Android) | st_metrics() | Resolves IDs and fetches by the requested os | | Cross-app workflows with mixed metrics | st_batch_metrics() | Batches active users + sales and standardizes shape | | Market rankings | st_top_charts(), st_top_publishers() | Top-and-trending style analysis by region/category |

Important behavior:

App and Publisher Workflows

App-first (recommended for specific apps)

app <- st_app_info("Candy Crush Saga") %>%
  slice(1)

ids <- st_app_lookup(app$unified_app_id)

ios_sales <- st_sales_report(
  os = "ios",
  ios_app_id = ids$ios_app_id,
  countries = "US",
  start_date = "2025-01-01",
  end_date = "2025-01-31",
  date_granularity = "daily"
)

Publisher portfolio in one call

portfolio <- st_publisher_portfolio(
  publisher = "Supercell",
  metrics = c("revenue", "downloads", "mau"),
  start_date = "2023-01-01",
  countries = "WW"
)

Top charts + dashboard

top_games <- st_top_charts(
  measure = "revenue",
  os = "unified",
  category = 6014,
  regions = "US",
  time_range = "month"
)

st_gt_dashboard(top_games, title = "Top Games - US")

Core Functions

| Function | Purpose | |---|---| | st_app_info() | Search unified apps or publishers by term | | st_app_lookup() | Resolve iOS/Android/unified IDs from any input ID | | st_metrics() | Flexible single-app metric retrieval with ID resolution | | st_sales_report() | Platform-specific sales/download estimates | | st_unified_sales_report() | Unified aggregation across related regional SKUs | | st_active_users() | Tidy DAU/WAU/MAU wrapper | | st_batch_metrics() | Batch retrieval across apps and metrics | | st_publisher_portfolio() | End-to-end publisher analysis | | st_top_charts() | Top app rankings by metric | | st_top_publishers() | Publisher rankings | | st_category_rankings() | Official app store ranking pulls | | st_gt_dashboard() | Formatted dashboard-style output |

Data Notes

| Data Type | Primary Function | Time Series | Coverage | |---|---|---|---| | Revenue/downloads (platform) | st_sales_report() | Yes | Country-level | | Revenue/downloads (unified aggregation) | st_unified_sales_report() | Yes | Country-level | | Revenue/downloads (ID-flexible) | st_metrics() | Yes | Country-level | | DAU/WAU/MAU | st_active_users(), st_batch_metrics() | Yes | Country-level | | Retention and demographics snapshots | st_app_enriched() | Snapshot | Primarily US/WW depending on metric |

ID Cache Utilities

st_cache_info()
save_id_cache()
load_id_cache()
st_clear_id_cache()

Cache location is CRAN-compliant via tools::R_user_dir("sensortowerR", "cache").

Learn More

License

MIT (LICENSE file).



Try the sensortowerR package in your browser

Any scripts or data that you put into this service are public.

sensortowerR documentation built on March 18, 2026, 5:07 p.m.