All posts
GuideJul 8, 2026 · 8 min

In-App Review Prompts: Timing, Ethics, and the StoreKit + Play APIs

How to ask for App Store and Google Play reviews the right way: StoreKit's 3-per-year limit, Play's In-App Review API, the best moment, and the no-gating rule.

RA

The Argus Team

Reply Argus

The best in-app review prompt is one the user barely notices: fired right after a genuine win, never on launch, never mid-task, never after an error — and never shown only to people you think are happy, because both Apple and Google ban that. Ask at the right moment with the native API and the store's own dialog does the rest. Ask at the wrong one and you burn one of the three chances iOS gives you for the entire year.

Most teams get this slightly wrong, and it's cheap to fix. Below: how the two native APIs behave (Apple's `SKStoreReviewController` / SwiftUI `requestReview` and Google Play's In-App Review API), where each silently ignores you, the single best moment to trigger it, and the review-gating rule that gets apps rejected. Then the part everyone forgets: a prompt gets you the review; it doesn't answer it. Getting reviews and replying to them are two jobs, and the second is where ratings actually move.

How do the native review prompt APIs actually work?

Both platforms give you one blessed way to ask, and both take the decision out of your hands on purpose. You request the prompt; the OS decides whether to show it. You never get to build your own star widget and post it to the store; that path is closed, for good reason.

On iOS, the modern entry point is the SwiftUI `requestReview` environment action (iOS 16+). Call it after something good happens:

swift
import SwiftUI
import StoreKit

struct CheckoutView: View {
    @Environment(\.requestReview) private var requestReview

    func onOrderComplete() {
        // Only after a real win — and only if your own
        // cadence check says now is a sensible time to ask.
        if ReviewCadence.shouldAsk() {
            Task { requestReview() }
        }
    }
}
SwiftUI, iOS 16+. The system still decides whether the dialog appears.

The older UIKit path is `SKStoreReviewController`, which you hand the active window scene. Same contract underneath: iOS chooses whether to surface the alert, and you get no callback telling you what happened.

swift
import StoreKit

// Older UIKit entry point (iOS 14+). Pass the active scene.
if let scene = view.window?.windowScene {
    SKStoreReviewController.requestReview(in: scene)
}
// No result, no callback. iOS decides if it shows at all.
The UIKit equivalent. Apple now steers new code toward the SwiftUI action above.

The hard constraint on iOS: the system shows the standard prompt at most three times per 365-day period, per user, and it alone decides whether any given call surfaces anything. Over budget, your `requestReview()` call is a silent no-op, with no error and no dialog. So you cannot treat the call as "a prompt appeared." It's a request, and most get declined. A testing gotcha: the alert never appears in development builds or TestFlight, only in App Store installs, so a QA pass that "never sees the prompt" is usually working exactly as designed.

Google Play's In-App Review API works the same way in spirit. You warm up a review flow, then launch it, and the card renders inside your app without kicking the user out to the Play Store:

kotlin
val manager = ReviewManagerFactory.create(context)
manager.requestReviewFlow().addOnCompleteListener { request ->
    if (request.isSuccessful) {
        manager.launchReviewFlow(activity, request.result)
            .addOnCompleteListener {
                // Flow finished. Google does NOT tell you whether
                // the card showed or the user left a review.
            }
    }
}
Google Play In-App Review API. The completion listener fires either way — success is not "they reviewed."

Play enforces a quota that Google deliberately does not publish: the docs only say the card is rate-limited per user over a window and that you shouldn't call the API more than necessary. Like Apple, the completion listener tells you nothing about whether the dialog appeared or a review was left, and the card won't reliably show in a debug build (test it through the internal testing track or internal app sharing). Design as if the prompt might never appear, because for most calls it won't.

You cannot detect the outcome — stop trying

Neither API tells you whether the user saw the prompt, tapped a star, or wrote anything. There is no callback for "they gave us 5 stars." Any logic that branches on the review result (unlocking a reward, suppressing a follow-up because "they already reviewed") is built on a signal that does not exist. Fire the request at a good moment, then forget about it.

When is the best moment to show a review prompt?

Timing is the whole game. Because iOS caps you at three prompts a year and Play throttles you invisibly, every request you spend on a bad moment is one you don't get back. The rule: ask right after the user has felt the app work for them (a task finished, a streak hit, a file exported, a level cleared) while the good feeling is fresh and the screen is calm.

