Skip to main content
A push needs three things: a provider connected in Courier, a device token on the user, and a send. The Courier mobile SDK handles the token. Pick your platform below, work down the steps, then send a test push.

Prerequisites

  • and an
  • Provider credentials: a Firebase service account JSON for Android, an APNs .p8 key for iOS, or both
  • A physical device, since simulators and emulators do not reliably receive push

Set up your app

Pick your platform. Each tab is the complete path, from an empty project to a device that receives push.
1

Connect APNs in Courier

Open , switch to the environment you send from, and choose Apple Push Notification Service. Providers are per environment, so one connected in test does not exist in production.Fill in four fields, then click Install Provider:
  • Key Id, the identifier of your APNs key
  • Key, the contents of the downloaded .p8 file
  • Team Id, your Apple Developer team identifier
  • Topic (App Bundle Id), the bundle ID of the app you send to
Where to find each one: .
2

Install the SDK

In Xcode, go to File > Add Packages, paste the repository URL, pick a version, and add it to your target.
With CocoaPods instead, add the pod and run pod install from your ios/ directory. The SDK needs iOS 15.0 or later.
3

Enable push in Xcode

Select your target, open Signing & Capabilities, and add Push Notifications.For silent push, add Background Modes as well and check Remote notifications.Optionally add a to track delivery while the app is closed. It is three steps in Xcode, and the iOS SDK reference walks them.
4

Sync the device token

Extend CourierDelegate in your AppDelegate. The SDK registers the APNs token, refreshes it, and forwards delivery and click events.
5

Sign in the user

Courier ties every token to a signed-in user, so no push reaches the device until you call signIn. Pass the user_id you send to, plus a JWT your backend mints (see ).
The user_id is yours, not Courier’s.
Use whatever your app already calls this user, such as a database id or your auth provider’s sub. Nothing has to exist in Courier first, since signing in registers the user and their device tokens. With no auth yet, any stable string works, as long as you reuse it on every launch and send to that same id.
Call it once, right after your own login resolves. Credentials persist on the device, so app launches do not need it. Call signOut on logout to delete that device’s tokens from Courier.
6

Request notification permission

iOS shows the system dialog once. If the user denies it, they re-enable it in device Settings.
Reading the status, and getting the user back after they deny: .
Next: send a test push to the user_id you signed in.
The SDK holds a token it receives before anyone signs in and uploads it at sign-in, so you never race the callback. Signing in a different user signs the previous one out first.
To register tokens from a server or outside the SDK, use the directly. The covers the token model.

Send a test push

First with a Push channel and publish it. Then send it to the user_id you signed in, routing to the push channel. Courier resolves the user’s tokens and delivers through each connected provider.

Verify

The notification appears on the device you registered. For a silent payload, confirm your app handled it in the background instead. Open the message in . A delivered push shows the provider it went through and the token it targeted. If it did not deliver, the log names the reason: no token, expired token, or provider not configured.
channels: ["push"] picks a single push provider in failover order and stops at the first success. To reach both iOS and Android on one send, set the push channel’s routing_method to all and put both providers on that channel. See .

Delivery and click tracking

Courier tracks push delivery and clicks for you. Every push carries a trackingUrl, and the SDK posts back to it as the notification arrives and again when the user taps it. Both events land in with no code of your own. The wiring from Set up your app is what reports them: Two provider defaults keep that accurate, and a new workspace has both on. Attach Mutable Content on is what lets the extension run at all. Apply Recommended Courier Mobile SDK Formatting on ships the push as data, so Android wakes for it. shows both payloads.
If you handle notifications outside the Courier hooks, post delivery and click events yourself with client.tracking.postTrackingUrl. Each SDK page carries the call: , , , and .