Swan SDK
Concepts

Push architecture

How a campaign reaches a device — from the dashboard, through FCM/APNs, into your app, and back as a delivery / click ACK.

A Swan push notification is a round trip: campaign → FCM/APNs → device → user tap → click ACK back to Swan. The SDK is responsible for the last two legs.

End-to-end flow

   ┌────────────────────┐
   │  Campaigns engine  │  (you author the message + audience here)
   └────────┬───────────┘


   ┌────────────────────┐
   │   Swan backend     │  resolves audience → device tokens
   │                    │
   │   POST to FCM/APNs │  one request per device
   └────────┬───────────┘

   ┌────────▼───────────┐
   │  FCM / APNs        │
   └────────┬───────────┘
            │  data-only payload

   ┌────────────────────┐
   │   Swan SDK         │  - receives payload in messaging service / delegate
   │                    │  - renders notification (basic or carousel)
   │   (your app)       │  - posts to OS notification tray
   │                    │  - on tap: routes to deep-link handler
   └────────┬───────────┘
            │  POST /events { type: "push_clicked", messageId }

   ┌────────────────────┐
   │  Swan backend      │  click ACK reconciles with delivery report
   └────────────────────┘

Why data-only payloads

The SDK uses data-only FCM payloads (no notification block), which means:

  • The OS always wakes the app to handle the message — the SDK renders the notification itself
  • Background message handlers fire reliably (including for silent: 'true' payloads where we suppress the user-visible notification entirely)
  • The SDK can render carousel templates, custom sounds, and channel-specific styling that pure notification payloads can't express

The trade-off: you must keep the SDK's messaging service registered. The Android getting-started guide covers the manifest entries.

Notification channels (Android)

The SDK declares five default channels at first init:

Channel IDImportanceUse
swan_transactionalHighOrder confirmations, OTPs
swan_alertsHighService alerts, account changes
swan_promotionalDefaultMarketing campaigns
swan_generalDefaultCatch-all
swan_notificationsDefaultLegacy / unspecified

The campaign payload picks the channel by ID. Host apps can register additional channels (e.g. one per category) via Swan.createNotificationChannel(...) — typically used for custom-sound channels, since the sound is bound to the channel at creation.

Click acknowledgement

When the user taps a notification, the SDK posts a push_clicked event back to /events with the originating messageId. The campaigns engine reconciles this with its delivery report to compute open rates, attribution, and trigger follow-on journeys (e.g. "if user clicked promo X, send promo Y after 24h").

You don't wire this up — the SDK does it automatically when the notification is tapped. You only need to handle the deep-link payload via Swan.addNotificationOpenedListener and Swan.addDeepLinkOpenedListener.

Silent push

A payload with silent: 'true' fires the background message handler without posting a user-visible notification. The SDK does not emit a delivery ACK or click ACK for silent payloads — by definition there is no user-visible interaction to report.

Use silent push for: cache invalidation, lightweight refresh nudges, or triggering an in-app action without bothering the user.

On this page