Just as important is where you must not ask. Never on cold launch, before the app has done anything for them. Never in the middle of a task, where the dialog is an interruption. And never right after a crash, an error, or a failed payment: that's how you manufacture one-star reviews. Rising review volume at good moments also helps your [review velocity](/blog/review-velocity), which feeds the recency-weighted rating both stores have used since Google's I/O 2019 change to how the [star rating is calculated](/blog/how-is-your-app-star-rating-calculated).

  1. 1

    Step 1 — Wait for a genuine win

    Trigger only after a positive, completed moment: an order placed, a workout logged, a document saved, a puzzle solved. The user should feel the app just did something good for them.

  2. 2

    Step 2 — Count meaningful sessions, not installs

    Gate on real engagement: a handful of successful sessions, not day one. Someone who has used the app three good times has an opinion worth asking for; a first-launch user does not.

  3. 3

    Step 3 — Never prompt on launch, mid-task, or after an error

    Cold start, a half-finished flow, or the screen right after a crash or failed payment are the three worst moments. A prompt there converts frustration into a public rating.

  4. 4

    Step 4 — Respect the platform's throttle on top of your own

    Keep your own cadence (say, no more than once per version, well under Apple's three-a-year budget). The OS will throttle you anyway; your job is to not waste a slot before it does.

  5. 5

    Step 5 — Ask once, then let it go

    Fire the request and move on. No nagging, no re-prompt loop, no follow-up survey chasing the ones who didn't bite. The API won't even tell you who did.

Why can't you show the prompt only to happy users?

Because that's review gating, and both stores prohibit it. The old dark pattern (a custom "Are you enjoying the app?" screen that routes the yes crowd to the store and quietly diverts the no crowd to a private feedback form) is exactly what the native APIs were built to kill. Apple's guidelines require you to use the provided StoreKit API and disallow custom review prompts, which is why you can't know the rating before it's cast. Google is just as explicit in its In-App Review guidance: don't ask the user any question before or while the card is shown, don't condition the prompt on how they might rate you, and never incentivize a review.

The store hands you an unfiltered audience on purpose; you don't get to pre-screen. That feels risky until you realize the real lever isn't who you ask, it's what you do with the reviews that come back. That's the half of the loop the prompt can't touch.

Gating a survey is fine — gating the store prompt is not

You can absolutely run an in-app satisfaction survey to learn who's unhappy. What you cannot do is use that answer to decide whether to show the store's review prompt. Ask for feedback and ask for a review as two independent things, and never make one the gate for the other.

You got the review — now you have to reply to it

A prompt is only the first half of the loop. Once the review lands, replying to it is what actually moves your rating: Google reported an average 0.7-star lift when developers respond (I/O 2019), and across 4.5 million reviews, users who received a reply were roughly six times more likely to raise their rating afterward (4.4% vs 0.7%, Hassan et al.). We break down the mechanism in [does replying to app reviews raise your rating](/blog/does-replying-to-app-reviews-raise-your-rating). The prompt fills your inbox; the reply is what turns that inbox into stars.

And this is where the work quietly balloons. More prompts means more reviews: more of them critical, more in languages you don't read, split across the [App Store and Google Play, which reply differently](/blog/app-store-vs-google-play-review-replies). Google Play caps replies at 350 characters and emails yours to the reviewer; Apple publishes no official length limit (community testing suggests a few thousand characters) and notifies the user with a one-tap path to update their rating. You wanted more reviews. Now you have to answer them all, fast, before the queue lapses during a busy week.

Prompt asked me to rate right after I exported my first report — nice touch. Docs are great, only wish the export supported CSV as well as PDF.

Reply

Glad the export moment felt like the right time to ask — and thank you for the honest four stars. CSV export is genuinely on our list; I've added your note to the ticket so it carries weight. Appreciate you taking the extra minute to tell us what would make it a five.

That reply acknowledged the specific praise, treated the feature request as real, and left the door open to a rating bump without promising a date it can't keep. It's warm, factual, and 268 characters, so the same draft posts cleanly on either store. Writing one like it per review, in the reviewer's language, at volume, is the job [ReplyArgus](/features) exists to do.

Prompt with StoreKit, reply with ReplyArgus

The native APIs are the right way to ask; no tool replaces them. ReplyArgus owns the other half: it watches your Apple App Store and Google Play reviews in one inbox, drafts an on-brand reply to each one grounded in your past approved replies and store listing, in the reviewer's own language, and holds everything for approval by default (with opt-in auto-publish for the safe lane). Free covers 1 app and 100 replies a month with no card; [paid plans](/pricing) add the knowledge base, automations, and analytics from $29/mo. The prompt gets the review in the door; this keeps every one of them answered.

Frequently asked

What are the best practices for in-app review prompts?
Use the native APIs (iOS SKStoreReviewController / SwiftUI requestReview, Play's In-App Review API), trigger only after a genuine positive moment, never on launch or after an error, respect the platform limits (iOS caps prompts at three per 365 days per user; Play throttles invisibly), and never gate the prompt to only happy users, which both stores prohibit. Then reply to the reviews you get, because responding is what actually raises the rating.
How many times can you show the iOS review prompt?
iOS displays the standard SKStoreReviewController prompt at most three times per 365-day period per user, and the system alone decides whether any given request actually appears. Requests over that budget are silent no-ops. The prompt also never shows in development builds or TestFlight — only in App Store installs.
What is the quota for Google Play's In-App Review API?
Google deliberately does not publish the exact number. The docs say the review card is rate-limited per user over a window and that you should not call the API more than necessary. Like iOS, the completion listener gives you no signal about whether the card appeared or a review was submitted.
Is review gating against App Store or Google Play policy?
Yes. Routing only happy users to the store prompt while diverting unhappy ones to private feedback is prohibited on both platforms. Apple requires you to use the provided StoreKit API and disallows custom review prompts; Google forbids asking questions before or during the review card or conditioning it on the expected rating. You can run a satisfaction survey, but you can't use it to decide who sees the store prompt.
When should you trigger the in-app review prompt?
Right after a genuine win the user just completed (a task finished, a report exported, a level cleared) while the screen is calm and the good feeling is fresh. Gate it on a few meaningful successful sessions, not on install. Never prompt on cold launch, mid-task, or immediately after a crash, error, or failed payment.
Can I detect whether the user left a review?
No. Neither the iOS nor the Google Play API tells you whether the prompt was shown, what rating was given, or if any text was written. There is no callback for the outcome. Any logic that depends on knowing the result is built on a signal that does not exist. Fire the request at a good moment and move on.

Ask well and the native prompt fills your review pipeline honestly, without tricks the stores will punish. But the prompt is the easy half. The reviews it earns still need answers: the negative ones fast, the foreign-language ones faithfully, all of them before the week gets away from you. [Start free with ReplyArgus](/signup), no card, and Argus drafts your first App Store and Google Play replies in minutes, so every review your prompts bring in actually gets one.

Try it

Let Argus draft your next reply.

Watch it answer a real review in your voice. 10-day trial, no card to begin.

See the features or pricing.

Keep reading