Rules

Automate engagement, retention, and revenue recovery with Rules. Pick a template, set a trigger, and Apphud delivers a push and/or in-app action to the right users at the right time.

Rules automate what would otherwise be manual operator work — sending a discount push to users who churned, asking for cancellation feedback, reminding subscribers to update a failed payment, and so on. Each rule combines a trigger (when to fire) with an optional push (what to send) and an optional in-app action (a paywall or built-in screen the user sees on next app open).

Find Rules in the left sidebar under Growth tools → Rules.

The page is organized in two layers:

  • Top of the page — two pinned featured cards for high-value Apple flows: Win back refund requests (auto-respond to App Store refund requests) and Apple retention messaging (configured cancel-flow messages, coming in H2 2026). These have their own dedicated configuration and aren't built from templates.
  • Below — Created Rules and Templates tabs — where you build and manage your own rules from the template library. The rest of this page covers how those custom rules work.
Apphud - Rules list page

How Rules work

Every rule is one of four types, determined by what fires it:

TypeFires whenActivation action
Event-triggeredA matching event is recorded for a user (e.g., subscription_canceled, billing_issue, paywall_checkout_initiated).Enable
ManualYou press the Trigger now button on the rule detail page.Trigger now
Scheduled (one time)A specific date and time arrives.Enable (rule sits as upcoming until the scheduled moment)
Scheduled (repeating)Selected days of the week + a daily time. Fires at most once per day.Enable (rule sits as upcoming until the next matching day)

Each rule has up to three things attached:

  1. Push notification (Title + Text + optional Custom data payload) — sent to the user's device.
  2. In-app action (a paywall, a built-in screen, or nothing) — shown on next app open.
  3. Audience filter — limit the rule to a subset of users.

Rules list

The list page has two tabs:

  • Created Rules — your existing rules in a single sortable, filterable table.
  • Templates — the library to create new rules from.

Above the tabs, two featured system rule types are pinned. They aren't created from templates and have their own configuration:

  • Win back refund requests — auto-respond to Apple refund requests with consumption data, saving up to 70% of monthly refund losses. Paid add-on.
  • Apple retention messaging — preconfigured messages shown to subscribers about to cancel. Coming in H2 2026.

Created Rules table

ColumnNotes
NameRule name. The row opens the rule's detail page; the ✏️ icon is a quick-edit shortcut.
CategoryManual rule · Event triggered · Scheduled (one time) · Scheduled (repeating).
StatusCurrent lifecycle status — see Rule lifecycle.
Times performedHow many times the rule has fired.
Created atCreation timestamp. Table is sorted by Created at, newest first.

Filter and search controls above the table:

  • Search — substring match on rule name.
  • Category filter — All / Manual rule / Event triggered / Scheduled (one time) / Scheduled (repeating).
  • Status filter — All / New / Running / Upcoming / Draft / Completed / Disabled. Archived rules are hidden from this list.

Per-row actions:

  • ✏️ — opens the rule's detail page in edit mode.
  • 🗑️ — opens an "Are you sure you want to archive this rule?" confirmation. The rule is archived (hidden from this list, configuration preserved) — same outcome as Actions → Archive on the rule detail page.
🚧

Archive is not reversible from the UI

Once a rule is archived, there's currently no way to unarchive it back through the dashboard. The rule's configuration and run history are preserved, but it's no longer accessible from the Created Rules list. Archive deliberately — if you might want to use the rule again, Disable it instead.

Create a rule

  1. Open the Templates tab.
  2. Pick a template (see Templates below for the full list and what each one does).
  3. Click Add rule on the template card.
  4. The rule opens as a Draft on the detail page. Fill in Configuration, Push notification, In-app action.
  5. Click Save and then Enable (or Trigger now for Manual).

Templates

Pick a template from the Templates tab to pre-fill a new rule with a trigger, a default English push, and an in-app action shape. You can still rename the rule, change triggers, edit the push, and swap audience after creation.

For the full template catalogue across all three categories (Manual / Event-triggered / Scheduled), default pushes, and detailed guides for the most-used templates (Win back lost subscribers, Get cancellation insights, Reduce involuntary churn, Get customers insights), see Rule templates.

Rule detail page

A rule detail page has four tabs:

TabWhat you configure
ConfigurationRule name, audience, triggers (or schedule), timing & limits.
Push notificationPush type, custom data, per-locale Title and Text.
In-app actionWhether the rule shows a paywall, a built-in screen, or nothing.
AnalyticsKPI counters for the rule, screen performance, and feedback.

