Getting Data Without a Developer Account

Part 3 of the "Behind the Map" series — how reviews get into the system without console access, and why a nightly run fights the stores' own forgetting

Abstract

Two barriers normally stop anyone from analysing a different app's reviews: the developer account, which only the app's owner holds — and the stores' own short memory, which lets old reviews vanish from their public feeds. This article shows how YelmeAtlas gets around both: a single input field that figures out on its own which store is meant, and a nightly archiving run that secures reviews before the store forgets them — with a clear rule for the failure case: one stuck app must never cost every other app its day of history.


1. Diagnosis: two separate barriers

Barrier 1 — the developer account is tied to ownership. Google Play Console and Apple App Store Connect both require an account bound to the specific app. Anyone analysing their own app eventually gets in. Anyone wanting to see a different app's reviews — a competitor's, a reference product's, an app they're evaluating before a purchase decision — gets no access this way at all. That's not a gap in either platform; it's the design.

Barrier 2 — the stores actively forget. Even with access to the public review endpoints: Apple's public feed shows only the most recent ~500 reviews per storefront. For a heavily-discussed app, that's measured at roughly twelve days of history — everything before that isn't "retrievable later," it's simply gone. Anyone who doesn't check regularly loses reviews irrecoverably, not just slowly.

2. Existing approaches and their limits

  • Use the official developer account. Works only for your own app — any analysis of a competitor stays impossible.
  • Export once. Solves barrier 1 for your own app, but not barrier 2: a one-time export is already stale the next day, and the twelve days run out regardless.
  • Rent a third-party tool with its own developer access. These exist (Sensor Tower and similar), often at prices that run into five figures per year for a single account — for what amounts to typing in one app ID.

3. The YelmeAtlas approach

The principle: one input field instead of two forms. The user types a single app ID — from either store — and the system figures out on its own where the request goes. Behind that, independent of any login, a nightly sweep re-queries every watched app before Apple's twelve days run out.

4. The algorithm in detail

sequenceDiagram
    participant U as User
    participant R as Store router
    participant P as Google Play
    participant A as App Store
    U->>R: "com.spotify.music" OR "id324684580"
    R->>R: All digits? (Apple's own link form "id…")
    alt purely numeric
        R->>A: Query Apple
    else reverse-domain
        R->>P: Query Google Play
    end
    Note over R: The user never has to name the store

The store router. Google Play identifies apps by a reverse-domain name (com.spotify.music); the App Store uses a purely numeric ID (324684580) — the two forms are never confusable. The router checks exactly one thing: is the input (after stripping Apple's own "id" prefix, which can be copied straight out of any App Store link) purely numeric? Then Apple. Otherwise Google Play. The user never has to name the store themselves — they just paste whatever's in the store's own address bar.

flowchart TD
    T["Timer: nightly, 04:00 ± 30 min jitter"] --> L["For each watched app"]
    L --> F{"Fetch succeeded?"}
    F -->|yes| S["Up to 1,000 reviews<br/>stored, deduplicated"]
    F -->|no, e.g. store outage| E["Error logged,<br/>ONLY this one app skipped"]
    S --> W["Next app"]
    E --> W
    W --> L

The nightly sweep. A systemd timer starts the run once a day, with a deliberate ±30-minute jitter (so not every customer hits the same store at exactly the same second) and Persistent=true (a missed run — after a server restart, say — catches up instead of simply lapsing). Every watched app is queried individually; one app's stuck store call must never cost every other app its history — a failure gets logged, and the list moves on.

The duplication that isn't one. Every review carries a unique ID assigned by the store. On save: if that ID already exists, the new record is silently discarded, never overwritten. That makes the daily run idempotent — fetching the same review twice costs nothing but a bit of network time, and never produces a duplicate row.

5. A measured example

For a heavily-discussed app, Apple's public feed shows roughly 500 reviews per storefront — measured, that's about twelve days of history. Without a run that checks more often than every twelve days, any older review simply becomes unretrievable. The daily rhythm sits deliberately well inside that window — not because daily is strictly necessary, but because the cost of a missed day (irrecoverable loss) outweighs the cost of a daily fetch (one network request).

6. Limits of the method

  • The store router works because the two ID formats never overlap — adding a third store would need the rule rethought, not just extended.
  • The nightly run collects up to 1,000 reviews per app per night — that covers normal update cycles, but isn't a substitute for a real-time stream around an extremely high-volume single event.
  • A failure is logged and skipped, not automatically retried within the same night — the next night picks it up again, as long as the app stays watched.

7. Conclusion

Two small, unremarkable decisions solve a problem that looks, at first glance, like it needs far more engineering: a simple shape check spares the user from having to know which store they're in — and a daily, fault-tolerant run keeps history from quietly disappearing while nobody's watching. Neither solution is complicated. Both rely on naming the actual problem precisely before solving it: not "how do I get more data," but "how do I not lose what I already had."

The next part puts exactly this archive to work: how a daily-growing list of reviews turns into a complaint rate — and the days that genuinely deserve a second look. → Part 4: The Complaint Rate and the Days That Stand Out (coming next)

← Part 2: Topics That Have to Earn Their Name