Overview
The Stay22 Mobile SDK turns travel intent in your app into well-timed accommodation offers.
Your users already tell your app where they're going — they book a flight, save an event, search a destination. The Stay22 Mobile SDK turns that travel intent into a new revenue stream: a single, well-timed local notification that opens a curated accommodation booking experience, with every booking attributed to you.
See it in action
One trip, start to finish. The panel on the right shows the decisions the SDK makes on the way — the part that isn't visible in an integration diagram.
A traveller searches Lisbon, 14–18 March. Your app already knows this — the signal exists whether or not anyone acts on it.
What the SDK decided
per notificationtravel_context
Destination and dates, in one call.
receivedhome_suppression
Lisbon isn't this user's home city, so the trip is real. A destination that matches home is dropped on the device.
allowedone_per_trip
Nothing pending for this trip. A new context replaces a pending one — it never stacks.
one per tripfrequency_cap
Cooldown checked. The cap holds across trips, not just within one.
under capapp_state
Foreground — hold. Never interrupt a live session.
holdingdelivery_delay
Backgrounded. Release after a delay tuned across partners, not guessed.
armedyour_controls
Title, message, badges, actions and placeholders are yours in code. Timing and caps are tuned with you per account.
yoursmeasurement
Shown → tapped → booked → paid, per trigger. Nothing to instrument.
full funnel
Illustrative walkthrough — “VOYAGO” is a placeholder for your app.
How it works
A traveler drops signals in your app — they search a destination, pick travel dates, save a place
You send those signals to the SDK — destination, dates, places, whatever you have — with a single call: Stay22.setTravelContext(...)
The SDK watches for exactly the right moment, then shows one local notification for that trip
One tap drops the traveler into a curated Stay22 booking experience for their destination and dates
Every booking is attributed to your partner ID (aid) and earns you affiliate revenue
You build and host nothing: you install the SDK, tell it about the trip, and Stay22 handles timing, relevance, and the booking experience. The SDK does call Stay22 to make that decision — see What reaches Stay22.
One notification, well timed
The SDK is deliberately conservative — a spammy notification costs you user trust, so it only shows one when it's worth showing:
- One notification per trip. Setting a new travel context replaces any pending notification; it never stacks.
- Timed for relevance. Delivery waits until the user has left your app, after a delay tuned by Stay22.
- Home suppression. If the destination looks like home, no notification is shown. The SDK compares the destination to a home city on the device and drops the trip there, without contacting Stay22 — this needs the destination as text, so a coordinates-only travel context skips it. Where a partner enables it, Stay22 also checks the distance between the destination and the user's approximate location before approving.
- Frequency capping. A cooldown prevents users from being notified too often, even across multiple trips.
- Notification copy. On Android, iOS, and Flutter you set title, message, grouping, badges, and action buttons, with
{destination}and date placeholders filled in per trip. Capacitor uses the native default copy. See Notifications & Events.
Notification timing, delays, frequency caps, and the optional distance check are managed by Stay22 per partner — you don't configure them in code. Reach out to your Stay22 account manager or support@stay22.com to tune them for your account.
Built around user consent
- App-controlled consent. The SDK starts enabled by default. With Capacitor 0.1.2, declaring the partner ID natively sends a startup request on first launch before JavaScript can disable it; the quick start shows how to initialize after opt-in instead.
- No GPS. The SDK never requests location permission and reads no device location. It acts on the travel context your app provides, plus the approximate city Stay22 derives from the request IP — see What reaches Stay22. That city is only ever used to suppress a notification, never as a destination.
- Standard notification permission. Notifications go through the OS permission prompt like any other — the SDK helps you request it and respects a denial.
- Privacy-manifest ready. The iOS SDK ships an Apple privacy manifest and has no third-party dependencies. What it declares, and what you inherit into your own store listing, is in What reaches Stay22.
What reaches Stay22
Deciding whether a notification is worth showing is split between the SDK and Stay22, so it is worth being precise about what crosses the boundary, and when.
At startup. Stay22.initialize fetches your partner settings from Stay22 and sends a load event. That request carries your partner ID (aid), an identifier Stay22 issues which the SDK stores on the device and reuses on every later launch (sid22), the OS and SDK versions, and whether a small set of travel booking apps is installed on the device. On iOS the SDK can only detect an app whose URL scheme your app lists in LSApplicationQueriesSchemes; without that entry the answer is always "not installed". As with any HTTP request Stay22 receives the originating IP address, and derives an approximate location from it — city, region, postal code, country, timezone and approximate coordinates — which is where the home city used above comes from. This happens whether or not the user ever travels.
Before a notification is scheduled. The SDK sends the travel context your app provided — destination, coordinates, check-in and check-out dates, hotel name — along with the installed-app answers from above and the same identifiers. Stay22 answers whether to schedule, and returns the booking link when it does.
After a notification is shown. The SDK reports that it was shown, and separately reports failures such as a denied notification permission. Stay22 stores that session's destination and dates alongside its frequency-capping record, so the same user is not notified again too soon. That record expires automatically: 7 days by default, configurable per partner.
Cookies. Stay22's responses set a session22 cookie carrying the same sid22 value, and the SDK stores it itself on neither platform: from 1.2.0 the iOS HTTP client is configured neither to store cookies nor to send stored ones, and the Android SDK installs no cookie handler of its own. On Android that is not the same as refusing the cookie — HttpURLConnection uses whatever process-wide cookie handler your app has installed, including one a dependency installs, so if your app has one it will keep that cookie. The SDK never reads it either way. On iOS releases before 1.2.0 the client did store it.
Store privacy declarations. The iOS SDK ships an Apple privacy manifest, and the Flutter and Capacitor plugins bundle the same one. You inherit it into your own App Store privacy disclosure. It declares Device ID, for the sid22 identifier above; product interaction; and precise and coarse location, which cover the destination coordinates your app passes and the approximate location derived from the request IP — the SDK itself reads no device location. Re-check your App Privacy answers when you adopt or upgrade the SDK, since any of these may be new for your listing. Android ships no equivalent manifest, so your Google Play Data Safety declaration is yours to complete, from what this section describes.
What the SDK does not do. It requests no location permission and reads no advertising identifier. Two destinations never leave the device at all: a trip the SDK suppresses as home, and a trip suppressed by its own cooldown.
Requirements
| Platform | Minimum version | Language | Distribution |
|---|---|---|---|
| Android | Android 7.0 (API 24) | Kotlin | Maven — com.stay22:sdk |
| iOS | iOS 15.0 | Swift 5.9+ | Swift Package Manager |
| Flutter | Flutter 3.19, Dart 3.3 | Dart | Git dependency, pinned to a release tag |
| Capacitor | Capacitor 6, iOS 15, Android 8.0 (API 26) | TypeScript | Git dependency, pinned to a release tag |
The Flutter and Capacitor plugins wrap the same two native SDKs. Flutter's version number is the native SDK it wraps. Capacitor's is the plugin's own. Both support Android and iOS; web and desktop targets are not covered.
Android and iOS ship as prebuilt binaries. Flutter and Capacitor are source packages that bundle the iOS framework and resolve the Android one from Stay22's Maven repository. All four are distributed through public GitHub repositories:
stay22-android-sdk
Android SDK on GitHub — README, releases, and integration guide.
stay22-ios-sdk
iOS SDK on GitHub — README, releases, and integration guide.
stay22-flutter-sdk
Flutter plugin on GitHub — README, releases, and a runnable example app.
stay22-capacitor-sdk
Capacitor plugin on GitHub — README, releases, and a runnable example app.
Next steps
- Quick Start — install, initialize, and send your first travel context
- Notifications & Events — customize the notification and observe the SDK's decisions
- Testing & Troubleshooting — verify your integration in minutes