Getting started with in-app messages and push notifications 

If a push notification is knocking on the door, then n-app is talking to someone already in the room. Here's what each one costs to set up, which to build first, and why the order matters more than you'd think.

Janelle P
Janelle P
Content Marketing Manager
purple magnet against a purple background

Most teams build these two channels in the wrong order.

Push feels like the real mobile channel, so it's the one that gets built first. It's also the one that needs a mobile developer, credentials from Apple or Google, and a permission prompt you only get to ask for once per person. In-app messaging on your website needs a block of JavaScript.

If you're starting from zero on both, the order you pick matters more than either setup does. So here's how the two channels differ, what they actually cost to stand up, and a sequence that doesn't burn your one push ask before you've earned it.

The distinction that drives everything else

A push notification reaches someone who isn't in your app. An in-app message reaches someone who is.

That's really it. Every other difference follows from that one.

Push is knocking on the door. It goes to a device, so it needs a device token and the operating system's permission to interrupt somebody's day. It shows up whether or not the person was thinking about you, which is both why it works and why it's easy to misuse.

An in-app message is talking to someone who's already in the room. It goes to a person inside your app or on your site, so it can't reach anyone who doesn't show up. It never interrupts, never needs permission, and never gets buried in a notification graveyard, because the person is already looking at the screen.

The way we'd hold it: push is how you start a conversation with someone who left. In-app is how you keep one going with someone who's here.

What each one costs to set up

Here's where the asymmetry shows up, and it's bigger than most marketers expect.

In-app on your website is about the cheapest channel you'll ever add. Enable in-app in Workspace Settings, drop our JavaScript snippet on your site, and make sure you're identifying visitors so your messages have somebody to go to. If that snippet's already there for event tracking, you're most of the way home, and the rest is a toggle.

In-app in your mobile app needs a developer to install an SDK. We've got them for iOS, Android, React Native, Expo, and Flutter. Good news, though: you can draft and build in-app messages in Customer.io before your app is wired up at all, so the marketing work and the engineering work can happen at the same time.

Push notifications are a project that requires a few more steps. Roughly in order:

  1. Install the SDK, or write your own integration.
  2. Register your app in Customer.io under Workspace Settings, with a name and its platforms.
  3. Get push credentials from your provider and upload them. That's a .p8 certificate plus App ID, App key, and Bundle ID for Apple's service, or a JSON key for Firebase Cloud Messaging. One nice shortcut: an app's iOS and Android platforms can share a single FCM credential.
  4. Have your app identify people and register device tokens. This one has a consequence worth knowing about: a device token can't be anonymous in Customer.io, so you can't push to somebody who hasn't logged in or otherwise told you who they are.
  5. Report push metrics back, so your reporting isn't guesswork. Our SDKs mostly handle this for you.
  6. Decide early if you want images, deep links into specific screens, or grouped notifications, because those need custom payloads and extra work in the app.

Step three is where timelines usually slip. Those credentials tend to live with somebody who isn't on the marketing team and has no idea why you need them, so it's a bit like needing a key from a coworker who's on vacation. Ask the week you start, not the week you planned to launch.

Why in-app is the better first move

Three reasons, roughly in order of how much they'll matter to you.

You only get to ask for push permission once. That operating system prompt is a single shot per person, and somebody who taps "don't allow" is really hard to win back. Firing it on first launch, before anyone knows what your app even does, is the most common way teams waste it. In-app is how you set that up properly: explain the value first, in context, and then trigger the prompt for the people who've already said yes to the idea.

In-app needs no consent, so you can start learning right away. You can be sending onboarding nudges and feature callouts this week while push is still sitting in the engineering queue. That's real program experience you're banking while you wait.

The data you build for in-app is the same data push needs. Segments, events, and triggers are shared across channels in Customer.io, so nothing you set up for in-app gets tossed when push finally lands. You're not doing the work twice.

There's one exception. If your product is fundamentally about things happening while people are away, like deliveries, price alerts, or scheduled reminders, then push is your core channel, and it should come first. Just be honest with yourself about which kind of product you have.

And there's a clock running either way. Roughly 56% of people uninstall an app within seven days, and once the app is gone your push channel goes with it. Our personalized mobile onboarding guide is worth a read on how the channels split the work in that first week.

How in-app delivery works

The mechanics here surprise people, and knowing them up front will save you a week of debugging.

An in-app message doesn't get pushed anywhere. It waits in a queue until the person next opens your app or site, then gets delivered. Think of it as leaving a note on the kitchen counter: it's there whenever they walk in, and it isn't going anywhere until they do.

You target by person ID or email rather than by device, and the message shows up on the first device or browser they open afterward. They won't get the same message again somewhere else, unless they re-enter the automation or you broadcast it again.

Timing depends on polling, and the rate ramps up:

Polling rate

When it applies

180 seconds

Before you've sent your first message, and after 30 days with no in-app activity

60 seconds

Got a message in the last 30 days, nothing currently queued

10 seconds

A message is actively queued

Which means your very first test can take up to three minutes to appear. That looks exactly like a broken integration, and it isn't one. Restarting the app or clearing your browser cache speeds things up. If you've ever given up on in-app after waiting 30 seconds, this is almost certainly why.

One more thing worth knowing: in-app messages don't have to be one-time popups. You can make them persistent and use them as banners or other interface elements, which is a completely different use than the interruption most people picture. And you can publish a notification inbox, so messages sit somewhere people can come back to instead of vanishing the moment they're dismissed.

