> For the complete documentation index, see [llms.txt](https://documentation.pushly.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.pushly.com/platform/app-messages.md).

# App Messages

App messages are units displayed inside of your native applications. These units are great for many use cases including:

* Special Offers
* Announcements
* Notifications Pre-Permission Prompt

## When to use App Messages

Use App Messages when you want to communicate with users while they are active in your app, including:

* Promotions and limited-time offers
* Product announcements and feature callouts
* Contextual reminders or nudges
* Education and onboarding moments

## Formats

App Message units are highly customizable and can be displayed in several different formats depending on the goal of the message.

### Banner

The Banner unit is a smaller unit that can be displayed at the top or bottom of the device's screen and includes body text and a left- or right-aligned image.

<div align="left"><figure><img src="https://810756845-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2FnVKzsTuJTjqtWFvGpmXj%2FScreenshot%202024-03-07%20at%209.52.20%20AM.png?alt=media&#x26;token=6ff7eaff-6faa-4c0c-b6ba-f8c789e97f6c" alt=""><figcaption></figcaption></figure></div>

### Modal

The Modal unit displays in middle of the device and includes a large image, header, title, and body text. Up to two buttons can be added to this unit.

<div align="left"><figure><img src="https://810756845-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2FRO4jAlmX6pww1afIcagq%2FScreenshot%202024-03-07%20at%209.34.01%20AM.png?alt=media&#x26;token=153b944f-5241-4f6e-a671-a4c5660613de" alt=""><figcaption></figcaption></figure></div>

### Full Screen

The Full Screen unit covers the device's screen and includes a large image, header, title, and body text. Up to two buttons can be added to this unit.

<div align="left"><figure><img src="https://810756845-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2FtVOKyRJtTPVWJCIcAQ54%2FScreenshot%202024-03-07%20at%209.36.52%20AM.png?alt=media&#x26;token=b939fe92-58dd-494c-b862-a2ef5a80b8da" alt=""><figcaption></figcaption></figure></div>

## Building a message

The builder is four numbered steps. You can work through them in order, and a panel beside the form — **Ready to Schedule** — tells you at any point what is still missing.

### Step 1 — Basics

Give the message a **Name**. This is internal: it identifies the message in your list and in reporting, and subscribers never see it.

Choose the **Delivery Channels** the message can be delivered to — **Native Apple**, **Native Android**, or both. A channel your domain has not integrated cannot be selected.

To start from a message you have built before, switch on **Use saved template** and pick one from **Select a template**.

### Step 2 — Message

<figure><img src="https://810756845-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2F3vXXAXiQBtdP7l3UiHTG%2FScreenshot%202026-08-27%20at%209.02.24%E2%80%AFAM.png?alt=media&amp;token=a0ee5216-2750-439d-b3e3-a88d03f6a8a0" alt=""><figcaption></figcaption></figure>

#### Style

Choose **Modal** (a centered card), **Banner** (a bar at the top or bottom of the screen) or **Fullscreen** (the whole screen). The style decides which content fields are available: a Banner has no header or title, and supports one button.

Switching style keeps your work. If you switch to Banner and back, the header and title you had written return.

#### Choosing colors

**Background** sets the message's background color, and the **Header**, **Title** and button blocks each have their own color rows. They all work the same way: click one of the swatches, type a hex value, or open the full picker with the **…** at the end of the row.

If you need a colour outside those groups — a brand color, for instance — use the spectrum at the top of the picker, or type its hex value into the field on the row.

#### Content

Each content field — **Image**, **Header**, **Title**, **Body** — is a block with its own switch. Switching a field off leaves it out of the message but **keeps what you wrote**, so you can switch it back on without retyping. Clicking a block's name toggles it too.

**Image,** **Position,** and **Fit** sit beside the thumbnail.

* Use **Contain** when the full image must always be visible.
* Use **Cover** when edge cropping is acceptable and you want a more immersive look.

See [Choosing an image that fits](#choosing-an-image-that-fits) for what shape of image each format wants.

**Header** and **Title.** Each has a text-color row in its header.

* Keep titles short so they do not wrap awkwardly on smaller phones.
* If the message is instructional, split the content between title and body for scannability.

**Body.** Formatting controls live in the block's header: bold, italic, strikethrough, numbered and bulleted lists, indent, alignment, text direction (**LTR** / **RTL**), text color, then **Emoji** and **Personalize**. Every control names itself on hover.

#### Emoji and personalization

**Emoji** and **Personalize** are available on the header, the title and the body, and behave the same way in each.

Choose **Emoji** to insert an emoji at the cursor. Choose **Personalize** to insert a macro — a placeholder replaced with each subscriber's own value when the message is delivered, so one message can greet everyone by their own city.

{% hint style="info" %}
You can also type `{{` in any of those fields to open the macro list without leaving the keyboard. If your cursor is already inside a macro, choosing a different one replaces it rather than adding a second.
{% endhint %}

The same macros are offered wherever you insert one, grouped as **Location** and **Custom**. Custom macros are the ones defined for your domain.

#### Buttons

A Modal or Fullscreen message can carry up to **two buttons**; a Banner carries one.

Choose **Add primary button** to add the message's main action. Once it exists the control becomes **Add secondary button**. Remove a button with the **×** at the end of its row.

**Button Layout** — **Horizontal** places two buttons side by side; **Vertical** stacks them.

Choose **Edit** on a button's row to set:

* **Button Text** — what the button says.
* **Action Type** — **Open URL**, **Prompt For Notification Permissions**, or **Dismiss**. Each of the two buttons must choose a different one where they overlap.
* **URL** — shown when the action is Open URL. Supports tracking macros.
* **Background** and **Text** — the button's own colors.

#### Closing the message

A **Modal** or **Fullscreen** message always offers a way out. If none of its buttons dismisses the message, a close control is drawn in the top corner for you. Give one of the buttons the **Dismiss** action and that button takes over the job, so no separate control is drawn.

On a **Fullscreen** message you can also switch on **Close Button** to show the control regardless of what the buttons do.

A **Banner** never gets a close control of its own, so give it a button with the **Dismiss** action if people should be able to close it.

Recommendations:

* Use one primary CTA when possible.
* Keep CTA text concise (2 to 4 words is a good target).
* If you include a second button, make it a clear alternative (for example, “Not now” or “Learn more”).

### Step 3 — Who Sees It

Choose the audience:

* **All App Users** — everyone using the app, whether or not they have accepted push notifications.
* **All Push Subscribers** — only app users who are subscribed to push.
* **Specific Segments** — one or more of your saved segments.

Switch on **Exclude segments** to remove members of chosen segments from whichever audience you selected.

An estimate of how many app users the audience reaches appears beside the form and updates as you change it.

### Step 4 — When and How It Behaves

This step is three settings, each shown as a sentence. Choose the chevron on any row to open its controls in place. Rows open independently, so you can have the trigger and the schedule open together while you decide how they fit.

<figure><img src="https://810756845-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2F0lDqrOMFaZ6KkL3lTA2F%2FScreenshot%202026-08-27%20at%209.03.38%E2%80%AFAM.png?alt=media&amp;token=a36370b4-06b7-4359-873f-9d682949be67" alt=""><figcaption></figcaption></figure>

#### Trigger

The trigger decides whether anyone sees the message at all, so it is worth setting deliberately.

| Option                | What it means                                                                                                                                                                               |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Immediately**       | Shows immediately, or the next time the app opens if it is currently closed.                                                                                                                |
| **On session start**  | Shows when a new session begins — when the user opens the app after being away for long enough, or after a cold start.                                                                      |
| **After time in app** | Shows once the user has spent the configured amount of time in the app. Set the amount and its unit, then choose whether it counts **This session** only or across the user's **Lifetime**. |
| **Custom trigger**    | Shows once a condition your app reports is met. Give the **Key** your app sends and the **Value** to match — for example key `app_opened`, value `5`.                                       |

A custom trigger only fires if your app reports that key. See the App Messages SDK page for your platform for how to send one.

#### On screen

| Setting                              | What it does                                                                                                     |
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| **Priority** — High, Default, Low    | Decides which message appears first when more than one is eligible at the same moment. High shows first.         |
| **Auto dismiss**                     | Off, the message stays on screen until the user dismisses it. On, set how many seconds it stays.                 |
| **Allow redisplay**                  | Off, each subscriber sees the message once. On, set how long before it may show again, in hours, days or months. |
| **Animate entry** / **Animate exit** | How the message arrives and leaves. Off, it appears and disappears without animation.                            |

Entry and exit offer the same animations named for the direction they travel: **Fade**, **Zoom In** and **Zoom Out** in both, then **Slide from Left / Right / Top / Bottom** on entry and **Slide to Left / Right / Top / Bottom** on exit.

#### Schedule

* **Strategy** — **Fixed** starts at one moment in the domain's time zone for everyone. **Subscriber Time Zone** starts at that local time for each subscriber.
* **Schedule Start** — the date and time the message becomes eligible. The time zone it is interpreted in is shown beside it. A new message defaults to starting tomorrow.
* **End Date** — off, the row reads *Runs until paused* and the message stays eligible until you pause it. Switch it on to set a date and time to stop.

## Choosing an image that fits

Each format gives your image a differently shaped frame, and the image is cropped to fill it unless you choose **Contain**. Choose a source image shaped like the frame it will sit in:

| Format          | Frame shape                                        | Recommended source | What happens to the wrong shape                            |
| --------------- | -------------------------------------------------- | ------------------ | ---------------------------------------------------------- |
| **Modal**       | Wide, with a capped height                         | 1200 × 628         | A taller image is cropped to about a square.               |
| **Full Screen** | Tall — the image takes the space the copy does not | 1080 × 1920        | A wide image is cropped in from the sides.                 |
| **Banner**      | A fixed 48 × 48 square                             | 144 × 144          | Everything is cropped to 1:1, so keep the subject centred. |

JPG and PNG are both supported. The builder states the guidance for the style you have selected underneath the image controls, so you do not have to remember which is which.

In landscape, or on a tablet, the frame is a different shape again — use the **App Message Previews** window to check before you publish.

## Knowing when a message is ready

The **Ready to Schedule** panel beside the form lists everything a message needs and marks each item as met or still needed, with a count. The bar at the end of the form says the same thing in one line, and **Schedule** stays unavailable until nothing is outstanding.

The list covers the name, at least one delivery channel, content in every field you have switched on, an audience that reaches someone, a trigger, a start date in the future, and — for each button — both its text and, where it opens a URL, its URL.

If a setting under **When and How It Behaves** is what is missing, that row opens itself and is marked, so you do not have to hunt for it.

<figure><img src="https://810756845-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2F4qTTdQXLUtiVswFp8VQ1%2FScreenshot%202026-08-27%20at%209.01.22%E2%80%AFAM.png?alt=media&amp;token=26c2f06d-979e-43be-92a1-890d31a27b2a" alt=""><figcaption></figcaption></figure>

## Previews

Previews are integrated throughout the builder so you can validate how your message will look before publishing. Use them to confirm spacing, text length, image behavior, and button visibility across different screen sizes and UI modes.

<figure><img src="https://810756845-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lry9Z27iWOZyQEGAgY7%2Fuploads%2FD1haO7iXNnYFjbzODcBD%2FScreenshot%202026-08-27%20at%209.01.40%E2%80%AFAM.png?alt=media&amp;token=e5b23899-0e9a-42e6-ba1d-72055645e6ba" alt=""><figcaption></figcaption></figure>

### Inline preview panel

The builder includes a preview panel that updates as you edit content and appearance. Use this to iterate quickly on layout and copy.

The panel carries its own controls: switch between **Android** and **iOS**, and between **Light** and **Dark**. A platform your message is not delivered to appears greyed out, with an explanation on hover — switch it on under **Delivery Channels** in Step 1 to preview it.

### App Message Previews window

For deeper validation, open the **App Message Previews** window. This window lets you preview the same message across multiple device contexts, including:

* **Device type:** Phone or Tablet
* **Platform:** Apple / iOS or Android
* **Orientation:** Portrait or Landscape
* **Theme:** Light or Dark


---

# 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, and the optional `goal` query parameter:

```
GET https://documentation.pushly.com/platform/app-messages.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
