All articles

We mapped a major app. Here is everything it emits.

Everyone talks about what apps collect. We measure it. On a real device, in real conditions, with advanced techniques, our engine observes what an app actually transmits once running: which data leaves, and to whom. Here is an extract, on a major mainstream app, fully anonymised.

The publisher’s shared responsibility

Regulators are explicit: a publisher carries at least joint responsibility for the trackers embedded through a third-party SDK. Choosing to integrate an ad network means answering for what it collects.

In other words, the declared list is not enough. What binds the publisher is not the announced set of partners, but what the app actually transmits. That is exactly what we measure.

The traffic, observed while the app runs

In a few dozen seconds of ordinary use, on a physical device, the app contacted fifty distinct hosts and emitted over one hundred and forty requests to third parties.

These third parties fall into a few families: marketing attribution, audience measurement, ad networks and real-time bidding, diagnostics. Here are the main ones, observed being contacted during the run.

Third parties contacted during the run
Adjust            · marketing attribution
AT Internet       · audience measurement
AppNexus          · ad auctions
Smart             · advertising
Google AdMob      · advertising
Google Tag Manager· tag orchestration
Batch             · engagement and push
Google Crashlytics· diagnostics

One player dominates the traffic

Not all requests carry the same weight. In this session, a single ad network concentrates most of the calls to third parties, far ahead of the rest.

Requests to third parties, by recipient
Google AdMob43 req.
AT Internet11 req.
Batch9 req.
Amazon Advertising6 req.
Hubvisor6 req.
AppNexus3 req.

Three requests, as they leave the device

Detail is more telling than a count. Here are three requests, anonymised, chosen because they show three different mechanics: attribution, measurement and bidding.

An attribution platform receives what you look at

This request goes to a marketing attribution platform. The role of such a tool: to link an action inside the app, viewing a listing for instance, to an ad campaign. To do that, it needs to know what you do.

So the request carries more than an identifier. It describes the screen viewed in detail: the category, the sub-category, the listing identifier, and even a conversion value. Stitched together over a session, these events draw the precise interest of the device’s owner, and the price range they care about.

Event sent to an attribution platform (anonymised)
POST app.adjust.com/event
Authorization: Signature signature="Tr4wNW…[truncated]"

partner_params:
  Category_name      = « Vehicles »
  Sub_category_name  = « Motorbike gear »
  ListId             = 321…[masked]
  ConversionValue    = 380.0
  app_instance_id    = b1e0e4…[truncated]
android_id           = 3a67…[masked]
app_token            = 3ouw…[truncated]

A measurement tool stacks up identifiers

The same device is tracked by several persistent identifiers in a single audience-measurement call: the advertising identifier and three distinct visitor identifiers sit together in the same payload.

This stacking is not neutral. An advertising identifier can be reset by the user. Proprietary identifiers, on the other hand, persist and make it possible to re-link sessions even after that reset.

Event sent to an audience-measurement tool (anonymised)
POST logws1357.ati-host.net/event
User-Agent: Piano Analytics SDK 3.6.0

events[0].data:
  adv_id                = 48d49bf2-…-…e560c1
  experiment_visitor_id = f9bfeb8c…[truncated]
  secure_instance_id    = 29ee196c-…[truncated]
  rollout_visitor_id    = 61a07ac8-…[truncated]
  marketplace_brand     = [redacted]
  device                = smartphone

The device enters a real-time ad auction

When an ad slot opens, the app broadcasts its context into a programmatic auction. The principle: in a few milliseconds, buyers receive a description of the available space and bid to fill it.

That description includes the package name, the domain, the exact screen and the device characteristics. This is the context that goes up for bid, to many buyers at once.

Real-time advertising bid request (anonymised)
POST ib.adnxs.com/openrtb2/prebid

imp[0].ext.gpid = « /[redacted]/Android/Homepage/Interstitial/ »
app.name        = [redacted]
app.bundle      = [redacted]
app.domain      = [redacted]
device.ua       = « Mozilla/5.0 (Linux; Android 15) … »

See the structure, not just a list

A list of trackers tells you who is present. It does not tell you how the data moves. This graph shows the real structure of the exchanges observed on the device: what leaves the app directly, and the links between third parties, when one party’s response redirects to another or a header names the originating party.

This is where the publisher’s responsibility sits. A control does not stop at the declared partner list: it looks at what actually leaves, and to whom. A publisher who only sees a flat list misses the relays and the chains; the graph makes them visible, and marks what leaves before any consent.

One honest limit: this graph shows what is observable on the device’s network. Server-to-server exchanges, between the third parties themselves, do not appear. What it does show is measured, not declared.

Request graph of a mobile app: the app at the centre, the third-party domains it contacts all around, redirect and referer links between them, and calls emitted before consent. App name and publisher domains redacted.
Exchange graph from a real, anonymized scan. The app at the centre; around it, the third parties contacted and the relays observed between them.

How to read these signals

Taken in isolation, each field looks harmless. It is their accumulation that draws the profile. An advertising identifier, shared by several third parties, becomes a common key: it links one person’s activity across apps and across ad networks.

Behavioural data, like the category browsed or the price looked at, adds intent. Persistent identifiers add continuity over time. Real-time auctions add broadcast, to many buyers, in an instant. Together, they turn a handful of requests into a portrait.

Why this matters

None of this is theoretical. These extracts come from a real run, on a real phone. It is exactly the level of detail a regulator expects: not the declared list of partners, but what the app actually transmits, to whom, and with what.

It is exactly what Skanopy produces, automatically, from the real traffic, on any Android app. With no configuration and no access to the publisher’s source code, in a single reproducible report.

Common questions

How do you find out what data a mobile app sends?
By intercepting its exchanges while it runs, then reading the contents of the requests. You find device and advertising identifiers, journey data, sometimes location, and the parameters handed to ad networks. None of it can be read off the screen or the store listing.
How do you find out who a mobile app sends data to?
Every outbound connection names a domain, and every domain belongs to an identifiable company. The list of actual recipients almost always exceeds the one the privacy policy announces, because embedded SDKs contact their own partners without the publisher deciding request by request.