Setting Up the Rating & Review SDK
What you'll learn
- Generating the Rating & Review SDK
- Configuring the five-gate prompt evaluation system at runtime
- Recording sessions and key events to drive the rating prompt
- Using the analytics-friendly decision API to track why prompts were skipped
- Understanding platform availability constraints on iOS and Android
Prerequisites
- An existing Archipelago monorepo (see Monorepo Scaffolding)
Step 1: Generate the Rating & Review SDK
The Rating & Review SDK is a Free tier brick.
archipelago generate rating_review_sdkThere are no generation variables — all configuration happens at runtime through RatingPromptConfig registered in your DI module.
Step 2: Understand the Generated Structure
The Rating & Review SDK uses the API/Impl split pattern:
features/
└── rating_review/
├── rating_review_api/ # RatingReviewSDK contract + RatingPromptConfig + decision types
└── rating_review_impl/ # Gate evaluation, persistence, and platform review request
└── lib/src/
├── rating_review_sdk_impl.dart
├── data/ # Local storage for session/event counts
├── di/ # RatingReviewImplPackageModule
└── domain/ # Gate evaluation logicFeatures that trigger the rating prompt depend only on rating_review_api.
Step 3: Configure the Prompt Gates
Override RatingPromptConfig in your app's DI module before RatingReviewImplPackageModule is registered:
// apps/my_app/lib/di/app_di_module.dart
@module
abstract class AppDIModule {
@lazySingleton
RatingPromptConfig get ratingPromptConfig => const RatingPromptConfig(
minSessions: 3, // Minimum app launches before showing the prompt
minKeyEvents: 2, // Minimum positive moments before showing the prompt
cooldownDays: 30, // Days to wait before asking again after a dismissal
askOncePerVersion: true, // Reset gates when the app version changes
iosAppStoreId: 'YOUR_APP_STORE_ID', // Required for openStoreListing() on iOS
);
}The five gates are evaluated in order on each shouldRequestReview() call:
- Platform availability —
in_app_reviewis supported on this device/OS version - Session threshold — recorded sessions ≥
minSessions - Key event threshold — recorded key events ≥
minKeyEvents - Cooldown — enough days have passed since the last prompt
- Per-version gate — not yet shown in this app version (when
askOncePerVersionis true)
All five must pass for the prompt to show.
Step 4: Record Sessions and Key Events
Call recordSession() once per app launch, early in your post-launch phase:
// apps/my_app/lib/post_launch_initializer.dart
await getIt<RatingReviewSDK>().recordSession();Call recordKeyEvent() after a meaningful positive interaction — checkout completion, a successful upload, or any moment of clear user satisfaction:
// In your order confirmation screen or usecase
await getIt<RatingReviewSDK>().recordKeyEvent('checkout_completed');
await getIt<RatingReviewSDK>().recordKeyEvent('photo_shared');Key event names are arbitrary strings; use them to distinguish event types in your analytics if needed.
Step 5: Show the Rating Prompt
Check the gates and show the prompt after a positive moment:
final ratingSDK = getIt<RatingReviewSDK>();
await ratingSDK.recordKeyEvent('subscription_activated');
if (await ratingSDK.shouldRequestReview()) {
await ratingSDK.requestReview();
}requestReview() delegates to the platform's native in-app review UI. On iOS this is SKStoreReviewController; on Android it is the Google Play In-App Review API. The OS controls whether the dialog actually appears — calling requestReview() is a hint, not a guarantee.
Step 6: Use the Decision API for Analytics
evaluatePromptDecision() returns a typed decision instead of a boolean, which lets you track skip reasons without duplicating the gate logic:
final ratingSDK = getIt<RatingReviewSDK>();
final decision = await ratingSDK.evaluatePromptDecision();
switch (decision) {
case RatingPromptDecisionShow():
await ratingSDK.requestReview();
analytics.track('rating_prompt_shown');
case RatingPromptDecisionSkip(:final reason):
analytics.track('rating_prompt_skipped', {'reason': reason.name});
// reason.name might be: 'platformUnavailable', 'sessionThreshold',
// 'keyEventThreshold', 'cooldown', or 'perVersionGate'
}This makes it straightforward to measure prompt suppression rates per gate in your analytics dashboard.
Step 7: Link to the Store Listing
After a positive review or to let users rate manually from a settings screen:
// Opens App Store (iOS) or Play Store (Android) listing
await getIt<RatingReviewSDK>().openStoreListing();On iOS, iosAppStoreId must be set in RatingPromptConfig for this to work. On Android, the Play Store app page is derived from the app's package name automatically.
Platform Notes
| Platform | Availability |
|---|---|
| iOS | Available when iosAppStoreId is set and the app is on the App Store |
| Android | Requires the app to be published (internal testing track is sufficient) |
| Debug builds | isAvailable() returns false on Android — the Play Store API requires a production or testing track build |
| iOS simulator | Review requests are silently ignored by the OS |
If isAvailable() returns false, shouldRequestReview() will also return false via the platform availability gate, so no special handling is needed in your feature code.
Common Customizations
| Goal | What to do |
|---|---|
| Lower threshold for testing | Set minSessions: 1, minKeyEvents: 1 in a debug DI override |
| Disable per-version gating | Set askOncePerVersion: false |
| Show prompt after a specific screen only | Call shouldRequestReview() in that screen's initState or onResume |
| Reset all counters | Call ratingSDK.reset() (useful for QA testing) |
| Surface the prompt after onboarding | Record a 'onboarding_completed' key event at the end of onboarding |
Next Steps
- Set up monitoring to capture exceptions if
requestReview()fails on older OS versions - Configure analytics to track
rating_prompt_skippedevents by gate reason