Insta Insight

Paused

Always-on Android tablet dashboard showing my wife's Instagram Creator account stats, wake-triggered against the Graph API with a self-refreshing token and no backend.

Started
August 7, 2026
Phases
7 of 7 done

Highlights

Overview

A single-purpose Android app for a tablet mounted where my wife can glance at her Instagram Creator account stats without opening the Instagram app and digging through its Insights UI. It wakes on a double-tap, fetches from the Instagram Graph API, and auto-rotates through a 7-page dashboard — followers, growth, the latest post, all-time totals, unseen comments, audience demographics, and history graphs — kiosk-pinned so nothing else is reachable on the tablet.

Deliberately no backend: the app talks directly to graph.instagram.com and refreshes its own long-lived token in place, so there’s no server to run or pay for, at the cost of the token and its refresh logic having to live entirely on-device.

Problem

  • A passive, always-current view, not another app to open. The point is a glance while walking past the tablet, not a session of opening Instagram and tapping into Insights.
  • No backend, but tokens expire. A ~60-day long-lived token has to refresh itself from the tablet with no server-side secret involved — driving the choice of the Instagram Login surface specifically for its secret-free ig_refresh_token grant.
  • Meta’s setup and docs don’t match reality. Getting from “create an app” to “comments actually return data” needed several undocumented or poorly-documented steps: a tester invite accepted by the account owner (not the app admin), a scope added later without which the comments edge returns an empty array with no error, and finally switching the app to Live mode before comments return anything at all. See SETUP.md in the repo for the full walkthrough.
  • Android kiosk behavior isn’t obvious either. Screen Pinning, show-when- locked, and turn-screen-on all had to be combined by trial and error to get a double-tap wake to land directly on the dashboard.

Phases

Tech stack

Languages

  • Kotlin

    App language throughout.

Frameworks

Libraries

  • Retrofit

    Typed calls to graph.instagram.com.

  • OkHttp

    HTTP client + logging interceptor under Retrofit.

  • kotlinx.serialization

    JSON models for every Graph API response.

  • DataStore

    Local caches: dashboard, follower history, unseen comments.

Tooling

  • EncryptedSharedPreferences

    Keystore-backed storage for the single long-lived access token, pinned to security-crypto 1.0.0.

  • WorkManager

    Two narrow, self-rescheduling job chains that deliberately break the wake-only rule (new-post polling, midnight snapshot).

APIs & Platforms

  • Instagram Graph API

    Instagram Login surface (graph.instagram.com), chosen for secret-free token refresh.

Approach

Every Graph API call that isn’t guaranteed to be supported gets its own try/catch rather than being trusted to succeed or batched with reliable calls — one unsupported metric silently zeroing an entire combined response was the concrete failure that drove that pattern. The wake-only refresh model (no background service) and the never-clear-a-good-cache rule both follow from the same constraint: this runs unattended on a tablet nobody is actively watching, so a transient failure should degrade gracefully rather than surface as a blank screen or a drained battery. The two background-job exceptions (see Background refresh exceptions) kept that same discipline — narrowly scoped, self-terminating, and stateless enough that neither needed its own error-recovery path beyond WorkManager’s own retry.

Future improvements

  • Proper pagination/backoff for all-time stats if the account ever grows past the current ~100-post cap fetched in one call — fine today at 13 posts, not built to scale further.

Setup and the full Meta app / API access walkthrough (tester invites, scope gotchas, the Live-mode requirement for comments, kiosk configuration) live in SETUP.md in the project repo.