Top-right buttons: Cancel · Actions dropdown · Save (or Trigger now on Manual rules).

The Actions dropdown contents depend on the rule's status:

  • Disable — turn off a rule that's currently Enabled. Won't fire while disabled.
  • Test — fire the rule once for a specific user. See Test a rule.
  • Archive — soft-delete the rule (available for non-Draft rules).

Configuration tab

General section

  • Rule name * — required.
  • Audience — dropdown listing default audiences + custom audiences from the Audiences page. You can't create an audience from inside a rule — define it in Audiences first, then pick it here.
  • Screen expiration time (TTL) — number in hours. Default 0 = no expiration. Recommended 24. Controls how long the pending in-app screen intent stays valid: if the user doesn't open the app within the TTL, the screen won't appear on later launches.
Apphud - Rules - Event Triggered Configuration page

Triggers section (event-triggered rules)

  • Perform the rule if — pick one or more events. Each dropdown lists every event from Event Types.
  • + Add trigger — OR-logic: the rule fires if any of the configured events occurs.
  • + Add filter — adds Permission Group or Product filter on top of the trigger.

Timing & limits section (event-triggered rules)

  • When to execute actions?
    • Immediately after the event occurs (default).
    • With delay after the event occurs — reveals Set delay in seconds *. Default 60. Maximum 21 600 seconds (6 hours).
  • How many times rule can be performed?
    • Unlimited times per each user - if you'd like an offering to be shown every time, e.g. when a user cancels a paywall checkout
    • Just once per each user - if you'd like an offering to be shown only once (e.g. One-time special offers triggering FOMO)
📘

Manual and Scheduled rules don't have a Triggers and Timing sections

Manual rules fire only when you press Trigger now. Scheduled rules fire on date/time. The Triggers section is replaced with a Schedule section for scheduled rules.

Schedule section (scheduled rules)

  • Which timezone should be applied? * — radio:
    • User's device timezone — fires when local time on the user's device matches Set time.
    • App timezone (<tz>) — fires at the configured app timezone for everyone. The label shows whatever's currently set on App settings → General, e.g. App timezone (America/Denver). The app-level default is Etc/UTC until you change it.
  • Scheduled one time: Select date * + Set time * (at HH hours MM minutes, hours range 00–23).
  • Scheduled repeating: Select days of week * (multi-select from Sunday–Saturday with Reset to clear) + Set time *.
📘

Pick the timezone that fits the use case

User's device timezone is right for engagement timing — a "morning reminder" rule lands at each user's local morning. App timezone is right for operational events — a flash sale that starts at the same absolute moment for everyone.

Apphud - Scheduled rule with schedule configuration page

Push notification tab

Push notification type

  • No push / Regular (default) / Silent.
🚧

Scheduled rules must send a push

For Scheduled (one time) and Scheduled (repeating) rules, No push is disabled — the rule must send either a Regular or Silent push. Configure the message before saving.

Custom data

Optional key/value pairs merged into the push payload. The + Add key-value button appears once you fill in the first Value.

Push message

One collapsible panel per locale defined in Localization. Each panel has Title and Text fields:

  • Default locale — Title and Text are required.
  • Other locales — Title and Text are optional. If left empty, users on that device language receive the default-locale push instead.

Translate to all button allows to automatically translate to all locales defined for the app.

Apphud - Regular Push message configuration tab
📘

"Translate to all" uses AI — review the result

Translate to all uses AI to translate the default language's Title and Text into every other configured language. Apphud asks you to confirm first, because it overwrites anything you've already entered for those languages.
After it runs, review every language yourself — AI translation can miss tone, length limits, or product-specific terms, so the final push copy is your responsibility.

In-app action tab

The Presentation model radio determines what the rule shows in the app when it fires:

  • None — push only, no in-app surface.
  • Paywall model — opens a paywall you select from the Current paywall dropdown. The paywall's own Screen renders if attached; otherwise the rule only fires the SDK callback.
  • Built-in Screen — uses the screen shipped with the template (for templates that include one). Templates without a built-in screen show a "No screens found" empty state.

Some templates (e.g. Cancellation survey, Billing issue notification, etc.) lock the built-in screen — you can't switch their Presentation model. Other templates (Manual rule, Win back lost subscribers, etc.) let you pick.

Analytics tab

