The app says subscribed, the site says not
In short
Get the internal subject identifier from both surfaces before investigating anything else, because most of these reports turn out to be two separate accounts rather than one account out of sync. If the identifiers match, the remaining causes are that each surface resolves entitlement from a different authority, or that one of them is holding a decision minted before the entitlement changed.
Key takeaways
- Ask for the subject id on each surface first — 2 accounts is the most common answer by a wide margin.
- A store receipt identifies a purchase, not a person, so an in-app subscriber has no web identity until one is created.
- Institutional access matched on IP range works on the office network and fails on mobile data, which reads as an app bug.
- A token minted before an entitlement changed keeps answering the old question until it expires.
- Email is not an identifier: relay addresses and address changes break every join built on it.
Three causes produce this ticket and they are separated by one question asked at the start: what internal subject identifier does each surface think it is looking at? Either the identifiers differ, in which case there are two accounts and no synchronisation problem at all; or they match and each surface is asking a different authority about the same person; or they match, both ask the same authority, and one is holding an answer it obtained before the entitlement changed. Everything else is a variation on these three, and the first is the most common by a wide margin.
If both surfaces are wrong for the same reader, this is not the page — the grant itself probably never changed, which is renewals that never reached the access system. If the website is inconsistent with itself between requests, that is a cache-key problem traced in subscribers hitting the wall on popular stories.
Both identifiers, before any theory
- Get the internal subject id from the app. Not the email, not the store receipt — the identifier your own systems key entitlements on. Put it in a debug screen so support can read it aloud rather than guessing.
- Get the same id from the website, from an equivalent account screen or a diagnostic endpoint. If the two strings differ, stop: you have 2 accounts, and the rest of this page is irrelevant.
- Record which authority each surface consulted and when, with the instant of the answer. A surface that cannot say where its answer came from is the surface to fix first.
- Record the age of the credential on each side: when the token or session was issued, and when it expires. This one field resolves the third cause without further work.
- Ask what network the reader was on. Institutional access resolved by IP range is present on the office wifi and absent on mobile data, and the reader will describe that as the app being broken.
Two accounts wearing one reader's name
A purchase made inside an app arrives as a receipt from a store — Apple's or Google's. That receipt says a transaction happened for a subscription product on a device; it does not tell the publisher who the person is, and in most flows it never will unless the reader is asked to create or connect an account. So the app can be entirely correct that a subscription exists, and the website entirely correct that the person in front of it has none, because they are not the same record.
- One reader, two signup routes. Bought in the app on Sunday, signed up on the website with a work address on Monday, and neither knows about the other.
- One reader, two providers. Signed in with a social or platform identity on one surface and an email password on the other, producing two subjects with no link between them.
- One household, two people. The subscription is genuinely on somebody else's account, and the reader in front of you never had access to begin with.
- One reader, an old account they have forgotten. The disagreement is real and the fix is a merge, not a sync. How to connect a store purchase to a web account is its own guide — linking store purchases to the web account.
This class is worth naming in your support tooling rather than in an engineer's head. A single screen that takes an email or a receipt and shows every subject associated with it, with the source of each, turns a 2-day investigation into a 30-second answer, and it is the kind of internal surface that repays its build cost in the first month.
The same reader, asking different systems the same question
The second cause is architectural. Each surface was built at a different time by a different team against whatever access source existed then, so each resolves entitlement its own way and they agree only by coincidence.
| Surface | What it typically asks | How it goes wrong |
|---|---|---|
| Native app | The store receipt on the device, validated at launch | A receipt is per store account, and cannot see a web-side cancellation or refund |
| Website | A session flag written at login from the billing record | Never refreshed within the session, so a renewal mid-session is invisible |
| Newsletter tool | A marketing tag synced nightly | Up to 24 hours stale, and silently wrong whenever the sync fails |
| Institutional access | An IP range or an email domain match | Present on the office network, absent on mobile data and at home |
The institutional row is the one that produces the most confusing tickets, because the reader's access appears and disappears with their location and they have no reason to connect the two. If a seat, a domain match or an address range is involved, read the behaviour described in seats, domains and IP ranges for institutional access before treating it as a synchronisation defect.
There is a second trap in the website row. When the site fails to recognise a subscriber it usually does not lock them out immediately — it falls back to the meter, so they read 3 or 4 stories and only then hit a wall. That delay makes the report arrive detached from its cause, and it is why the meter's own behaviour, described in the meter resets in a private window, keeps turning up inside entitlement investigations.
Four systems each holding a defensible opinion about who is a subscriber is not a synchronisation problem. It is three systems too many.
Right answer, wrong moment: credentials that outlive the change
The third cause is timing. A token issued at login carries claims that were true when it was minted, and a native app holds that token far longer than a browser tab lives. Give it a 24-hour lifetime and a reader who upgrades at 09:00 keeps the old answer for 24 hours, while the website — which re-resolves on every request — is correct immediately. Both systems are working exactly as built.
- Keep entitlement claims out of long-lived tokens. Let the token prove identity and let the access call answer entitlement, so the two can expire on different clocks.
- If claims must be embedded, make the token short — 5 to 15 minutes, not days — and pair it with a refresh path the app actually exercises on resume, not only on cold start.
- Re-resolve on the events that matter: app foreground, purchase completion, restore, and any push telling the client something changed.
- Give support a way to force a re-resolve for one reader. Without it, every one of these tickets ends in asking somebody to reinstall the app, which works and teaches them nothing good.
One resolver, one subject, decisions that expire quickly
- Do the identifiers differ? Then it is a merge or a link, not a sync. Fix the account model and the signup flows that created the second record, or the same reader will do it again on their next device.
- Do they match but the authorities differ? Point every surface at one access resolver and delete the local interpretations. This is the only fix that stops the class of ticket rather than the instance.
- Do they match, with the same authority, but different ages of answer? Shorten the lifetime of the cached decision and add explicit re-resolution triggers. Confirm by forcing a refresh on the stale surface and watching it agree.
- Does the disagreement track the reader's network or location? Treat it as institutional access, not as a bug in the app.
- Afterwards, add the standing check that would have caught it: a synthetic reader whose entitlement is toggled on a schedule, with every surface asserting the expected answer within its stated freshness window.
The end state is unglamorous and durable: one internal subject identifier, one service that answers what this subject may read right now, and every surface calling it rather than remembering. That resolver is a small, well-bounded piece of software with a genuinely testable contract — the kind of component we build to be owned and extended by the team that inherits it, described in products built to be handed over. The rest of this silo sits under paywalls, subscriptions and entitlements, inside our media and publishing practice.
Frequently asked questions
Short answers to the follow-ups this page tends to raise.
Why does my subscription work in the app but not on the website?
Most often because the app and the website are looking at two different accounts. A subscription bought inside an app arrives as a store receipt tied to a store account, and unless that purchase was connected to a web login, the website has no record of the person in front of it. Compare the internal account identifier on both surfaces before assuming the systems are out of sync.
What should support ask for first on an access mismatch?
The internal subject identifier from both surfaces, shown in a debug or account screen. Email addresses are unreliable — relay addresses, work and personal accounts and address changes all break the join — while the subject id answers in one comparison whether this is one account or two. Add the credential's issue time as the second question.
Why does access come and go depending on where the reader is?
That pattern is institutional access resolved by network address. A seat granted to an organisation by IP range is present on the office network and absent on mobile data or at home, so the same reader is entitled in one place and anonymous in another. It is not a synchronisation failure, and the repair is to bind the entitlement to a person once they have been recognised rather than to the network alone.
How fresh does an entitlement decision need to be?
Seconds on the web and 2 minutes at most inside an app, because a reader who has just paid expects to read immediately. Long-lived tokens carrying entitlement claims are the usual cause of an app being confidently out of date; keep identity in the token and resolve entitlement separately on foreground, purchase and restore.
- entitlements
- identity
- subscriptions
- mobile apps
The work behind this page
Builds from our portfolio that this page draws on.
Read next
- Renewals that never reached the access systemCount the gap between what the provider sent and what you processed. Its size and shape separate delivery loss from processing loss, and only one of them is fixed by a better handler.diagnostic
- Dunning as a state machine: retries, grace and when access stopsDunning is not a sequence of emails. It is a state machine, and every state must be written into the entitlement record so access, messaging and reporting cannot drift.definition
- Paying subscribers are hitting the wall, and only on the popular storiesThe symptom tracks popularity because the hit ratio is the exposure: the more cacheable a story is, the more likely a subscriber gets served the anonymous copy of it.diagnostic
- The meter count: where it lives, what it counts and who can reset itA meter is not a number. It is 4 decisions — countable event, storage location, reset window and exemptions — and most implementations make only the first one consciously.definition
- The meter resets for anyone who opens a private windowA meter stored in the browser can be cleared by the browser. Measure the leak first, then decide whether identity-bound counting is worth what it costs.diagnostic
- The registration wall is not a cheap paywallA regwall trades content for a durable identity. Judged on revenue it always looks like a weak paywall; judged on known-reader coverage it is a different instrument entirely.definition
Working on something in this space?
Tell us where you are in a sentence or two. We'll tell you honestly whether we're the right team, and what a sensible first slice of the work looks like.
Start the conversation