Mobile authentication
A mobile app cannot hide a key: anyone can unpack an IPA or an APK. So the Yatmo frontend key is locked to your app ids, exactly as it is locked to your domain names on the web. You register the ids once, the SDK sends them, the API refuses every other app.
Which key
You have two keys. Mobile apps use the frontend key, the one already used by the plugins and safe to embed. Keep the backend key on your servers: it is not restricted by app id, so a backend key inside an app would be a real credential leak.
Register your app ids
- Self-service accounts: sign in on yatmo.com, open License, and fill in Allowed mobile app ids with your identifiers separated by commas, for example
com.myagency.homes, com.myagency.homes.android. Up to 20 ids. - Custom and enterprise plans: send the ids to your Yatmo contact, they are set on your licence within the day.
- White-label partners: pass
allowedAppIds(comma separated) toPOST /clients/{name}andPUT /clients/{name}, see White-label.GET /clientsreturns them. OnPUT, omit the parameter to keep the current ids, send it empty to clear them.
Changes reach the API within five minutes.
What the SDK sends
Every request made by an SDK carries the licence and three mobile headers. The SDK reads the app id from the running app (Bundle.main.bundleIdentifier on iOS, context.packageName on Android); the React Native and Flutter packages take it as a configuration value.
| Name | In | Type | Description |
|---|---|---|---|
| LicenseKey required | header | string | Your frontend key. |
| X-Yatmo-App-Id required | header | string | The iOS bundle identifier or the Android application id of the running app. Compared exactly, case-insensitively, with your registered ids. |
| X-Yatmo-Platform | header | string |
ios, android, react-native or flutter. Informative only.
|
| X-Yatmo-SDK | header | string |
SDK name and version, for example yatmo-ios/1.0.0. Informative only.
|
If you call the REST API yourself from an app (the bring your own map path), send the same headers:
curl "https://be.yatmo.com/Summary?latitude=50.8520525&longitude=4.3442926&language=EN" \
-H "LicenseKey: YOUR_FRONTEND_KEY" \
-H "X-Yatmo-App-Id: com.myagency.homes" \
-H "X-Yatmo-Platform: ios"
The rules
The API applies them to the frontend key only:
| Name | In | Type | Description |
|---|---|---|---|
| App id sent, registered | 200 |
Accepted, whatever the Origin header says.
|
|
| App id sent, not registered | 403 | Refused. The message lists the registered ids so you can spot a typo or a missing debug id. | |
| No app id, browser Origin | web rules | The usual domain check of the plugins applies. | |
| No app id, no Origin | 200 or 403 | Accepted while you have no app id registered (server-side and bot traffic). Refused as soon as you register one: a key extracted from your app then no longer works outside it. | |
| Backend key | unchanged | Never checked against app ids. It stays server-side, locked by IP if you asked for it. |
applicationIdSuffix (com.myagency.homes.debug) and iOS schemes may use a different bundle id. Register every variant your team runs, otherwise the app works in production and fails on a developer’s phone with a 403.Finding your app ids
- iOS: Xcode, target, Signing & Capabilities, Bundle Identifier. Also the
CFBundleIdentifierkey inInfo.plist. - Android:
applicationIdin thedefaultConfigblock ofapp/build.gradle(.kts). Not necessarily the Kotlin package name. - React Native: the two values above in the
ios/andandroid/folders. With Expo,ios.bundleIdentifierandandroid.packageinapp.json. - Flutter: the two values above in
ios/Runnerandandroid/app. At runtimepackage_info_plusreturns them aspackageName.
Allowed characters: letters, digits, dots, underscores and hyphens, 2 to 150 characters.
Errors
| Name | In | Type | Description |
|---|---|---|---|
| 401 | unauthorized | Missing or unknown licence key. Check the key, and that the SDK configuration is not empty in the build you are running. | |
| 403 | forbidden | App id not registered, or country not included in your licence. The JSON body says which. | |
| 429 | too many requests | Free plans only: daily quota reached. |
What it protects, honestly
An app id is declared by the app, not proven by the platform: a determined attacker who decompiles your app can read the key and forge the header, exactly as a script outside a browser can forge an Origin. The restriction stops the realistic abuse (a key copied into another app, a web page or a scraper) and lets us trace and rotate a leaked key quickly, without any extra work on your side.
If your security policy requires a platform-attested proof (Apple App Attest, Google Play Integrity), talk to us: it is on the roadmap for enterprise plans and needs a small setup per app on your side.
Related: License & keys · REST API authentication · Mobile SDKs overview.