Secure logins so a client cannot impersonate another user’s External ID or claim email and SMS subscriptions they do not own. Generally available on the native Android SDK 5.9.0+ and iOS SDK 5.8.0+. Not yet supported on the Web SDK or cross-platform SDKs.
Generate a JWT on your server and pass it to OneSignal.login so a client cannot impersonate another External ID. The same token can authorize adding email and SMS subscriptions and selected User REST API calls.Identity Verification is generally available on the native Android and iOS SDKs. It does not work yet on the Web SDK or on cross-platform SDKs.
React Native and Expo, Flutter, Unity, Cordova and Ionic, Capacitor, .NET MAUI
Not yet supported
Unsupported SDKs have no way to pass a JWT to login. Support for them is coming soon.Enable Identity Verification to secure:
Logging in users
Adding email subscriptions
Adding SMS subscriptions
Modifying user identities and aliases
The dashboard lets you turn on Token Identity Verification for any app, even if your app uses an SDK that cannot send a JWT. The toggle applies to the whole app, across every platform.If any client in the app uses the Web SDK or a cross-platform SDK, do not turn on the toggle. Once it is on, OneSignal rejects requests from those clients that create or update users and subscriptions. login, addEmail, and addSms fail, and new devices on those clients cannot register a push subscription.You can still generate keys and build JWT signing on your server now. Only the toggle enforces verification.
An existing OneSignal app with a configured push platform.
Every client that calls login uses a supported SDK: the native Android SDK 5.9.0+ or the native iOS SDK 5.8.0+.
A backend that authenticates your users and can sign JWTs.
Access to Settings > Keys & IDs in the OneSignal dashboard. The Identity Verification section is available for every app. You do not need to contact support.
Complete these steps in order: generate keys, create the JWT, then add it to your app. Do not turn on the Token Identity Verification toggle until your backend can mint JWTs and your app can pass them to login.Log in to your OneSignal account and go to Settings > Keys & IDs > Identity Verification.
Identity Verification configuration
Click Generate New Keys to create a new key pair.
Creating new key pair
Download the PEM file or copy the private key and store it securely. This private key is not an App API key. Use it only to sign Identity Verification JWTs.
Identity Verification key pair
Always store private keys in a secure environment, such as a key management system. Never expose private keys in client-side code, public repositories, or logs.
You now have a private key stored on your server and a public key held by OneSignal.
Authenticate the user with your own server before you sign a token. When that auth succeeds, sign an ES256 JWT with the claims below and return it to the device in your auth response. If your app has no backend, stand up a small server whose only job is to verify users and sign these tokens. Never sign JWTs on the device.
Expiration as a Unix timestamp in seconds, not milliseconds. OneSignal rejects expired tokens.
identity
Yes
Object that includes external_id. This value must match the External ID you pass to OneSignal.login().
subscriptions
No
Array of objects with type (Email or SMS) and token. Here token is the email address or E.164 phone number, not the JWT. Include this claim before you call addEmail or addSms.
Sign the JWT with the ES256 algorithm (ECDSA using P-256 and SHA-256). Other algorithms are rejected. Use a JWT library rather than assembling the token by hand.Example using jsonwebtoken. Pass the PEM private key you downloaded in the previous step:
Store the PEM private key with its line breaks intact. Many environment variable systems strip newlines, which makes ES256 signing fail. Preserve the literal \n characters, or base64-encode the key and decode it at runtime.
Log or return the string from signOneSignalJWT(), then decode it to confirm the payload. jwt.io decodes tokens in your browser, but treat a real user’s token as a secret and use a test token when pasting into third-party tools. The decoded payload must look like this:
Include email and SMS in the JWT at login when you already have those values. If they arrive later, mint a new JWT that includes the subscriptions claim and pass it to updateUserJwt before you call addEmail or addSms. See Adding subscriptions.
Call login with the External ID and the JWT. Until Token Identity Verification is enabled in the dashboard, the SDK does not send the JWT, so you can ship this app update before you turn on the toggle. After you enable the toggle, login without a valid JWT fails.
On success, OneSignal associates the device’s subscription with your External ID and the user becomes an identified user.
2
Handle JWT lifecycle events
When OneSignal rejects a JWT (for example, because it expired), the SDK fires a JWT invalidated event. Fetch a new token from your backend and pass it to updateUserJwt. Requests that need the token wait until you supply it. You can use the same endpoint to mint a token that includes email or SMS if the original login token did not.Add the listener at app startup, before you call login:
Android: add it in Application.onCreate. The listener only receives events that fire after you add it, and it is called on a background thread.
iOS: the SDK holds the listener weakly, so keep a strong reference to it. It is called on the main thread, so fetch the token asynchronously. If an event fired before you added the listener, the SDK delivers it when you add the listener.
// Called on a background thread, so a blocking network call is OK here.OneSignal.addUserJwtInvalidatedListener(event -> { String externalId = event.getExternalId(); String onesignalJWT = fetchOneSignalJwt(externalId); OneSignal.updateUserJwt(externalId, onesignalJWT);});
// Called on a background thread, so a blocking network call is OK here.OneSignal.addUserJwtInvalidatedListener { event -> val externalId = event.externalId val onesignalJWT = fetchOneSignalJwt(externalId) OneSignal.updateUserJwt(externalId, onesignalJWT)}
OneSignal.addUserJwtInvalidatedListener { event -> val externalId = event.externalId appScope.launch { val onesignalJWT = fetchOneSignalJwt(externalId) OneSignal.updateUserJwtSuspend(externalId, onesignalJWT) }}
import OneSignalFramework// The app delegate lives for the whole app session, so the SDK's weak reference stays valid.class AppDelegate: UIResponder, UIApplicationDelegate, OSUserJwtInvalidatedListener { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { OneSignal.addUserJwtInvalidatedListener(self) return true } // Called on the main thread. Fetch the token without blocking it. func onUserJwtInvalidated(event: OSUserJwtInvalidatedEvent) { let externalId = event.externalId Task { let onesignalJWT = try await fetchOneSignalJwt(externalId: externalId) OneSignal.updateUserJwt(externalId: externalId, token: onesignalJWT) } }}
@import OneSignalFramework;@interface MyListener : NSObject <OSUserJwtInvalidatedListener>@end@implementation MyListener// Called on the main thread. Fetch the token without blocking it.- (void)onUserJwtInvalidatedWithEvent:(OSUserJwtInvalidatedEvent * _Nonnull)event { NSString *externalId = event.externalId; [self fetchOneSignalJwt:externalId completion:^(NSString *onesignalJWT) { [OneSignal updateUserJwt:externalId withToken:onesignalJWT]; }];}@end// The SDK holds the listener weakly. Store it in a property that lives as long as your app.self.jwtListener = [MyListener new];[OneSignal addUserJwtInvalidatedListener:self.jwtListener];// To stop listening:[OneSignal removeUserJwtInvalidatedListener:self.jwtListener];
Replace fetchOneSignalJwt with a call to your backend. Do not sign JWTs on the device.With this listener in place, an expired token is replaced automatically and the session continues without forcing the user to log in again.
3
Enable Token Identity Verification in the dashboard
From Settings > Keys & IDs, turn on Token Identity Verification.
Enabling Token Identity Verification
Before you turn it on, confirm:
No client in this app uses the Web SDK or a cross-platform SDK. See Supported SDKs.
Most of your users are on an app version that passes a JWT to login. Older app versions still installed on devices cannot send a JWT, so their requests fail too.
Your server sends a JWT for the User REST APIs it calls.
From now on, OneSignal rejects any login or gated REST API call that does not include a valid JWT. See What changes when the toggle is on.
Login:login requires a valid JWT whose identity.external_id matches the External ID.
Logged-out devices: the SDK does not create anonymous users on OneSignal. On a new install, the device does not register a push subscription until the app calls login with a valid JWT, so it cannot receive push notifications before then. If you send push to users before they log in, plan for this before you turn on the toggle.
Logout:logout() disables the device’s push subscription. Calling login with a JWT restores it. See the FAQ.
Email and SMS:addEmail and addSms require a JWT that includes the address in its subscriptions claim. See Adding subscriptions.
REST API: the User and Subscription endpoints require Authorization: Bearer YOUR_ONESIGNAL_JWT. See REST API.
If the login JWT already includes the email or phone number in subscriptions, login associates those subscriptions with the user. You do not need a second call.If the address is not in the JWT yet, mint a new token that includes it, call updateUserJwt, then call addEmail or addSms. Do this on every platform. addEmail / addSms alone is not enough once Token Identity Verification is on.fetchOneSignalJwtWithEmail and fetchOneSignalJwtWithSms are placeholders for your own backend call that mints a JWT with the subscriptions claim.
Identity Verification JWTs are not App API keys. Other endpoints (for example Create message) still use Authorization: Key YOUR_APP_API_KEY. See Keys & IDs.When Token Identity Verification is enabled, the User and Subscription endpoints below authenticate with the identity JWT instead:
Authorization: Bearer YOUR_ONESIGNAL_JWT
Mint that JWT the same way as for SDK login. The identity.external_id in the token must match the user the request operates on.
No, but it is strongly recommended for production apps. Without it, any client that knows a user’s External ID can impersonate that user and modify their subscriptions or data.
What is the “Identity Verification for email + external_id” toggle?
Legacy Identity Verification toggle in Keys & IDs
That toggle is a separate, legacy setting for OneSignal SDK v3/v4. It is not the JWT-based Identity Verification on this page and does not protect apps on SDK v5. For SDK v5, use Generate New Keys in the Identity Verification section under Settings > Keys & IDs. See Generate keys.
The native Android SDK 5.9.0+ and the native iOS SDK 5.8.0+. The Web SDK and cross-platform SDKs (React Native, Expo, Flutter, Unity, Cordova, Ionic, Capacitor, and .NET MAUI) are not supported yet. See Supported SDKs.
My app uses the Web SDK or a cross-platform SDK. Can I turn on Identity Verification?
Not yet. The dashboard lets you turn on the toggle, but your clients cannot send a JWT, so their logins and subscription updates fail. You can generate keys and build JWT signing on your server now, then turn on the toggle once your SDK is supported.
The SDK fires a JWT invalidation event. Implement addUserJwtInvalidatedListener (see Add the JWT to your app) to fetch a new token and pass it to updateUserJwt.
Only after you enable Token Identity Verification. Then the User and Subscription endpoints require Authorization: Bearer YOUR_ONESIGNAL_JWT. They do not accept the App API key for those calls. Create message and other non-user endpoints still use Authorization: Key YOUR_APP_API_KEY.
When Identity Verification is enabled, logout() disables the push subscription. The subscription stays associated with that user. Calling login with a JWT restores the previous subscription status. You do not need to call optIn() again.On Android (Kotlin), logoutSuspend() is the non-blocking equivalent of logout().
External ID, anonymous vs identified Users, and login/logout.
Keys & IDs
App ID, App API keys, and where Identity Verification keys live.
Mobile SDK reference
login, logout, addEmail, addSms, and subscription methods.
REST API overview
Default App API key authentication for endpoints that are not JWT-gated.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"OneSignal","description":"OneSignal is a platform for sending push notifications, emails, in-app messages, and SMS campaigns via a single API, Journey Builder, and a dashboard.","colors":{"primary":"#3A3DB3","light":"#E54B4D","dark":"#3A3DB3"},"logo":{"light":"https://mintcdn.com/onesignal/yJcueeDCO7UpHnnY/logo/OneSignal-Logo.svg?fit=max\u0026auto=format\u0026n=yJcueeDCO7UpHnnY\u0026q=85\u0026s=1fcfb6fef6d820fd9d99c74850711107","dark":"https://mintcdn.com/onesignal/s4WC_KzLxf8ornqq/logo/OneSignal-Logo-White.svg?fit=max\u0026auto=format\u0026n=s4WC_KzLxf8ornqq\u0026q=85\u0026s=2573a53b5aea961e18c82b3af8f31925"},"favicon":"https://mintcdn.com/onesignal/SGduBFHpiRdg5l6h/favicon.ico?fit=max\u0026auto=format\u0026n=SGduBFHpiRdg5l6h\u0026q=85\u0026s=c0a99fadc0553c658a83741c5611cef4","api":{"examples":{"languages":["curl","typescript","python","php","go","ruby","java","csharp","rust"],"autogenerate":true}},"navbar":{"links":[{"href":"mailto:support@onesignal.com","label":"Support"}],"primary":{"type":"button","label":"Dashboard","href":"https://dashboard.onesignal.com"}},"footer":{"socials":{"github":"https://github.com/OneSignal","linkedin":"https://linkedin.com/company/onesignal","youtube":"https://www.youtube.com/@onesignalofficial/playlists"}},"seo":{"metatags":{"apple-mobile-web-app-title":"OneSignal Docs"}},"fonts":{"family":"Nunito Sans"},"styling":{"eyebrows":"breadcrumbs","latex":true},"integrations":{"ga4":{"measurementId":"G-2DGWL0VYP5"},"posthog":{"apiKey":"phc_vZpvE0f5eyzcOt30FHer34yddVmNdo9kmlMVRBzLMtn","apiHost":"https://eu.i.posthog.com","sessionRecording":true}},"contextual":{"options":["copy","view","chatgpt","claude"],"display":"header"},"navigation":{"languages":[{"language":"en","href":"docs/en/home"},{"language":"cn","href":"docs/cn/home"},{"language":"ko","href":"docs/ko/home"},{"language":"ja","href":"docs/ja/home"},{"language":"tr","href":"docs/tr/home"},{"language":"pt-BR","href":"docs/pt-BR/home"},{"language":"es","href":"docs/es/home"},{"language":"fr","href":"docs/fr/home"}]}},"deployment":{"deploymentMetadataValue":{"subdomain":"onesignal","hasAudioNarration":false,"actualSubdomain":"onesignal","customDomains":["documentation.onesignal.com"],"gitSource":{"type":"github","owner":"onesignal","repo":"mintlify-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6adfd7d4d2d129649ad8c836","collectionId":"0dcb1f09-c967-4fa3-8090-922799a1ce83","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6adfd7d4d2d129649ad8c836"},"feedback":{"thumbs":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6adfd85ac4d90543576ae0f0","clientVersion":"0.0.3971","searchFilterCounts":[{"language":"en","tag":"User Guides","count":201},{"language":"es","tag":"Guías del Usuario","count":178},{"language":"fr","tag":"Guides utilisateur","count":178},{"language":"ja","tag":"ユーザーガイド","count":178},{"language":"ko","tag":"사용자 가이드","count":178},{"language":"pt-BR","tag":"Guia do Usuário","count":178},{"language":"tr","tag":"Kullanıcı Kılavuzları","count":178},{"language":"cn","tag":"用户指南","count":176},{"language":"en","tag":"Message channels","count":90},{"language":"es","tag":"Canales de mensajería","count":84},{"language":"fr","tag":"Canaux de messagerie","count":84},{"language":"ja","tag":"メッセージングチャネル","count":84},{"language":"ko","tag":"메시지 채널","count":84},{"language":"pt-BR","tag":"Canais de mensagem","count":84},{"language":"tr","tag":"Mesaj kanalları","count":84},{"language":"cn","tag":"消息渠道","count":83},{"language":"default","tag":"API Reference","count":68},{"language":"default","tag":"API reference","count":64},{"language":"en","tag":"Analytics \u0026 Integrations","count":53},{"language":"es","tag":"Analítica \u0026 Integraciones","count":52},{"language":"fr","tag":"Analyses et intégrations","count":52},{"language":"ja","tag":"分析 \u0026 統合","count":52},{"language":"ko","tag":"분석 \u0026 통합","count":52},{"language":"pt-BR","tag":"Análises \u0026 Integrações","count":52},{"language":"tr","tag":"Analitik ve Entegrasyonlar","count":52},{"language":"cn","tag":"分析和集成","count":51},{"language":"cn","tag":"开发者指南","count":48},{"language":"es","tag":"Guías del desarrollador","count":48},{"language":"fr","tag":"Guides développeur","count":48},{"language":"ja","tag":"開発者ガイド","count":48},{"language":"ko","tag":"개발자 가이드","count":48},{"language":"tr","tag":"Geliştirici Kılavuzları","count":48},{"language":"pt-BR","tag":"Guia de desenvolvedor","count":47},{"language":"en","tag":"Developer Guides","count":46},{"language":"en","tag":"Integrations","count":37},{"language":"es","tag":"Integraciones","count":37},{"language":"fr","tag":"Intégrations","count":37},{"language":"ja","tag":"統合","count":37},{"language":"ko","tag":"통합","count":37},{"language":"pt-BR","tag":"Integrações","count":37},{"language":"tr","tag":"Entegrasyonlar","count":37},{"language":"cn","tag":"集成","count":36},{"language":"en","tag":"Tutorials","count":35},{"language":"cn","tag":"推送通知","count":31},{"language":"cn","tag":"OneSignal 作为目的地","count":31},{"language":"en","tag":"Push","count":31},{"language":"en","tag":"OneSignal as destination","count":31},{"language":"es","tag":"Push notificaciones","count":31},{"language":"es","tag":"OneSignal como destino","count":31},{"language":"fr","tag":"Push","count":31},{"language":"fr","tag":"OneSignal comme destination","count":31},{"language":"ja","tag":"プッシュ通知","count":31},{"language":"ja","tag":"OneSignal as 宛先","count":31},{"language":"ko","tag":"푸시","count":31},{"language":"ko","tag":"OneSignal을 데이터 목적지로 사용","count":31},{"language":"pt-BR","tag":"Push notificações","count":31},{"language":"pt-BR","tag":"OneSignal como destino","count":31},{"language":"tr","tag":"Anlık bildirimler","count":31},{"language":"tr","tag":"OneSignal hedef","count":31},{"language":"cn","tag":"移动SDK","count":25},{"language":"en","tag":"Mobile SDKs","count":25},{"language":"es","tag":"SDKs móviles","count":25},{"language":"fr","tag":"SDK mobiles","count":25},{"language":"ja","tag":"モバイルSDK","count":25},{"language":"ko","tag":"모바일 SDKs","count":25},{"language":"pt-BR","tag":"SDKs móveis","count":25},{"language":"tr","tag":"Mobil SDK'lar","count":25},{"language":"cn","tag":"教程","count":24},{"language":"es","tag":"Tutoriales","count":24},{"language":"fr","tag":"Tutoriels","count":24},{"language":"ja","tag":"チュートリアル","count":24},{"language":"ko","tag":"튜토리얼","count":24},{"language":"pt-BR","tag":"Tutoriais","count":24},{"language":"tr","tag":"Eğitimler","count":24},{"language":"en","tag":"Email","count":19},{"language":"cn","tag":"移动SDK设置","count":18},{"language":"es","tag":"Configuración del SDK móvil","count":18},{"language":"fr","tag":"Configuration SDK mobile","count":18},{"language":"ja","tag":"モバイルSDKセットアップ","count":18},{"language":"ko","tag":"모바일 SDK 설정","count":18},{"language":"pt-BR","tag":"Configuração do SDK móvel","count":18},{"language":"tr","tag":"Mobil SDK kurulumu","count":18},{"language":"default","tag":"Messages","count":9},{"language":"default","tag":"Users","count":9},{"language":"default","tag":"Organization","count":9},{"language":"default","tag":"Journeys","count":8},{"language":"default","tag":"Deprecated","count":6},{"language":"default","tag":"Templates","count":6},{"language":"default","tag":"Subscriptions","count":6},{"language":"default","tag":"Segments","count":5}]},"assistantConfig":{"enableStarterQuestions":false,"deflection":{"enabled":true,"email":"support@onesignal.com","showHelpButton":true}},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":true},"customCss":[],"page":{"pagePath":"docs/en/identity-verification","slug":"/docs/en/identity-verification","pageMetadata":{"title":"Identity verification","description":"Secure logins so a client cannot impersonate another user's External ID or claim email and SMS subscriptions they do not own. Generally available on the native Android SDK 5.9.0+ and iOS SDK 5.8.0+. Not yet supported on the Web SDK or cross-platform SDKs.","keywords":["identity verification","JWT","External ID","login JWT","updateUserJwt","user impersonation","ES256","Token Identity Verification","Android SDK 5.9.0","iOS SDK 5.8.0"],"href":"/docs/en/identity-verification"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Secure logins so a client cannot impersonate another user’s External ID or claim email and SMS subscriptions they do not own. Generally available on the native Android SDK 5.9.0+ and iOS SDK 5.8.0+. Not yet supported on the Web SDK or cross-platform SDKs.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,hr:`hr`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{Card,CodeBlock,CodeGroup,Columns,Frame,Heading,OptimizedImage,Step,Steps,Tab,Table,Tabs,Warning}=_components;if(!Card)_missingMdxReference(`Card`,true);if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!CodeGroup)_missingMdxReference(`CodeGroup`,true);if(!Columns)_missingMdxReference(`Columns`,true);if(!Frame)_missingMdxReference(`Frame`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);if(!Tab)_missingMdxReference(`Tab`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tabs)_missingMdxReference(`Tabs`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Generate a `,_jsx(_components.a,{href:`https://jwt.io/introduction`,children:`JWT`}),` on your server and pass it to `,_jsx(_components.code,{children:`OneSignal.login`}),` so a client cannot impersonate another External ID. The same token can authorize adding email and SMS subscriptions and selected User REST API calls.`]}),`\n`,_jsx(_components.p,{children:`Identity Verification is generally available on the native Android and iOS SDKs. It does not work yet on the Web SDK or on cross-platform SDKs.`}),`\n`,_jsx(Heading,{level:`2`,id:`supported-sdks`,children:`Supported SDKs`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`SDK`}),_jsx(_components.th,{children:`Identity Verification`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Android (native)`}),_jsxs(_components.td,{children:[`Supported in `,_jsx(_components.a,{href:`https://github.com/OneSignal/OneSignal-Android-SDK/releases`,children:`5.9.0+`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`iOS (native)`}),_jsxs(_components.td,{children:[`Supported in `,_jsx(_components.a,{href:`https://github.com/OneSignal/OneSignal-iOS-SDK/releases`,children:`5.8.0+`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Web`}),_jsx(_components.td,{children:`Not yet supported`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`React Native and Expo, Flutter, Unity, Cordova and Ionic, Capacitor, .NET MAUI`}),_jsx(_components.td,{children:`Not yet supported`})]})]})]}),`\n`,_jsxs(_components.p,{children:[`Unsupported SDKs have no way to pass a JWT to `,_jsx(_components.code,{children:`login`}),`. Support for them is coming soon.`]}),`\n`,_jsx(_components.p,{children:`Enable Identity Verification to secure:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Logging in users`}),`\n`,_jsx(_components.li,{children:`Adding email subscriptions`}),`\n`,_jsx(_components.li,{children:`Adding SMS subscriptions`}),`\n`,_jsx(_components.li,{children:`Modifying user identities and aliases`}),`\n`]}),`\n`,_jsxs(Warning,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`The dashboard lets you turn on Token Identity Verification for any app, even if your app uses an SDK that cannot send a JWT.`}),` The toggle applies to the whole app, across every platform.`]}),_jsxs(_components.p,{children:[`If any client in the app uses the Web SDK or a cross-platform SDK, `,_jsx(_components.strong,{children:`do not turn on the toggle`}),`. Once it is on, OneSignal rejects requests from those clients that create or update users and subscriptions. `,_jsx(_components.code,{children:`login`}),`, `,_jsx(_components.code,{children:`addEmail`}),`, and `,_jsx(_components.code,{children:`addSms`}),` fail, and new devices on those clients cannot register a push subscription.`]}),_jsx(_components.p,{children:`You can still generate keys and build JWT signing on your server now. Only the toggle enforces verification.`})]}),`\n`,_jsx(Heading,{level:`2`,id:`prerequisites`,children:`Prerequisites`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`An existing OneSignal app with a configured push platform.`}),`\n`,_jsxs(_components.li,{children:[`Every client that calls `,_jsx(_components.code,{children:`login`}),` uses a `,_jsx(_components.a,{href:`#supported-sdks`,children:`supported SDK`}),`: the native Android SDK 5.9.0+ or the native iOS SDK 5.8.0+.`]}),`\n`,_jsx(_components.li,{children:`A backend that authenticates your users and can sign JWTs.`}),`\n`,_jsxs(_components.li,{children:[`Access to `,_jsx(_components.strong,{children:`Settings > Keys \u0026 IDs`}),` in the OneSignal dashboard. The `,_jsx(_components.strong,{children:`Identity Verification`}),` section is available for every app. You do not need to contact support.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`generate-keys`,children:`Generate keys`}),`\n`,_jsxs(_components.p,{children:[`Complete these steps in order: generate keys, create the JWT, then add it to your app. Do not turn on the Token Identity Verification toggle until your backend can mint JWTs and your app can pass them to `,_jsx(_components.code,{children:`login`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Log in to your OneSignal account and go to `,_jsx(_components.strong,{children:`Settings > Keys \u0026 IDs > Identity Verification`}),`.`]}),`\n`,_jsx(Frame,{caption:`Identity Verification configuration`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/d6f1009-keys_and_ids.png?fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=c0be9c91a0dd0449b0120badf8f94b43`,alt:`Settings page showing Identity Verification section`,\"data-og-width\":`2401`,width:`2401`,\"data-og-height\":`734`,height:`734`,\"data-path\":`images/docs/d6f1009-keys_and_ids.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/d6f1009-keys_and_ids.png?w=280\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=2ca195dcb87843352cc0d544bf8637b1 280w, https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/d6f1009-keys_and_ids.png?w=560\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=9f5979c55f941ee93ac5607060f0e53a 560w, https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/d6f1009-keys_and_ids.png?w=840\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=5e2afdfd94ef1c8f14fb1b439a911915 840w, https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/d6f1009-keys_and_ids.png?w=1100\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=b194bbcf7b2beb774be103246d41ad3d 1100w, https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/d6f1009-keys_and_ids.png?w=1650\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=b6ff0ee4629b69e7c1360cc609bcb53a 1650w, https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/d6f1009-keys_and_ids.png?w=2500\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=da4f61ae97603300ccb0283854f8e553 2500w`})}),`\n`,_jsxs(_components.p,{children:[`Click `,_jsx(_components.strong,{children:`Generate New Keys`}),` to create a new key pair.`]}),`\n`,_jsx(Frame,{caption:`Creating new key pair`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b24c1fd-Identity_Verification.png?fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=73e56aa60fdef2dc8152bf929ebc1d52`,alt:`Generate New Keys button in the Identity Verification section`,\"data-og-width\":`2350`,width:`2350`,\"data-og-height\":`686`,height:`686`,\"data-path\":`images/docs/b24c1fd-Identity_Verification.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b24c1fd-Identity_Verification.png?w=280\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=ed67c9b1f27985e8732948d2a32c00df 280w, https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b24c1fd-Identity_Verification.png?w=560\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=6ebe69ac8a3ad8fdba9a1f614e29e184 560w, https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b24c1fd-Identity_Verification.png?w=840\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=ff80c8aa6103603a5373ca915c020d27 840w, https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b24c1fd-Identity_Verification.png?w=1100\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=909c5a15fddbb8d15775570f693cb4f5 1100w, https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b24c1fd-Identity_Verification.png?w=1650\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=c1f058eb0aced1cfc7bc4029e24bfac6 1650w, https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b24c1fd-Identity_Verification.png?w=2500\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=538d61d8fb65bcd370ef998830436751 2500w`})}),`\n`,_jsxs(_components.p,{children:[`Download the PEM file or copy the private key and store it securely. This private key is not an `,_jsx(_components.a,{href:`/docs/en/keys-and-ids#app-api-key`,children:`App API key`}),`. Use it only to sign Identity Verification JWTs.`]}),`\n`,_jsx(Frame,{caption:`Identity Verification key pair`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/bc217af-id_keys.png?fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=b8e99ccdb2f4aafd453063540148ca2e`,alt:`Identity Verification key pair with private key and PEM download`,\"data-og-width\":`1128`,width:`1128`,\"data-og-height\":`966`,height:`966`,\"data-path\":`images/docs/bc217af-id_keys.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/bc217af-id_keys.png?w=280\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=6a9dfe175839461254005d9ca1674505 280w, https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/bc217af-id_keys.png?w=560\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=f20c98f5367511637b83a5c6654a4de7 560w, https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/bc217af-id_keys.png?w=840\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=5aab2b4078c2af481d415d1450989a6f 840w, https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/bc217af-id_keys.png?w=1100\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=da4a94d77d6908e4f0a0941e1d5cae03 1100w, https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/bc217af-id_keys.png?w=1650\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=c49f1c335808b2ef25bbd1ad82972bfb 1650w, https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/bc217af-id_keys.png?w=2500\u0026fit=max\u0026auto=format\u0026n=56ctKxZSV4m5VEkn\u0026q=85\u0026s=6f7bf0e28c158f734cadd74480702663 2500w`})}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`Always store private keys in a secure environment, such as a key management system. Never expose private keys in client-side code, public repositories, or logs.`})}),`\n`,_jsx(_components.p,{children:`You now have a private key stored on your server and a public key held by OneSignal.`}),`\n`,_jsx(Heading,{level:`2`,id:`create-the-jwt`,children:`Create the JWT`}),`\n`,_jsxs(_components.p,{children:[`Authenticate the user with your own server `,_jsx(_components.strong,{children:`before`}),` you sign a token. When that auth succeeds, sign an ES256 JWT with the claims below and return it to the device in your auth response. If your app has no backend, stand up a small server whose only job is to verify users and sign these tokens. Never sign JWTs on the device.`]}),`\n`,_jsx(Heading,{level:`3`,id:`jwt-payload`,children:`JWT payload`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Claim`}),_jsx(_components.th,{children:`Required`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`iss`})}),_jsx(_components.td,{children:`Yes`}),_jsx(_components.td,{children:`Your OneSignal App ID.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`exp`})}),_jsx(_components.td,{children:`Yes`}),_jsxs(_components.td,{children:[`Expiration as a Unix timestamp in `,_jsx(_components.strong,{children:`seconds`}),`, not milliseconds. OneSignal rejects expired tokens.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`identity`})}),_jsx(_components.td,{children:`Yes`}),_jsxs(_components.td,{children:[`Object that includes `,_jsx(_components.code,{children:`external_id`}),`. This value must match the External ID you pass to `,_jsx(_components.code,{children:`OneSignal.login()`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`subscriptions`})}),_jsx(_components.td,{children:`No`}),_jsxs(_components.td,{children:[`Array of objects with `,_jsx(_components.code,{children:`type`}),` (`,_jsx(_components.code,{children:`Email`}),` or `,_jsx(_components.code,{children:`SMS`}),`) and `,_jsx(_components.code,{children:`token`}),`. Here `,_jsx(_components.code,{children:`token`}),` is the email address or E.164 phone number, not the JWT. Include this claim `,_jsx(_components.strong,{children:`before`}),` you call `,_jsx(_components.code,{children:`addEmail`}),` or `,_jsx(_components.code,{children:`addSms`}),`.`]})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`signing-the-jwt`,children:`Signing the JWT`}),`\n`,_jsxs(_components.p,{children:[`Sign the JWT with the `,_jsx(_components.strong,{children:`ES256`}),` algorithm (ECDSA using P-256 and SHA-256). Other algorithms are rejected. Use a `,_jsx(_components.a,{href:`https://jwt.io/libraries`,children:`JWT library`}),` rather than assembling the token by hand.`]}),`\n`,_jsxs(_components.p,{children:[`Example using `,_jsx(_components.a,{href:`https://www.npmjs.com/package/jsonwebtoken`,children:`jsonwebtoken`}),`. Pass the PEM private key you downloaded in the previous step:`]}),`\n`,_jsx(CodeBlock,{filename:`Node.js`,numberOfLines:`25`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`25`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` jwt`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"jsonwebtoken\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` APP_ID`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` process`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`env`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`ONESIGNAL_APP_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` IDENTITY_VERIFICATION_SECRET`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` process`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`env`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`ONESIGNAL_IDENTITY_VERIFICATION_SECRET_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` signOneSignalJWT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`externalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` payload`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` iss:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` APP_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` exp:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Math`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`floor`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`now`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`() `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`/`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1000`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`+`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 3600`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` identity:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` external_id:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` externalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` };`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` payload`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptions`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` subscriptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` jwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`sign`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`payload`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`IDENTITY_VERIFICATION_SECRET`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` algorithm:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"ES256\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` onesignalJWT`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` signOneSignalJWT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"YOUR_EXTERNAL_ID\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`]})})}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Store the PEM private key with its line breaks intact. Many environment variable systems strip newlines, which makes ES256 signing fail. Preserve the literal `,_jsx(_components.code,{children:`\\\\n`}),` characters, or base64-encode the key and decode it at runtime.`]})}),`\n`,_jsx(Heading,{level:`3`,id:`verify-your-jwt`,children:`Verify your JWT`}),`\n`,_jsxs(_components.p,{children:[`Log or return the string from `,_jsx(_components.code,{children:`signOneSignalJWT()`}),`, then decode it to confirm the payload. `,_jsx(_components.a,{href:`https://jwt.io`,children:`jwt.io`}),` decodes tokens in your browser, but treat a real user’s token as a secret and use a test token when pasting into third-party tools. The decoded payload must look like this:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"iss\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"your-onesignal-app-id\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"exp\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1234567890`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"identity\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"external_id\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"your-external-id\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Confirm all of the following before you call `,_jsx(_components.code,{children:`login`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`iss`}),` matches your OneSignal App ID from `,_jsx(_components.strong,{children:`Settings > Keys \u0026 IDs`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`identity.external_id`}),` matches the value you will pass to `,_jsx(_components.code,{children:`OneSignal.login()`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`exp`}),` is in the future and expressed in seconds`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`including-subscriptions`,children:`Including subscriptions`}),`\n`,_jsxs(_components.p,{children:[`Include email and SMS in the JWT at login when you already have those values. If they arrive later, mint a new JWT that includes the `,_jsx(_components.code,{children:`subscriptions`}),` claim and pass it to `,_jsx(_components.code,{children:`updateUserJwt`}),` before you call `,_jsx(_components.code,{children:`addEmail`}),` or `,_jsx(_components.code,{children:`addSms`}),`. See `,_jsx(_components.a,{href:`#adding-subscriptions`,children:`Adding subscriptions`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:`Node.js`,numberOfLines:`11`,language:`javascript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`javascript`,children:_jsxs(_components.code,{language:`javascript`,numberOfLines:`11`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` subscriptions`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` type:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Email\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` token:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"user@example.com\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` type:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"SMS\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` token:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"+15551234567\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`];`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` onesignalJWT`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` signOneSignalJWT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"YOUR_EXTERNAL_ID\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`subscriptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Phone numbers must use `,_jsx(_components.a,{href:`https://www.twilio.com/docs/glossary/what-e164`,children:`E.164 format`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`add-the-jwt-to-your-app`,children:`Add the JWT to your app`}),`\n`,_jsx(_components.p,{children:`Complete these steps in your mobile app.`}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Pass the JWT to the login method`,children:[_jsxs(_components.p,{children:[`Call `,_jsx(_components.code,{children:`login`}),` with the External ID and the JWT. Until Token Identity Verification is enabled in the dashboard, the SDK does not send the JWT, so you can ship this app update before you turn on the toggle. After you enable the toggle, `,_jsx(_components.code,{children:`login`}),` without a valid JWT fails.`]}),_jsxs(CodeGroup,{children:[_jsx(CodeBlock,{filename:`Java`,numberOfLines:`4`,language:`java`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`java`,children:_jsxs(_components.code,{language:`java`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#4EC9B0`},children:`String`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` externalId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"YOUR_EXTERNAL_ID\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#4EC9B0`},children:`String`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` onesignalJWT`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"YOUR_JWT_TOKEN\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`OneSignal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`login`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, onesignalJWT);`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Kotlin`,numberOfLines:`4`,language:`kotlin`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`kotlin`,children:_jsxs(_components.code,{language:`kotlin`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`val`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` externalId `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"YOUR_EXTERNAL_ID\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`val`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"YOUR_JWT_TOKEN\"`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`login`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, onesignalJWT)`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Kotlin (suspend)`,numberOfLines:`4`,language:`kotlin`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`kotlin`,children:_jsxs(_components.code,{language:`kotlin`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`val`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` externalId `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"YOUR_EXTERNAL_ID\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`val`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"YOUR_JWT_TOKEN\"`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`loginSuspend`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, onesignalJWT)`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Swift`,numberOfLines:`4`,language:`swift`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`swift`,children:_jsxs(_components.code,{language:`swift`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`let`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` externalId `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"YOUR_EXTERNAL_ID\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`let`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"YOUR_JWT_TOKEN\"`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`login`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`externalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: externalId, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`token`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: onesignalJWT)`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Objective-C`,numberOfLines:`4`,language:`objective-c`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`objective-c`,children:_jsxs(_components.code,{language:`objective-c`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`NSString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`externalId `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @\"YOUR_EXTERNAL_ID\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`NSString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @\"YOUR_JWT_TOKEN\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[OneSignal `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`login:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`externalId `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`withToken:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`onesignalJWT];`})]}),`\n`]})})})]}),_jsx(_components.p,{children:`On success, OneSignal associates the device’s subscription with your External ID and the user becomes an identified user.`})]}),_jsxs(Step,{title:`Handle JWT lifecycle events`,children:[_jsxs(_components.p,{children:[`When OneSignal rejects a JWT (for example, because it expired), the SDK fires a JWT invalidated event. Fetch a new token from your backend and pass it to `,_jsx(_components.code,{children:`updateUserJwt`}),`. Requests that need the token wait until you supply it. You can use the same endpoint to mint a token that includes email or SMS if the original login token did not.`]}),_jsxs(_components.p,{children:[`Add the listener at app startup, before you call `,_jsx(_components.code,{children:`login`}),`:`]}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Android:`}),` add it in `,_jsx(_components.code,{children:`Application.onCreate`}),`. The listener only receives events that fire after you add it, and it is called on a background thread.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`iOS:`}),` the SDK holds the listener weakly, so keep a strong reference to it. It is called on the main thread, so fetch the token asynchronously. If an event fired before you added the listener, the SDK delivers it when you add the listener.`]}),`\n`]}),_jsxs(CodeGroup,{children:[_jsx(CodeBlock,{filename:`Java`,numberOfLines:`6`,language:`java`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`java`,children:_jsxs(_components.code,{language:`java`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Called on a background thread, so a blocking network call is OK here.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`OneSignal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`addUserJwtInvalidatedListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(event `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`->`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#4EC9B0`},children:` String`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` externalId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`getExternalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#4EC9B0`},children:` String`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` onesignalJWT`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` OneSignal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, onesignalJWT);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),_jsx(CodeBlock,{filename:`Kotlin`,numberOfLines:`6`,language:`kotlin`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`kotlin`,children:_jsxs(_components.code,{language:`kotlin`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Called on a background thread, so a blocking network call is OK here.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`addUserJwtInvalidatedListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { event `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`->`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` val`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` externalId `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` event.externalId`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` val`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` OneSignal.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, onesignalJWT)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsx(CodeBlock,{filename:`Kotlin (suspend)`,numberOfLines:`7`,language:`kotlin`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`kotlin`,children:_jsxs(_components.code,{language:`kotlin`,numberOfLines:`7`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`addUserJwtInvalidatedListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { event `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`->`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` val`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` externalId `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` event.externalId`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` appScope.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`launch`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` val`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` OneSignal.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwtSuspend`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, onesignalJWT)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsx(CodeBlock,{filename:`Swift`,numberOfLines:`18`,language:`swift`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`swift`,children:_jsxs(_components.code,{language:`swift`,numberOfLines:`18`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` OneSignalFramework`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// The app delegate lives for the whole app session, so the SDK's weak reference stays valid.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`class`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` AppDelegate`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`UIResponder`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`UIApplicationDelegate`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`OSUserJwtInvalidatedListener `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` func`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` application`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` application`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: UIApplication, `}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`didFinishLaunchingWithOptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` launchOptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [UIApplication.LaunchOptionsKey: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Any`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`?`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` Bool`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` OneSignal.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`addUserJwtInvalidatedListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`self`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` true`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Called on the main thread. Fetch the token without blocking it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` func`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` onUserJwtInvalidated`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: OSUserJwtInvalidatedEvent) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` let`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` externalId `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` event.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`externalId`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` Task`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` let`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` try`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`externalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: externalId)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` OneSignal.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`externalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: externalId, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`token`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: onesignalJWT)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsx(CodeBlock,{filename:`Objective-C`,numberOfLines:`21`,language:`objective-c`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`objective-c`,children:_jsxs(_components.code,{language:`objective-c`,numberOfLines:`21`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`@import OneSignalFramework;`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`@interface`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` MyListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` : `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`NSObject`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` \u003cOSUserJwtInvalidatedListener>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`@end`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`@implementation`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` MyListener`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Called on the main thread. Fetch the token without blocking it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`void`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`onUserJwtInvalidatedWithEvent:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(OSUserJwtInvalidatedEvent `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`*`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` _Nonnull`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` NSString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`externalId `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`externalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`self`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwt:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`externalId `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`completion:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`^`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`NSString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`onesignalJWT) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [OneSignal `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`externalId `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`withToken:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`onesignalJWT];`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }];`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`@end`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// The SDK holds the listener weakly. Store it in a property that lives as long as your app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`self`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.jwtListener `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [MyListener `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`new`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`];`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[OneSignal `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`addUserJwtInvalidatedListener:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`self`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.jwtListener];`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// To stop listening:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[OneSignal `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`removeUserJwtInvalidatedListener:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`self`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.jwtListener];`})]}),`\n`]})})})]}),_jsxs(_components.p,{children:[`Replace `,_jsx(_components.code,{children:`fetchOneSignalJwt`}),` with a call to your backend. Do not sign JWTs on the device.`]}),_jsx(_components.p,{children:`With this listener in place, an expired token is replaced automatically and the session continues without forcing the user to log in again.`})]}),_jsxs(Step,{title:`Enable Token Identity Verification in the dashboard`,children:[_jsxs(_components.p,{children:[`From `,_jsx(_components.strong,{children:`Settings > Keys \u0026 IDs`}),`, turn on `,_jsx(_components.strong,{children:`Token Identity Verification`}),`.`]}),_jsx(Frame,{caption:`Enabling Token Identity Verification`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/4887367-identity_verification_enabled.png?fit=max\u0026auto=format\u0026n=YOTSrtBSoqdrJ37A\u0026q=85\u0026s=26d06ca0a008e841d5206093bfbf2a8c`,alt:`Token Identity Verification toggle enabled in dashboard settings`,\"data-og-width\":`2350`,width:`2350`,\"data-og-height\":`686`,height:`686`,\"data-path\":`images/docs/4887367-identity_verification_enabled.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/4887367-identity_verification_enabled.png?w=280\u0026fit=max\u0026auto=format\u0026n=YOTSrtBSoqdrJ37A\u0026q=85\u0026s=c4de06719a8828f43acaaaaef12a9dfc 280w, https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/4887367-identity_verification_enabled.png?w=560\u0026fit=max\u0026auto=format\u0026n=YOTSrtBSoqdrJ37A\u0026q=85\u0026s=8cd20820cfee031334a0e64eead8ce04 560w, https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/4887367-identity_verification_enabled.png?w=840\u0026fit=max\u0026auto=format\u0026n=YOTSrtBSoqdrJ37A\u0026q=85\u0026s=3dca5b6c52c8ad05e7288b6a6e8cb84f 840w, https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/4887367-identity_verification_enabled.png?w=1100\u0026fit=max\u0026auto=format\u0026n=YOTSrtBSoqdrJ37A\u0026q=85\u0026s=c7f729ce8add84a2d9fee687db901c5d 1100w, https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/4887367-identity_verification_enabled.png?w=1650\u0026fit=max\u0026auto=format\u0026n=YOTSrtBSoqdrJ37A\u0026q=85\u0026s=c44cddca2927f734599800fa14a272be 1650w, https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/4887367-identity_verification_enabled.png?w=2500\u0026fit=max\u0026auto=format\u0026n=YOTSrtBSoqdrJ37A\u0026q=85\u0026s=ee3c97bc4d74bd416e8b5ce313373342 2500w`})}),_jsx(_components.p,{children:`Before you turn it on, confirm:`}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`No client in this app uses the Web SDK or a cross-platform SDK. See `,_jsx(_components.a,{href:`#supported-sdks`,children:`Supported SDKs`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Most of your users are on an app version that passes a JWT to `,_jsx(_components.code,{children:`login`}),`. Older app versions still installed on devices cannot send a JWT, so their requests fail too.`]}),`\n`,_jsxs(_components.li,{children:[`Your server sends a JWT for the `,_jsx(_components.a,{href:`#rest-api`,children:`User REST APIs`}),` it calls.`]}),`\n`]}),_jsxs(_components.p,{children:[`From now on, OneSignal rejects any `,_jsx(_components.code,{children:`login`}),` or gated REST API call that does not include a valid JWT. See `,_jsx(_components.a,{href:`#what-changes-when-the-toggle-is-on`,children:`What changes when the toggle is on`}),`.`]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`what-changes-when-the-toggle-is-on`,children:`What changes when the toggle is on`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Login:`}),` `,_jsx(_components.code,{children:`login`}),` requires a valid JWT whose `,_jsx(_components.code,{children:`identity.external_id`}),` matches the External ID.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Logged-out devices:`}),` the SDK does not create anonymous users on OneSignal. On a new install, the device does not register a push subscription until the app calls `,_jsx(_components.code,{children:`login`}),` with a valid JWT, so it cannot receive push notifications before then. If you send push to users before they log in, plan for this before you turn on the toggle.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Logout:`}),` `,_jsx(_components.code,{children:`logout()`}),` disables the device’s push subscription. Calling `,_jsx(_components.code,{children:`login`}),` with a JWT restores it. See the `,_jsx(_components.a,{href:`#what-happens-to-the-push-subscription-on-logout`,children:`FAQ`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Email and SMS:`}),` `,_jsx(_components.code,{children:`addEmail`}),` and `,_jsx(_components.code,{children:`addSms`}),` require a JWT that includes the address in its `,_jsx(_components.code,{children:`subscriptions`}),` claim. See `,_jsx(_components.a,{href:`#adding-subscriptions`,children:`Adding subscriptions`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`REST API:`}),` the User and Subscription endpoints require `,_jsx(_components.code,{children:`Authorization: Bearer YOUR_ONESIGNAL_JWT`}),`. See `,_jsx(_components.a,{href:`#rest-api`,children:`REST API`}),`.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`adding-subscriptions`,children:`Adding subscriptions`}),`\n`,_jsxs(_components.p,{children:[`If the login JWT already includes the email or phone number in `,_jsx(_components.code,{children:`subscriptions`}),`, `,_jsx(_components.code,{children:`login`}),` associates those subscriptions with the user. You do not need a second call.`]}),`\n`,_jsxs(_components.p,{children:[`If the address is not in the JWT yet, mint a new token that includes it, call `,_jsx(_components.code,{children:`updateUserJwt`}),`, then call `,_jsx(_components.code,{children:`addEmail`}),` or `,_jsx(_components.code,{children:`addSms`}),`. Do this on every platform. `,_jsx(_components.code,{children:`addEmail`}),` / `,_jsx(_components.code,{children:`addSms`}),` alone is not enough once Token Identity Verification is on.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`fetchOneSignalJwtWithEmail`}),` and `,_jsx(_components.code,{children:`fetchOneSignalJwtWithSms`}),` are placeholders for your own backend call that mints a JWT with the `,_jsx(_components.code,{children:`subscriptions`}),` claim.`]}),`\n`,_jsxs(Tabs,{children:[_jsx(Tab,{title:`Add an email`,id:`add-an-email`,children:_jsxs(CodeGroup,{children:[_jsx(CodeBlock,{filename:`Java`,numberOfLines:`3`,language:`java`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`java`,children:_jsxs(_components.code,{language:`java`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#4EC9B0`},children:`String`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` onesignalJWT`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwtWithEmail`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, emailAddress);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`OneSignal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, onesignalJWT);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`OneSignal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`getUser`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`().`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`addEmail`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(emailAddress);`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Kotlin`,numberOfLines:`3`,language:`kotlin`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`kotlin`,children:_jsxs(_components.code,{language:`kotlin`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`val`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwtWithEmail`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, emailAddress)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, onesignalJWT)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.User.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`addEmail`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(emailAddress)`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Swift`,numberOfLines:`3`,language:`swift`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`swift`,children:_jsxs(_components.code,{language:`swift`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`let`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwtWithEmail`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`externalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: externalId, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`email`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: emailAddress)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`externalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: externalId, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`token`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: onesignalJWT)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`User`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`addEmail`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(emailAddress)`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Objective-C`,numberOfLines:`3`,language:`objective-c`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`objective-c`,children:_jsxs(_components.code,{language:`objective-c`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`NSString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`self`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwtWithEmail:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`externalId `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`email:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`emailAddress];`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[OneSignal `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`externalId `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`withToken:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`onesignalJWT];`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[OneSignal.User `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`addEmail:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`emailAddress];`})]}),`\n`]})})})]})}),_jsx(Tab,{title:`Add a phone number`,id:`add-a-phone-number`,children:_jsxs(CodeGroup,{children:[_jsx(CodeBlock,{filename:`Java`,numberOfLines:`3`,language:`java`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`java`,children:_jsxs(_components.code,{language:`java`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#4EC9B0`},children:`String`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` onesignalJWT`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwtWithSms`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, smsNumber);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`OneSignal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, onesignalJWT);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`OneSignal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`getUser`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`().`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`addSms`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(smsNumber);`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Kotlin`,numberOfLines:`3`,language:`kotlin`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`kotlin`,children:_jsxs(_components.code,{language:`kotlin`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`val`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwtWithSms`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, smsNumber)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(externalId, onesignalJWT)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.User.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`addSms`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(smsNumber)`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Swift`,numberOfLines:`3`,language:`swift`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`swift`,children:_jsxs(_components.code,{language:`swift`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`let`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwtWithSms`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`externalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: externalId, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`sms`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: smsNumber)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`externalId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: externalId, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`token`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: onesignalJWT)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`OneSignal.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`User`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`addSms`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(smsNumber)`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Objective-C`,numberOfLines:`3`,language:`objective-c`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`objective-c`,children:_jsxs(_components.code,{language:`objective-c`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`NSString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`onesignalJWT `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`self`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` fetchOneSignalJwtWithSms:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`externalId `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`sms:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`smsNumber];`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[OneSignal `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`updateUserJwt:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`externalId `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`withToken:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`onesignalJWT];`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[OneSignal.User `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`addSms:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`smsNumber];`})]}),`\n`]})})})]})})]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`rest-api`,children:`REST API`}),`\n`,_jsxs(_components.p,{children:[`Identity Verification JWTs are `,_jsx(_components.strong,{children:`not`}),` App API keys. Other endpoints (for example `,_jsx(_components.a,{href:`/reference/create-message`,children:`Create message`}),`) still use `,_jsx(_components.code,{children:`Authorization: Key YOUR_APP_API_KEY`}),`. See `,_jsx(_components.a,{href:`/docs/en/keys-and-ids`,children:`Keys \u0026 IDs`}),`.`]}),`\n`,_jsx(_components.p,{children:`When Token Identity Verification is enabled, the User and Subscription endpoints below authenticate with the identity JWT instead:`}),`\n`,_jsx(CodeBlock,{numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Authorization: Bearer YOUR_ONESIGNAL_JWT`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`Mint that JWT the same way as for SDK `,_jsx(_components.code,{children:`login`}),`. The `,_jsx(_components.code,{children:`identity.external_id`}),` in the token must match the user the request operates on.`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/reference/create-user`,children:`Create user`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/reference/view-user`,children:`View user`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/reference/update-user`,children:`Update user`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/reference/delete-user`,children:`Delete user`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/reference/fetch-aliases`,children:`View user identity`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/reference/create-alias`,children:`Create alias`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/reference/delete-alias`,children:`Delete alias`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/reference/create-subscription`,children:`Create subscription`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/reference/update-subscription`,children:`Update subscription`})}),`\n`]}),`\n`,_jsx(_components.p,{children:`Example:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -X`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` GET`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'https://api.onesignal.com/apps/YOUR_APP_ID/users/by/external_id/YOUR_EXTERNAL_ID'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'Authorization: Bearer YOUR_ONESIGNAL_JWT'`})]}),`\n`]})})}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`troubleshooting`,children:`Troubleshooting`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Symptom`}),_jsx(_components.th,{children:`Likely cause`}),_jsx(_components.th,{children:`Fix`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`login`}),` seems to do nothing after you enable the toggle`]}),_jsx(_components.td,{children:`The JWT is missing, expired, or signed with an algorithm other than ES256`}),_jsxs(_components.td,{children:[`Pass a valid ES256 JWT whose `,_jsx(_components.code,{children:`exp`}),` is in the future.`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`A gated REST API call returns `,_jsx(_components.code,{children:`401 Unauthorized`})]}),_jsxs(_components.td,{children:[`Missing or invalid `,_jsx(_components.code,{children:`Authorization: Bearer`}),` JWT, or `,_jsx(_components.code,{children:`identity.external_id`}),` does not match the target user`]}),_jsxs(_components.td,{children:[`Send a current JWT whose `,_jsx(_components.code,{children:`identity.external_id`}),` matches the user in the request path.`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`exp`}),` is rejected even though the token looks valid`]}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`exp`}),` was set in milliseconds instead of seconds`]}),_jsxs(_components.td,{children:[`Set `,_jsx(_components.code,{children:`exp`}),` to a Unix timestamp in seconds.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`New installs have no push subscription after you enable the toggle`}),_jsx(_components.td,{children:`The user has not logged in. Anonymous users are not created while the toggle is on.`}),_jsxs(_components.td,{children:[`Call `,_jsx(_components.code,{children:`login`}),` with a valid JWT as soon as the user is authenticated.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Web, React Native, Flutter, or other cross-platform users stopped updating after you enabled the toggle`}),_jsx(_components.td,{children:`Those SDKs cannot send a JWT yet`}),_jsxs(_components.td,{children:[`Turn off Token Identity Verification. Turn it back on only when every client uses a `,_jsx(_components.a,{href:`#supported-sdks`,children:`supported SDK`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`The JWT invalidated listener never fires on Android`}),_jsx(_components.td,{children:`The listener was added after the event fired`}),_jsxs(_components.td,{children:[`Add the listener in `,_jsx(_components.code,{children:`Application.onCreate`}),`, before you call `,_jsx(_components.code,{children:`login`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`The JWT invalidated listener stops firing on iOS`}),_jsx(_components.td,{children:`The SDK holds the listener weakly and it was released`}),_jsx(_components.td,{children:`Keep a strong reference to the listener for the life of the app.`})]})]})]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`faq`,children:`FAQ`}),`\n`,_jsx(Heading,{level:`3`,id:`is-identity-verification-required`,children:`Is identity verification required?`}),`\n`,_jsx(_components.p,{children:`No, but it is strongly recommended for production apps. Without it, any client that knows a user’s External ID can impersonate that user and modify their subscriptions or data.`}),`\n`,_jsx(Heading,{level:`3`,id:`what-is-the-“identity-verification-for-email-+-external_id”-toggle`,children:`What is the “Identity Verification for email + external_id” toggle?`}),`\n`,_jsx(Frame,{caption:`Legacy Identity Verification toggle in Keys \u0026 IDs`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/legacy-iv-toggle.jpg?fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=7c07e9feedde98a29745251d38375525`,alt:`Settings page showing legacy Identity Verification toggle`,\"data-og-width\":`710`,width:`710`,\"data-og-height\":`70`,height:`70`,\"data-path\":`images/docs/legacy-iv-toggle.jpg`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/legacy-iv-toggle.jpg?w=280\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=47b24309345365019e8f6337e120ebc1 280w, https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/legacy-iv-toggle.jpg?w=560\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=61dde8dd142796b3155bc9c533d5ad8c 560w, https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/legacy-iv-toggle.jpg?w=840\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=b416ad5abd645f9f152df552038513a3 840w, https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/legacy-iv-toggle.jpg?w=1100\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=5100064ff483ee737c40a7555600ba51 1100w, https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/legacy-iv-toggle.jpg?w=1650\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=0291d607c1705c0ea718f7e01c05d335 1650w, https://mintcdn.com/onesignal/q_BlLe_fAL4tDvWs/images/docs/legacy-iv-toggle.jpg?w=2500\u0026fit=max\u0026auto=format\u0026n=q_BlLe_fAL4tDvWs\u0026q=85\u0026s=65d3a0a914435215d1a252dc73c1a496 2500w`})}),`\n`,_jsxs(_components.p,{children:[`That toggle is a separate, legacy setting for OneSignal SDK v3/v4. It is not the JWT-based Identity Verification on this page and does not protect apps on SDK v5. For SDK v5, use `,_jsx(_components.strong,{children:`Generate New Keys`}),` in the `,_jsx(_components.strong,{children:`Identity Verification`}),` section under `,_jsx(_components.strong,{children:`Settings > Keys \u0026 IDs`}),`. See `,_jsx(_components.a,{href:`#generate-keys`,children:`Generate keys`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`which-sdks-support-identity-verification`,children:`Which SDKs support identity verification?`}),`\n`,_jsxs(_components.p,{children:[`The native Android SDK 5.9.0+ and the native iOS SDK 5.8.0+. The Web SDK and cross-platform SDKs (React Native, Expo, Flutter, Unity, Cordova, Ionic, Capacitor, and .NET MAUI) are not supported yet. See `,_jsx(_components.a,{href:`#supported-sdks`,children:`Supported SDKs`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`my-app-uses-the-web-sdk-or-a-cross-platform-sdk-can-i-turn-on-identity-verification`,children:`My app uses the Web SDK or a cross-platform SDK. Can I turn on Identity Verification?`}),`\n`,_jsx(_components.p,{children:`Not yet. The dashboard lets you turn on the toggle, but your clients cannot send a JWT, so their logins and subscription updates fail. You can generate keys and build JWT signing on your server now, then turn on the toggle once your SDK is supported.`}),`\n`,_jsx(Heading,{level:`3`,id:`what-algorithm-does-the-jwt-use`,children:`What algorithm does the JWT use?`}),`\n`,_jsx(_components.p,{children:`ES256 (ECDSA using P-256 and SHA-256). Other algorithms are rejected.`}),`\n`,_jsx(Heading,{level:`3`,id:`what-happens-if-the-jwt-expires-during-a-session`,children:`What happens if the JWT expires during a session?`}),`\n`,_jsxs(_components.p,{children:[`The SDK fires a JWT invalidation event. Implement `,_jsx(_components.code,{children:`addUserJwtInvalidatedListener`}),` (see `,_jsx(_components.a,{href:`#add-the-jwt-to-your-app`,children:`Add the JWT to your app`}),`) to fetch a new token and pass it to `,_jsx(_components.code,{children:`updateUserJwt`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`do-i-need-identity-verification-for-the-rest-api`,children:`Do I need identity verification for the REST API?`}),`\n`,_jsxs(_components.p,{children:[`Only after you enable Token Identity Verification. Then the `,_jsx(_components.a,{href:`#rest-api`,children:`User and Subscription endpoints`}),` require `,_jsx(_components.code,{children:`Authorization: Bearer YOUR_ONESIGNAL_JWT`}),`. They do not accept the App API key for those calls. Create message and other non-user endpoints still use `,_jsx(_components.code,{children:`Authorization: Key YOUR_APP_API_KEY`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`what-happens-to-the-push-subscription-on-logout`,children:`What happens to the push subscription on logout?`}),`\n`,_jsxs(_components.p,{children:[`When Identity Verification is enabled, `,_jsx(_components.code,{children:`logout()`}),` disables the push subscription. The subscription stays associated with that user. Calling `,_jsx(_components.code,{children:`login`}),` with a JWT restores the previous subscription status. You do not need to call `,_jsx(_components.code,{children:`optIn()`}),` again.`]}),`\n`,_jsxs(_components.p,{children:[`On Android (Kotlin), `,_jsx(_components.code,{children:`logoutSuspend()`}),` is the non-blocking equivalent of `,_jsx(_components.code,{children:`logout()`}),`.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`related-pages`,children:`Related pages`}),`\n`,_jsxs(Columns,{cols:2,children:[_jsx(Card,{title:`Users`,icon:`users`,href:`/docs/en/users`,children:_jsx(_components.p,{children:`External ID, anonymous vs identified Users, and login/logout.`})}),_jsx(Card,{title:`Keys \u0026 IDs`,icon:`key`,href:`/docs/en/keys-and-ids`,children:_jsx(_components.p,{children:`App ID, App API keys, and where Identity Verification keys live.`})}),_jsx(Card,{title:`Mobile SDK reference`,icon:`mobile`,href:`/docs/en/mobile-sdk-reference`,children:_jsx(_components.p,{children:`login, logout, addEmail, addSms, and subscription methods.`})}),_jsx(Card,{title:`REST API overview`,icon:`code`,href:`/reference/rest-api-overview`,children:_jsx(_components.p,{children:`Default App API key authentication for endpoints that are not JWT-gated.`})})]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Identity verification","description":"Secure logins so a client cannot impersonate another user's External ID or claim email and SMS subscriptions they do not own. Generally available on the native Android SDK 5.9.0+ and iOS SDK 5.8.0+. Not yet supported on the Web SDK or cross-platform SDKs.","keywords":["identity verification","JWT","External ID","login JWT","updateUserJwt","user impersonation","ES256","Token Identity Verification","Android SDK 5.9.0","iOS SDK 5.8.0"],"href":"/docs/en/identity-verification"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Supported SDKs","slug":"supported-sdks","depth":2,"children":[]},{"title":"Prerequisites","slug":"prerequisites","depth":2,"children":[]},{"title":"Generate keys","slug":"generate-keys","depth":2,"children":[]},{"title":"Create the JWT","slug":"create-the-jwt","depth":2,"children":[{"title":"JWT payload","slug":"jwt-payload","depth":3,"children":[]},{"title":"Signing the JWT","slug":"signing-the-jwt","depth":3,"children":[]},{"title":"Verify your JWT","slug":"verify-your-jwt","depth":3,"children":[]},{"title":"Including subscriptions","slug":"including-subscriptions","depth":3,"children":[]}]},{"title":"Add the JWT to your app","slug":"add-the-jwt-to-your-app","depth":2,"children":[]},{"title":"What changes when the toggle is on","slug":"what-changes-when-the-toggle-is-on","depth":2,"children":[]},{"title":"Adding subscriptions","slug":"adding-subscriptions","depth":2,"children":[]},{"title":"REST API","slug":"rest-api","depth":2,"children":[]},{"title":"Troubleshooting","slug":"troubleshooting","depth":2,"children":[]},{"title":"FAQ","slug":"faq","depth":2,"children":[{"title":"Is identity verification required?","slug":"is-identity-verification-required","depth":3,"children":[]},{"title":"What is the “Identity Verification for email + external_id” toggle?","slug":"what-is-the-“identity-verification-for-email-+-external_id”-toggle","depth":3,"children":[]},{"title":"Which SDKs support identity verification?","slug":"which-sdks-support-identity-verification","depth":3,"children":[]},{"title":"My app uses the Web SDK or a cross-platform SDK. Can I turn on Identity Verification?","slug":"my-app-uses-the-web-sdk-or-a-cross-platform-sdk-can-i-turn-on-identity-verification","depth":3,"children":[]},{"title":"What algorithm does the JWT use?","slug":"what-algorithm-does-the-jwt-use","depth":3,"children":[]},{"title":"What happens if the JWT expires during a session?","slug":"what-happens-if-the-jwt-expires-during-a-session","depth":3,"children":[]},{"title":"Do I need identity verification for the REST API?","slug":"do-i-need-identity-verification-for-the-rest-api","depth":3,"children":[]},{"title":"What happens to the push subscription on logout?","slug":"what-happens-to-the-push-subscription-on-logout","depth":3,"children":[]}]},{"title":"Related pages","slug":"related-pages","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/onesignal/e069c1b9f3157e14/hotjar-koala.js","/_mintlify/custom/onesignal/3e5d03885ab32f49/intercom.js","/_mintlify/custom/onesignal/dbb7af4794d1b586/munchkin-marketo.js"],"subdomain":"onesignal","siteName":"OneSignal","title":"Identity verification - OneSignal","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{"en":{"href":"/docs/en/identity-verification","matchLevel":0},"cn":{"href":"/docs/cn/identity-verification","matchLevel":1},"ko":{"href":"/docs/ko/identity-verification","matchLevel":1},"ja":{"href":"/docs/ja/identity-verification","matchLevel":1},"tr":{"href":"/docs/tr/identity-verification","matchLevel":1},"pt-BR":{"href":"/docs/pt-BR/identity-verification","matchLevel":1},"es":{"href":"/docs/es/identity-verification","matchLevel":1},"fr":{"href":"/docs/fr/identity-verification","matchLevel":1}}},"lastModified":"2026-10-22T17:53:39.183Z","originalFileLocation":"docs/en/identity-verification.mdx","locale":"en"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Secure logins so a client cannot impersonate another user\u0026#x27;s External ID or claim email and SMS subscriptions they do not own. Generally available on the native Android SDK 5.9.0+ and iOS SDK 5.8.0+. Not yet supported on the Web SDK or cross-platform SDKs.\">\u003cmeta data-mint-head name=\"application-name\" content=\"OneSignal\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/onesignal/eCiRydtW5fLfLRWp/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/onesignal/eCiRydtW5fLfLRWp/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/onesignal/eCiRydtW5fLfLRWp/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/onesignal/eCiRydtW5fLfLRWp/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/onesignal/eCiRydtW5fLfLRWp/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/onesignal/eCiRydtW5fLfLRWp/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/onesignal/eCiRydtW5fLfLRWp/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/onesignal/eCiRydtW5fLfLRWp/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/onesignal/eCiRydtW5fLfLRWp/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Identity verification - OneSignal\">\u003cmeta data-mint-head property=\"og:description\" content=\"Secure logins so a client cannot impersonate another user\u0026#x27;s External ID or claim email and SMS subscriptions they do not own. Generally available on the native Android SDK 5.9.0+ and iOS SDK 5.8.0+. Not yet supported on the Web SDK or cross-platform SDKs.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"OneSignal\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://documentation.onesignal.com/docs/en/identity-verification\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://onesignal.mintlify.app/_mintlify/api/og/v2?division=Developer+Documentation\u0026amp;title=Identity+verification\u0026amp;description=Secure+logins+so+a+client+cannot+impersonate+another+user%27s+External+ID+or+claim+email+and+SMS+subscriptions+they+do+not+own.+Generally+available+on+the+native+\u0026amp;theme=8d648f04f85028b307bd669b\u0026amp;signature=ea53aabce281d62a483424a7dde21c5454db65eff9ca7b82b1330384387ffeaf\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Identity verification - OneSignal\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Secure logins so a client cannot impersonate another user\u0026#x27;s External ID or claim email and SMS subscriptions they do not own. Generally available on the native Android SDK 5.9.0+ and iOS SDK 5.8.0+. Not yet supported on the Web SDK or cross-platform SDKs.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://onesignal.mintlify.app/_mintlify/api/og/v2?division=Developer+Documentation\u0026amp;title=Identity+verification\u0026amp;description=Secure+logins+so+a+client+cannot+impersonate+another+user%27s+External+ID+or+claim+email+and+SMS+subscriptions+they+do+not+own.+Generally+available+on+the+native+\u0026amp;theme=8d648f04f85028b307bd669b\u0026amp;signature=ea53aabce281d62a483424a7dde21c5454db65eff9ca7b82b1330384387ffeaf\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/onesignal/eCiRydtW5fLfLRWp/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"OneSignal Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#3A3DB3\">\u003clink data-mint-head rel=\"canonical\" href=\"https://documentation.onesignal.com/docs/en/identity-verification\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/en/identity-verification.md\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"en\" href=\"https://documentation.onesignal.com/docs/en/identity-verification\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"zh\" href=\"https://documentation.onesignal.com/docs/cn/identity-verification\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ko\" href=\"https://documentation.onesignal.com/docs/ko/identity-verification\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ja\" href=\"https://documentation.onesignal.com/docs/ja/identity-verification\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"tr\" href=\"https://documentation.onesignal.com/docs/tr/identity-verification\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"pt-BR\" href=\"https://documentation.onesignal.com/docs/pt-BR/identity-verification\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"es\" href=\"https://documentation.onesignal.com/docs/es/identity-verification\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"fr\" href=\"https://documentation.onesignal.com/docs/fr/identity-verification\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"x-default\" href=\"https://documentation.onesignal.com/docs/en/identity-verification\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://documentation.onesignal.com/#organization\",\"name\":\"OneSignal\",\"url\":\"https://documentation.onesignal.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/onesignal/yJcueeDCO7UpHnnY/logo/OneSignal-Logo.svg?fit=max\u0026auto=format\u0026n=yJcueeDCO7UpHnnY\u0026q=85\u0026s=1fcfb6fef6d820fd9d99c74850711107\"}},{\"@type\":\"WebSite\",\"@id\":\"https://documentation.onesignal.com#website\",\"name\":\"OneSignal\",\"url\":\"https://documentation.onesignal.com\",\"publisher\":{\"@id\":\"https://documentation.onesignal.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://documentation.onesignal.com/docs/en/identity-verification#webpage\",\"url\":\"https://documentation.onesignal.com/docs/en/identity-verification\",\"name\":\"Identity verification\",\"description\":\"Secure logins so a client cannot impersonate another user's External ID or claim email and SMS subscriptions they do not own. Generally available on the native Android SDK 5.9.0+ and iOS SDK 5.8.0+. Not yet supported on the Web SDK or cross-platform SDKs.\",\"dateModified\":\"2026-10-22T17:53:39.183Z\",\"isPartOf\":{\"@id\":\"https://documentation.onesignal.com#website\"},\"breadcrumb\":{\"@id\":\"https://documentation.onesignal.com/docs/en/identity-verification#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://documentation.onesignal.com/docs/en/identity-verification#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Developer Documentation\",\"item\":\"https://documentation.onesignal.com/docs/en/developers\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Identity verification\",\"item\":\"https://documentation.onesignal.com/docs/en/identity-verification\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://documentation.onesignal.com/docs/en/identity-verification#article\",\"headline\":\"Identity verification\",\"name\":\"Identity verification\",\"description\":\"Secure logins so a client cannot impersonate another user's External ID or claim email and SMS subscriptions they do not own. Generally available on the native Android SDK 5.9.0+ and iOS SDK 5.8.0+. Not yet supported on the Web SDK or cross-platform SDKs.\",\"url\":\"https://documentation.onesignal.com/docs/en/identity-verification\",\"mainEntityOfPage\":{\"@id\":\"https://documentation.onesignal.com/docs/en/identity-verification#webpage\"},\"dateModified\":\"2026-10-22T17:53:39.183Z\",\"keywords\":\"identity verification, JWT, External ID, login JWT, updateUserJwt, user impersonation, ES256, Token Identity Verification, Android SDK 5.9.0, iOS SDK 5.8.0\",\"publisher\":{\"@id\":\"https://documentation.onesignal.com/#organization\"},\"isPartOf\":{\"@id\":\"https://documentation.onesignal.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"OneSignal\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"OneSignal","nav":{"global":null,"languages":[{"language":"en","tabs":[{"tab":"Home","pages":[{"title":"Home","href":"/docs/en/home"}]},{"tab":"User Guides","pages":[{"title":"User Guides","href":"/docs/en/quickstart-guide"}]},{"tab":"Developer Guides","groups":[{"group":"Developer Documentation","pages":[{"title":"Developers","description":"Set up the OneSignal Mobile and Web SDKs, find your App ID and API keys, identify Users, and test your integration before going live.","href":"/docs/en/developers"},{"title":"Identity verification","href":"/docs/en/identity-verification"},{"group":"User model","pages":[{"title":"User model \u0026 migration guide","description":"Learn how to migrate from OneSignal’s device-centric model to the new user-centric APIs and SDKs for more personalized, multi-channel engagement.","href":"/docs/en/user-model-migration-guide"},{"title":"Mobile SDK Mapping","href":"/docs/en/device-user-model-mobile-sdk-mapping"},{"title":"Web SDK Mapping","href":"/docs/en/device-user-model-web-sdk-mapping"}]}]},{"group":"Mobile SDKs","pages":[{"group":"Mobile SDK setup","pages":[{"title":"Mobile SDK setup","href":"/docs/en/mobile-sdk-setup"},{"group":"Platform credential setup","pages":[{"title":"Android Firebase credentials","href":"/docs/en/android-firebase-credentials"},{"title":"iOS p8 token-based connection to APNs","href":"/docs/en/ios-p8-token-based-connection-to-apns"},{"title":"iOS p12 certificate generation","href":"/docs/en/ios-p12-generate-certificates"},{"title":"Amazon API key generation","href":"/docs/en/generate-an-amazon-api-key"},{"title":"Huawei authorization","href":"/docs/en/authorize-onesignal-to-send-huawei-push"}]},{"title":"iOS SDK setup","href":"/docs/en/ios-sdk-setup"},{"title":"Android SDK setup","href":"/docs/en/android-sdk-setup"},{"title":"Unity SDK setup","href":"/docs/en/unity-sdk-setup"},{"title":"React Native SDK setup","href":"/docs/en/react-native-sdk-setup"},{"title":"Expo SDK setup","href":"/docs/en/react-native-expo-sdk-setup"},{"title":"Flutter SDK setup","href":"/docs/en/flutter-sdk-setup"},{"title":"Flutterflow SDK setup","href":"/docs/en/flutterflow-sdk-setup"},{"title":"Cordova SDK setup","href":"/docs/en/cordova-sdk-setup"},{"title":"Capacitor SDK setup","href":"/docs/en/capacitor-sdk-setup"},{"title":".NET MAUI SDK setup","href":"/docs/en/net-sdk-setup"},{"title":"Amazon SDK setup","href":"/docs/en/amazon-sdk-setup"},{"title":"Huawei SDK setup","href":"/docs/en/huawei-sdk-setup"}]},{"group":"Mobile SDK reference","pages":[{"title":"Mobile SDK reference","href":"/docs/en/mobile-sdk-reference"},{"title":"Mobile service extensions","href":"/docs/en/service-extensions"},{"title":"Managing the notification tray","href":"/docs/en/managing-the-notification-tray"},{"title":"OSNotification payload","href":"/docs/en/osnotification-payload"},{"title":"iOS: App Clip Support","href":"/docs/en/app-clip-support"}]},{"group":"Mobile SDK troubleshooting","pages":[{"title":"Mobile SDK troubleshooting","href":"/docs/en/mobile-troubleshooting"},{"title":"Getting a Debug Log","href":"/docs/en/capturing-a-debug-log"}]}]},{"group":"Web SDKs","pages":[{"group":"Web SDK setup","pages":[{"title":"Web SDK setup","href":"/docs/en/web-sdk-setup"},{"title":"iOS web push setup","href":"/docs/en/web-push-for-ios"},{"title":"OneSignal service worker","href":"/docs/en/onesignal-service-worker"},{"title":"Custom code web push setup with the OneSignal Web SDK","href":"/docs/en/web-push-custom-code-setup"},{"title":"Google Tag Manager setup","href":"/docs/en/google-tag-manager"},{"title":"Angular Web SDK setup","href":"/docs/en/angular-setup"},{"title":"ReactJS \u0026 NextJS Setup","href":"/docs/en/react-js-setup"},{"title":"Vue JS Web SDK setup","href":"/docs/en/vue-js-setup"}]},{"title":"Web SDK reference","href":"/docs/en/web-sdk-reference"},{"group":"Web SDK troubleshooting","pages":[{"title":"Web SDK troubleshooting","href":"/docs/en/troubleshooting-web-push"},{"title":"Clearing cache and resetting push permissions","href":"/docs/en/clearing-cache-and-resetting-push-permissions"},{"title":"Web push webhooks","sidebarTitle":"Web push webhooks (legacy)","href":"/docs/en/webhooks"}]}]},{"group":"Live Activities","pages":[{"title":"Live Activities developer setup","href":"/docs/en/live-activities-developer-setup"},{"title":"Cross-platform Live Activity SDK setup","href":"/docs/en/cross-platform-live-activity-setup"},{"title":"Android Live Update notifications","href":"/docs/en/android-live-notifications"}]},{"group":"Desktop \u0026 Watch Setup","pages":[{"title":"macOS app setup","href":"/docs/en/macos-app-setup"},{"title":"Windows app setup","href":"/docs/en/windows-app-setup"},{"title":"watchOS \u0026 Wear OS Support","href":"/docs/en/watchos-and-wear-os-support"}]},{"group":"Legacy SDK reference","pages":[{"group":"v3-4 Client SDK reference","pages":[{"title":"v3-4 Client SDK Reference","href":"/v9.0/docs/sdk-reference"},{"title":"v3-4 SDK SDK Notification Event Handlers","href":"/v9.0/docs/sdk-notification-event-handlers"},{"title":"v4 Android Mobile Service Extensions","href":"/v9.0/docs/service-extensions"},{"title":"v3-4 SDK In-App Message SDK Methods","href":"/v9.0/docs/iam-sdk-methods"},{"title":"v3-4 SDK Web SDK Methods","href":"/v9.0/docs/web-push-sdk"},{"title":"v3-4 SDK SMS SDK Methods","href":"/v9.0/docs/sms-sdk-methods"},{"title":"v3-4 SDK Email SDK Methods","href":"/v9.0/docs/email-sdk-methods"}]},{"title":"v3-4 SDK Capturing a Debug Log","href":"/v9.0/docs/capturing-a-debug-log"},{"title":"v3-4 SDK Identity Verification","href":"/v9.0/docs/identity-verification"},{"title":"v3-4 SDK Handling Personal Data","href":"/v9.0/docs/handling-personal-data"}]}]},{"tab":"Tutorials","pages":[{"title":"Tutorials","href":"/docs/en/tutorials"}]},{"tab":"API Reference","pages":[{"title":"API Reference","href":"/reference/rest-api-overview"}]},{"tab":"Release Notes","pages":[{"title":"Release Notes","href":"/release-notes/changelog"}]},{"tab":"Customer Success Hub","pages":[{"title":"Customer Success Hub","href":"/docs/en/customer-success-hub"}]}],"global":{"anchors":[{"anchor":"Blog","icon":"newspaper","href":"https://onesignal.com/blog"},{"anchor":"GitHub","icon":"github","href":"https://github.com/OneSignal"},{"anchor":"YouTube","icon":"youtube","href":"https://www.youtube.com/@onesignalofficial/playlists"}]}},{"language":"cn","pages":[{"title":"cn","href":"/docs/cn/identity-verification"}]},{"language":"ko","pages":[{"title":"ko","href":"/docs/ko/identity-verification"}]},{"language":"ja","pages":[{"title":"ja","href":"/docs/ja/identity-verification"}]},{"language":"tr","pages":[{"title":"tr","href":"/docs/tr/identity-verification"}]},{"language":"pt-BR","pages":[{"title":"pt-BR","href":"/docs/pt-BR/identity-verification"}]},{"language":"es","pages":[{"title":"es","href":"/docs/es/identity-verification"}]},{"language":"fr","pages":[{"title":"fr","href":"/docs/fr/identity-verification"}]}]},"title":"Identity verification - OneSignal","buildId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","deploymentId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","dynamics":["07c022d89b","a74be98ba7","a9bb46feb3"],"chunks":["Frame-COGkNuA6.js","DynamicMarkdown-85clUA0i.js","zoom-image-lightbox-BZxD9MAj.js","lightbox-handle-r17bVUz3.js","Markdown-Cfiy0xZO.js","clsx-rL8ZCCw4.js","lib--scc4DXi.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-aeztFa9U.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-BywkCr5C.js"]}