What each channel is actually good for

Push works well for:

  • Time-sensitive stuff happening outside the app: a delivery arriving, a price alert, a match, a payment failing
  • Bringing lapsed users back, sparingly
  • Reminders somebody explicitly asked for, like a dose or an appointment
  • Anything where the value is in arriving now rather than arriving eventually

In-app works well for:

  • Onboarding, in context, on the actual screen where the thing you're explaining lives
  • Feature adoption, triggered by behavior that suggests somebody's ready for it
  • Surveys and feedback, right after the experience you're asking about
  • Persistent banners for maintenance windows, plan limits, or expiring trials
  • Anything that needs more room than a notification tray gives you

The line between them: push is for urgency, in-app is for context. If a message needs to interrupt somebody's day, that's push. If it only makes sense while they're looking at a particular screen, that's in-app. Getting it backwards costs you either way, since a non-urgent push teaches people to turn notifications off, and an urgent in-app message just never arrives.

If you want the wider version of this thinking across your whole channel mix, our retention channel strategy piece lands on a shortcut that's stuck with us: email for depth, SMS for urgency, in-app for relevance.

Using them together

These two are at their best in sequence, and the pattern's pretty much the same everywhere.

Push handles the return trip. In-app handles what happens on arrival.

Say somebody bails halfway through your setup flow. Push says come back and finish, which is a job in-app literally can't do, because the person isn't there. Then, when they open the app, an in-app message meets them on the exact screen where they stopped and picks the thread back up. Neither one works alone here: the push has nowhere to land, and the in-app message never fires.

Or take a feature launch. Push announces it to everyone who isn't currently in the app. In-app explains it to the people who are, or who wander in later, right where the feature lives.

Once you're comfortable with the handoff, the same pattern scales into full behavioral branching: send to one channel, then route people differently based on whether they opened it, ignored it, or converted. Our customer messaging playbook walks through a cart-abandonment version of exactly this, with the branch logic spelled out. Same idea as the setup flow above, just with more forks in it.

Because both channels run on the same profile data and the same workflows in Customer.io, coordinating them means adding a step to one automation rather than syncing two systems. Same segments, same events, same triggers.

One thing to sort out before you're sending much of either: set up a subscription center with channel-level preferences. It lets somebody opt out of push without losing everything else, which is a much better outcome for both of you than a system-level notification block you can never undo.

Getting your first message out this week

Sequenced so you're sending something in days, not weeks.

Days one and two. Enable in-app, get the JavaScript snippet on your site or the mobile SDK into your developer's queue, and confirm you're identifying users. Then add a test user. This is the step everybody skips and then regrets.

Day three. Send yourself a test from Workspace Settings > In-App Settings. Make sure you're logged in as that test user on the site or app you're testing, or you won't see it and won't be able to tell whether the problem is your setup or your session. Give it three minutes before you conclude anything's wrong, and check our troubleshooting notes if it still doesn't land.

Day four. Build one real in-app message. Pick a single moment: a first-session welcome, or a nudge on whichever screen new users most often stall out on. One message, one trigger, one clear action.

In parallel, all week. Start the push credentials conversation with whoever owns your Apple and Firebase accounts. That request has a longer lead time than anything else on this list, so it should be the first thing you kick off.

Week two onward. Once the push is live, use in-app to earn the permission before the prompt appears, then connect the two channels in a single automation.

Start with one message, not a program. You'll learn more from one in-app nudge that's actually running than from a channel strategy doc nobody's tested.

Frequently asked questions

What's the difference between an in-app message and a push notification?

A push notification reaches somebody whose app is closed, delivered by the operating system to their device. An in-app message only shows up while somebody's using your app or browsing your site. Push needs permission and a device token. In-app needs neither.

Do in-app messages require the user's permission?

Nope. Because they only appear while somebody's already in your app or on your website, they don't need the notification permission push requires. That's a big part of why they're the faster channel to get going.

Can I send in-app messages on a website, or only in a mobile app?

Both. Despite the name, in-app messages work on websites through our JavaScript snippet, and they're commonly used as banners, modals, and surveys on the web. Web setup is much lighter than mobile, which needs an SDK.

Why hasn't my in-app test message arrived?

Usually one of three things. Our SDKs poll slowly before your first message, so give it up to three minutes and try restarting the app or clearing your cache. Or you're not identified as the test user in the session where you're looking. Or in-app isn't enabled in Workspace Settings yet.

Can I send push notifications to users who haven't logged in?

No. Device tokens can't be anonymous in Customer.io, so somebody has to identify themselves before you can reach them with push. Worth knowing early, since it shapes how you think about your onboarding flow.

What do I need to send push notifications?

An SDK or custom integration in your app, your app registered in Customer.io with its platforms, and push credentials uploaded: a .p8 certificate with App ID, App key, and Bundle ID for Apple, or a JSON key for Firebase. Your app also needs to identify people and register their device tokens.

Which should I set up first?

In-app, most of the time. It's faster to launch, needs no permission, and you can use it to earn the push opt-in before you spend it. The exception is products where the core value happens while people are away, like alerts or deliveries. There, push is the primary channel and should come first.

Free 14-day trial 

  • No credit card required
  • Cancel anytime
Getting started with in-app messages and push notifications | Customer.io