> For the complete documentation index, see [llms.txt](https://docs.amply.tools/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amply.tools/user-guide/custom-popups.md).

# Custom popup flows

Amply doesn't have a native Custom Popup campaign type today — this page documents the shipped pattern: fire a DeepLink campaign to an in-app popup screen your app renders.

A custom popup is an in-app message you control — the title, the body, the buttons, and what happens on tap. Today you create custom popups by pairing a **Deep Link** campaign with a screen your app already knows how to render. The dashboard decides when to show it and to whom; the app decides how it looks.

**Use this when** you need to communicate something in your own visual language (sentiment checks, feedback prompts, in-app offers, soft push pre-prompts) at a specific moment in the user's session. **Don't use this when** you only need to route the user to an existing screen — a plain [deeplink campaign](/user-guide/managing-deeplinks.md) is simpler. Also don't use this for the native review sheet — use a [Rate & Review campaign](/user-guide/rate-review-flows.md) instead.

## Custom popup vs deeplink — quick rule

* If the outcome is "take the user to an existing screen," use a deeplink campaign with no popup.
* If the outcome is "show a message or ask a question inside the app," use a custom popup (delivered as a deeplink to a dedicated popup screen).
* If the outcome is "show the native store review sheet," use a Rate & Review campaign.

## How it works today

Your mobile team implements one reusable popup screen. That screen reads parameters from the deeplink URL — title, body, primary CTA label, secondary CTA label, variant — and renders them using your design system. You then create a Deep Link campaign whose URL points at that popup screen.

Result: the dashboard controls *when* the popup shows and *what text* it shows. The app controls how it looks and what the buttons do. Content changes do not require a release.

{% hint style="info" %}
A native "Custom Popup" campaign type is planned. Until it ships, the deeplink-to-popup-screen pattern described below is the supported approach.
{% endhint %}

## Before you start

Engineering needs to have built the popup screen once. Agree on:

* The URL shape. Example: `yourapp://popup?id=sentiment_check&title=Enjoying%20the%20app?&primary=Yes&secondary=Not%20really`.
* Which parameters are supported (title, body, primary/secondary CTA, icon, variant).
* What each CTA does. Common patterns: dismiss, track an event, fire a second deeplink, open system settings.

Document the contract somewhere the marketing team can reference without reading code. The developer-side docs for this live at [Showing custom popups](/developer-guide/showing-custom-popups.md).

## Create a popup campaign

1. Open **Campaigns** → **New campaign**. Enter a name. Choose type **Deep Link**.
2. **Who** — define the audience. Standard targeting applies: countries, app version, install date, custom properties.
3. **When** — pick the **Triggering event** and configure repeat rules and frequency limits. Custom popups are fatiguing if overused. A one-per-device limit on a 30-day window is a safe default for non-time-critical prompts.
4. **What** — build the **DeepLink** URL that encodes the popup content. For the example sentiment check:

   ```
   yourapp://popup?id=sentiment_check&title=Enjoying+the+app%3F&primary=Yes&secondary=Not+really
   ```

   Parameter values must be URL-encoded. Test long strings carefully.
5. Save as **Draft**. Verify in a staging build. Promote to **Active**.

## Content fields

The exact fields depend on what your app's popup screen supports. A typical contract:

| Field       | Purpose                                  | Notes                                                            |
| ----------- | ---------------------------------------- | ---------------------------------------------------------------- |
| `id`        | Unique identifier for the popup template | Lets the app apply variant-specific layout or tracking.          |
| `title`     | Bold top line                            | Keep under 40 characters — it wraps awkwardly on small screens.  |
| `body`      | Supporting sentence                      | Optional. Keep under 120 characters.                             |
| `primary`   | Main button label                        | Should match the intended action, not say "OK".                  |
| `secondary` | Secondary button label                   | Optional. Use for a soft dismiss ("Not now") or a counter-offer. |
| `icon`      | Icon key the app recognizes              | Optional.                                                        |
| `variant`   | Style key (info, warning, celebration)   | Optional.                                                        |

## Display rules

Every rule from the [Campaigns](/user-guide/campaigns.md) page applies. The ones that matter most for popups:

* **Repeat Rules** — show after the Nth fire of the event, not the first.
* **Frequency Limits** — cap per device over a time window. Popups that appear more than once a week feel broken.
* **Audience filters** — exclude users who already completed the goal (for example, exclude users whose custom property `invited_friends` is true from the invite popup).

## When a popup is the wrong tool

* If you need to block the user from using a feature until they act, that belongs in app-side logic, not a popup campaign.
* If you need a multi-step form, deeplink into a full screen, not a popup.
* If the message is time-critical and users must act within hours, a push notification is a better channel.

## Worked example — soft push pre-prompt

Goal: ask users whether they want notifications inside your UI before triggering the system permission dialog. If they say no, never call the system API (the system prompt can only be shown once).

* **Who**: users who have not yet been asked (custom property `push_asked` is not set).
* **When**: event `OnboardingFinished`, repeat every event, one-per-device frequency limit.
* **What**: `yourapp://popup?id=soft_push&title=Get+updates%3F&primary=Yes&secondary=Maybe+later`.

In the app, the popup screen reads `id=soft_push`. "Yes" calls the system push API; "Maybe later" sets `push_asked=true` and closes the popup.

## Worked example — feature feedback

Goal: collect a one-tap reaction after a user has interacted with a new feature twice.

* **Who**: users with custom property `feature_x_uses >= 2` and `feedback_given` not set.
* **When**: event `FeatureXClosed`.
* **What**: `yourapp://popup?id=feature_x_feedback&title=How+was+it%3F&primary=%F0%9F%94%A5&secondary=Meh`.

Tap handlers track the answer as an event and set `feedback_given=true`.

## Related

* [Managing deeplinks](/user-guide/managing-deeplinks.md) — because popups are delivered as deeplinks.
* [Campaign actions](/concepts/campaign-actions.md) — the concept page covering campaign action types.
* [Showing custom popups](/developer-guide/showing-custom-popups.md) — engineer-side integration.
* [Rate & Review flows](/user-guide/rate-review-flows.md) — combine a sentiment popup with a gated review prompt.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.amply.tools/user-guide/custom-popups.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
