App Store / Review compliance
Review compliance
Changing your paywall without shipping a build sounds like it should be against the rules. It isn't — and this page explains why, plus what we block on your behalf and what remains yours.
Why over-the-air funnels are allowed
The guideline people worry about is 2.5.2, which forbids an app from downloading and executing code that changes what it is. What Uplift Funnel sends your app is not code.
A published flow is data. Everything it can put on screen is already compiled into your binary by the SDK; the flow only says which of those pieces to arrange, in what order, with what copy. Nothing is interpreted as a script, nothing is downloaded and run, and no screen can appear that your shipped SDK cannot already draw.
This is the same category as a remote config or a server-driven layout, both long-standing App Store practice. It is also why your funnel stays native rather than becoming a webview.
The related worry is 3.2.2, about an app changing its purpose after review. Editing onboarding copy, screen order, or which offer is highlighted does not change what your app does — and there is no mechanism here that would let it.
What we refuse to publish
Guideline 3.1.2 is the one that actually gets apps rejected: a subscription screen must disclose what is being sold, at what price, and link the Terms and Privacy Policy, with a way to restore purchases. Rejections there land on your release, not ours, so the platform will not let you deploy a paywall that would fail it.
Pressing Deploy is blocked when:
- a paywall screen is missing its Terms of Use or Privacy Policy URL;
- either URL still points at a placeholder domain. Every paywall template ships with one so that a template can never reach the App Store unedited — reviewers do follow these links;
- a plan in the picker has no price on it.
You will also see a non-blocking warning when no plan shows a billing period. That one cannot be a hard rule, because a lifetime unlock legitimately has no period — but if you are selling auto-renewing subscriptions, review expects the duration next to the price.
The Terms · Privacy · Restore row is generated for you
You do not build that caption. Give the paywall its two URLs and the row is added when the flow is served, with a working Restore action alongside them. It cannot be half-deleted or drift between screens, and if your design already places its own restore control, the generated one steps aside so you do not offer it twice.
Set the two URLs once in app settings → Legal links and every new paywall you add is prefilled with them.
Still yours before you submit
We can enforce structure, not judgement. These stay with you:
- Say what the subscription is. Title, duration, and price in the copy itself — the generated footer links the documents, it does not describe your offer.
- Let people leave. A paywall with no visible way to dismiss it is a reliable rejection, and a policy violation here too.
- Do not ask for personal data before showing value. Guideline 5.1.1(v): an onboarding that demands an account or personal details up front, for features that do not need them, gets sent back.
- Keep claims honest.Fabricated countdowns, invented social proof, or a "personalized" result that ignores the answers given are rejection material and are not allowed on the platform.
- Declare what your flow collects. See App Privacy answers.
If you are rejected anyway
Fix the copy in the editor and press Deploy — the change reaches the build already in review the next time the app is opened, with no new binary. That is usually faster than a resubmission, and it is the main reason to run your funnel through Uplift Funnel in the first place.
If a reviewer questions the over-the-air mechanism itself, the first section of this page is the answer to give them: a fixed set of capabilities compiled into the binary, arranged by data, with no downloaded executable code.