Four KPI cards for the rule:

  • Rule performed — how many times the rule ran.

    • Event-triggered: count of trigger fires for matching events.
    • Manual / scheduled: count of executions.
  • Push sent — pushes Apphud dispatched for this rule.

    • Doesn't increment if the rule has no push action, the user has no push token, or push was skipped.
  • Push opened — pushes opened by users.

    • Depends on the Apphud SDK reporting $push_opened. Only counts opens on app versions with that SDK behavior.
  • Push errored — pushes that failed to deliver (invalid/expired token, APNs/FCM rejection).

    For revenue impact, drill down on standard charts (MRR, conversions, etc.) using the Rule filter or segment in Reports.

Built-in Screen statistics

For rules whose in-app action shows a screen with user input, e.g. Cancellation survey, — the Analytics tab also surfaces two additional sections below the KPI row.

One block per screen attached to the rule. Each block shows:

  • The screen preview and its name / description.
  • Presentations — how many times the screen was shown to a user.
  • Total answers — how many user responses the screen collected.
Apphud - Rules: built-in screen statistics

Feedbacks

A chronological feed of individual user responses, each row showing the timestamp, the user ID, and the answer text. Click Download all in the top-right to export the full list (latest responses first).

The user ID in each row is a link to the User page — open it for context on who submitted the response.

Rule lifecycle

A rule has two independent fields. Together they describe what the rule is doing.

Status (lifecycle stage)

StatusMeaning
draftUnsaved or incomplete. Cannot fire.
newManual rule saved and ready to be fired with Trigger now.
runningEvent-triggered rule actively listening to incoming events.
upcomingScheduled rule waiting for its scheduled time.
completedScheduled one-time rule that has fired. (Scheduled repeating never reaches Completed.)

State (operational toggle)

StateMeaning
enabledDefault. The rule operates at its current status.
disabledManually turned off. Won't fire even if its status would otherwise trigger.
archivedHidden from the main list. Available for non-Draft rules.
deletedSoft-deleted.
📘

Status vs state

A Running rule is "currently listening", a Completed rule "fired its single scheduled run". Either can be Disabled (operator-paused) or Archived (out of the way). Disabling a rule doesn't complete it — only firing or completion does that.

Activation actions per type

Rule typeButtonWhat happens
ManualTrigger nowFires immediately, once. Creates a run log and sends the configured push. Doesn't change status.
Event-triggeredEnableStatus moves to running. Rule listens to incoming events.
Scheduled (one time)EnableStatus moves to upcoming. Rule fires once at perform_at.
Scheduled (repeating)EnableStatus moves to upcoming. Rule fires on each matching day at the configured time (max once per day).

Validation errors on Enable

  • Event-triggered: the rule must have at least one trigger AND at least one action (push or screen). Otherwise Apphud shows "Rule should have at least one trigger and one action".
  • Scheduled one-time: the selected date and time must be in the future. Otherwise Apphud shows "Rule perform time must be in future".

Scheduled rule behavior detail

  • Scheduled one-time: after the rule fires, status moves to completed. If you then edit perform_at (date or time), the rule re-arms and returns to upcoming.
  • Scheduled repeating: stays upcoming forever. Fires at most once per day, even if the day-of-week + time conditions would otherwise allow re-firing.

Test a rule

The Test action in the Actions dropdown fires the rule once for a specific user, bypassing the rule's audience and timing logic.

  1. Save the rule first — Test is unavailable on Drafts.
  2. Open Actions → Test.
  3. Enter the User ID in the modal.
  4. Click Test.

What the user sees:

  • If their device has a push token: the push is dispatched.
  • The in-app action (paywall or built-in screen) is presented on the next app launch. If the user is currently in the app, they won't see the screen until they reopen.

Manage rules at scale

  • Disable — keep the rule's configuration but stop it from firing.
  • Archive — hide the rule from the main list (available for non-Draft rules).
  • Edit any time — for Running rules, changes apply on the next trigger event.

FAQ

What's the difference between Disable and Archive?

  • Disable keeps the rule in the main list but prevents it from firing. The configuration is preserved. Re-enable any time.
  • Archive hides the rule from the main list and cannot be undone through the UI — use it only when you're sure you won't need the rule again. Configuration and history are preserved but no longer accessible from the dashboard.

My rule has a Push sent count but Push opened stays at 0. Is that broken?

Push opened counts depend on the Apphud SDK reporting the open event. Older SDK versions don't track this. Update the SDK in your app to start collecting opens.

Why does the built-in screen only show on Cancellation survey but not on Manual rule?

The built-in screen is shipped with specific templates that need it (cancellation feedback, refund feedback, billing issue). Templates that don't ship a screen show "No screens found" in the Built-in Screen option. Use Paywall model instead to attach a Paywall Screen.

The delay maxes out at 6 hours. How do I run a rule a day later?

For windows longer than 6 hours, use a Scheduled rule combined with a custom audience that includes users in the right state. Example: a custom user property signed_up_n_days_ago your app sets when the user matches the cohort you want to target.

Can I send a push without showing anything in-app?

Yes. On the In-app action tab, choose None as the Presentation model. The rule will dispatch the push and won't open any screen in the app.

Can I run a rule on a custom event from my app?

Yes. Any event Apphud receives — including SDK-pushed custom events (email_submitted, flow_started, etc.) and store-side events (refund_requested, subscription_expired) — is selectable in the Trigger dropdown. See Event Types for the full catalog.

How do I test Rule push notifications, or troubleshoot pushes that don't arrive?

Push delivery itself is configured outside of Rules — APNs credentials, Team ID, device-token submission, payload handling. See Push Notifications → Testing and Push Notifications → Troubleshooting for the full checklist. The push token must be visible on the User page in Apphud before a Rule can dispatch to that user.

My Rule is Performed but Push Sent is 0. Why?

A Rule can be Performed without sending a push if the matching users have no push token registered in Apphud. Performed counts trigger fires; Push Sent counts dispatches — they're different events.

Check the following:

  1. The user has a non-empty Push Token field on their User page in Apphud.
  2. The app passes the APNs device token to Apphud:
   Apphud.submitPushNotificationsToken(token: deviceToken, callback: nil)
  1. didRegisterForRemoteNotificationsWithDeviceToken is called and doesn't pass nil or an empty string.
  2. The user has allowed push notifications on the device.

Test the Rule with a sandbox user who has a valid push token before enabling for all users. For full push integration setup, see Push Notifications.

Push Sent counts up, but Push Opened stays at 0. Is something broken?

Most likely the app is receiving push notifications but not handing the payload to the Apphud SDK, so opens aren't tracked (and Rule screens won't be presented on next launch).

Check:

  1. The app calls Apphud.handlePushNotification(apsInfo: userInfo) for incoming pushes.
  2. UNUserNotificationCenterDelegate is configured correctly.
  3. The push is actually being opened by the user — not just delivered to the notification tray.

Older Apphud SDK versions may not track opens at all — update the SDK if you're on an old version. Setup details: Push Notifications.

Can a Rule work without push notifications?

Yes. A Rule fires whenever its trigger conditions match — push delivery is a separate step. In the typical flow, the push notification is how the user is brought back to the app so the Rule's in-app screen can be presented; if push isn't configured (or the user has no token), the Rule is still Performed but no push is dispatched.

To verify the full flow end-to-end, test:

  1. The trigger conditions fire (Rule Performed counter increments).
  2. The push is delivered and opened (Push Sent / Push Opened counters increment).
  3. The in-app action presents on next app launch.

What's the difference between Unlimited times and Just once per user?

Both control how often a single user can re-trigger the Rule:

  • Unlimited times per each user — the Rule fires every time the user matches the trigger condition. Example: with autorenew_disabled, a user who disables auto-renew today, re-enables it next week, and disables it again will trigger the Rule twice.
  • Just once per each user — the Rule fires only on the first match for that user. Subsequent matches are ignored.

Pick Just once for one-time interventions (welcome push, first-cancellation survey). Pick Unlimited for ongoing prompts (recurring billing-issue nudges, repeat win-back).

My Rule is firing and pushes are opened, but I'm not seeing more purchases. What's wrong?

If your Rule analytics show healthy Rule Performed / Push Sent / Push Opened counters and the in-app screen is rendering, the technical setup is working. Low conversion is usually a product / offer problem, not an integration one.

Things to try:

  • A different product or promotional offer on the in-app screen.
  • A lower price point or stronger discount.
  • A different screen layout or copy.
  • A custom background image or other visual changes.
  • Manual A/B-style testing — run two variants of the Rule with different offers, compare results.

What should I include when contacting support about a Rule?

To help us debug your Rule quickly, please send:

  1. The Rule URL (open the Rule's detail page and copy the URL).
  2. A User URL or User ID used for testing (sandbox or production — specify which).
  3. A screenshot of that user's Push Token field on their User page.
  4. Confirmation that push notifications are enabled on the device.
  5. Confirmation that the app calls Apphud.submitPushNotificationsToken(token: deviceToken, callback: nil).
  6. Confirmation that the app calls Apphud.handlePushNotification(apsInfo: userInfo) for incoming pushes.
  7. Whether the test was on a real device (Xcode or TestFlight build) or the iOS Simulator.