Phone Number Silent Network Authentication
Phone Number Silent Network Authentication (SNA) checks that a phone number belongs to the SIM card in the user’s device:
- The check runs over the device’s cellular data connection.
- The user doesn’t type a code, and Persona shows no UI.
With Sentinel, SNA runs on Transactions:
- Your server starts the check by creating a Transaction with the phone number.
- Your app runs the carrier step with Persona’s SNA SDK. It needs only the Transaction ID and a client token.
- Your Workflow gets the result and continues.
This guide covers SNA with the Sentinel SDKs. If your app also uses the Inquiry SDK, see Use the Inquiry SDK with Sentinel and SNA.
On iOS, transaction-initiated SNA isn’t released yet. The iOS run API in this guide is the planned API and may change before release.
How it works
- Your server creates a Transaction with the user’s phone number. It sends the Transaction ID and a client token to your app.
- Your app calls
SilentNetworkAuthentication.runwith those two values. - Your Workflow runs on the new Transaction and creates an SNA Verification for its phone number.
- The SDK claims the Verification’s carrier check, runs it over cellular data and submits the result.
- Persona checks the result, and your Workflow continues down the branch for the Verification’s status.
Packages
Sentinel and SNA are separate packages:
- SNA is not part of the Sentinel package on either platform.
- You can run SNA without Sentinel. Add Sentinel only if you also collect Sentinel signals.
- The same SNA package also runs SNA steps in Inquiries. See Use the Inquiry SDK with Sentinel and SNA.
For approximate sizes, see Size impact.
Install
Add the packages for each platform your app supports.
Android
sna-impl is Persona’s SNA artifact. It’s optional and separate from sentinel, and it comes from the same repository as the other Persona Android artifacts.
A few details about these dependencies:
- Use the same version as your other Persona Android artifacts.
- If you only use SNA, leave out the
sentinelline. sna-implrequires Android 7.0 (API 24), because Vonage’s client library does. SetminSdkVersionto 24 or higher in apps that include it. Sentinel alone needs API 23.sna-implpulls in OkHttp, Moshi, Kotlin coroutines and Vonage’s client library 1.0.0.sna-impldoesn’t depend on the Inquiry SDK or on Sentinel.
For the full Sentinel setup, see the Sentinel Android Integration Guide.
iOS
Add Persona with Swift Package Manager. These packages aren’t published to CocoaPods.
- In Xcode, select your project’s Swift Packages tab and click
+. - Enter
https://github.com/persona-id/inquiry-ios-2and add the package. - Select the
PersonaSentinelproduct for your app target. - For transaction-initiated SNA, also select
PersonaSnaonce itsrunAPI is released.
iOS 15 or later is required.
Sentinel used to ship in the separate sentinel-ios package, which no longer gets releases. Add PersonaSentinel from inquiry-ios-2 instead.
For the full Sentinel setup, see the Sentinel iOS Integration Guide.
Set up once
Set up these pieces once, in the Dashboard or with the API:
-
A Transaction type with a phone number field, for example
phone_number. See Transaction types. -
A Workflow that runs SNA on each new Transaction of that type. See Building Workflows.
- Trigger it when a Transaction of the type is created.
- Add a Run Verification step that runs your SNA Verification template on the Transaction’s phone number field.
- Branch on the Verification’s status. For example, tag the Transaction when it passes, and fall back to another check when it fails.
- In Production, the Run Verification step waits for the Verification to finish before the Workflow continues. For Sandbox, see Test SNA.
-
Optionally, a webhook subscribed to
verification.passedandverification.failed, if you read the outcome from webhooks. See Webhooks. -
A client token for your app. Create it on your server with your API key, using Create a Client Token.
- Never put an API key in the app.
- List
verification.sna.submitinpermissions. - List the Transaction type’s ID in
allowed-resources. The token can’t run SNA for a Transaction type you don’t list.
- Setting
permissionsreplaces the default set (sentinel.collectandtxn.write). If your app uses the same token for Sentinel, list those too. - The token’s
valueis in the client token version, under the response’sincluded. - The
valueis returned only when that version is created, so store it on your server.
Run SNA for each Transaction
For each phone number you want to check:
-
Your server creates the Transaction with the phone number in
fields, using Create a Transaction.- Use the phone number on file for the user, or one they enter in your app.
- The SDK doesn’t collect the phone number.
- The response’s
data.idis the Transaction ID (txn_...). - The Transactions API rejects Sentinel-enabled Transaction types with HTTP 422. Create those through the Sentinel API with a client token instead.
-
Your server sends the Transaction ID and the client token value to your app right away. The Transaction ID is the only ID the app needs.
-
Your app calls
SilentNetworkAuthentication.runwith both values, as in the Android and iOS examples below.- The SDK waits for your Workflow to create the SNA Verification.
- It then runs the carrier check over cellular data and submits the result.
- The carrier check is only valid for a short time after the Verification is created, so call
runpromptly.
-
Persona checks the result, and the Workflow continues down the branch for the Verification’s status. Read the outcome on your server from either:
- The
verification.passedorverification.failedwebhook. - The Transaction’s status and tags that your Workflow sets.
- The
What run does
run handles the whole device side of the check:
- Polls Persona about once a second, for up to 2 minutes, until your Workflow has created the SNA Verification and its check is ready.
- Claims the check for this device. If the response is lost,
runretries the claim and gets the same check back. - Runs the carrier check over cellular data, with a timeout of at most 10 seconds, bounded by the check’s remaining validity.
- Submits the code or an error name to Persona, retrying network errors, server errors and transient conflicts up to 3 attempts.
Each Verification hands its check to one device, once. Call run once per Transaction: a second call, on any device, gets unavailable and reports it, which can fail a check that is still running.
Android
Import SilentNetworkAuthentication from the com.withpersona.sdk2.sna package. Call run from a coroutine, or use the Java overload with a callback:
The Kotlin run is a suspend function. The Java overload takes a Callback fun interface.
SilentNetworkAuthenticationResult is one of:
SubmittedClientError(name, message)Failed(reason), whereFailureReasonisINVALID_INPUT,UNAUTHORIZED,NOT_FOUND,NOT_ACCEPTED,NETWORK,SERVERorCANCELLED
iOS
Transaction-initiated SNA isn’t released on iOS yet. This is the planned API.
Import PersonaSna. Call run from an async context, or pass a completion handler:
The results are .submitted, .clientError(name:message:) and .failed(SilentNetworkAuthenticationFailure). The failure is one of .invalidInput, .unauthorized, .notFound, .notAccepted, .network, .server(statusCode:) or .cancelled.
Results
Each call returns one of three results:
Failure reasons (Android FailureReason / iOS SilentNetworkAuthenticationFailure):
The result never says whether the Verification passed. Get the outcome on your backend, from Verification or Transaction webhooks or from the Workflow. Don’t gate sign-in on the SDK result.
Test SNA
Sandbox and Production test different things:
- Sandbox: no carrier check runs.
- Persona tells the SDK that SNA is unavailable.
- The SDK records that and returns
ClientError(Android) or.clientError(iOS) with the nameunavailable. - Persona then completes the Verification with a simulated pass.
- Sandbox Workflows don’t wait for the SNA Verification. They continue as soon as it’s created.
- Use Sandbox to check your wiring (token permissions, passing the Transaction ID and calling
run), not to test Workflow branches on the SNA outcome.
- End to end: use Production.
- Use a phone whose subscriber identity module (SIM) card has the Transaction’s phone number.
- Turn on cellular data.
Limitations
Transaction-initiated SNA has these limits:
- Not available in FedRAMP (Federal Risk and Authorization Management Program) environments yet.
runalways talks to Persona’s default host,withpersona.com.- Don’t pass
runa client token from a FedRAMP organization.
- Requires Android 7.0 or later, or iOS 15 or later.
- SNA works only on devices with an active SIM card or eSIM (embedded SIM) profile.
Collect Sentinel signals (optional)
SNA doesn’t need this step. To also collect Sentinel’s passive device signals, build an event with your client token and Transaction type ID, then trigger it:
The builders also accept optional context, identifiers, environment ID and Account settings. See the Android and iOS guides for every option.
Use the Inquiry SDK with Sentinel and SNA
Some apps use all three SDKs:
- The Inquiry SDK runs identity verification flows (Inquiries).
- Sentinel collects passive device signals on Transactions.
- SNA checks phone numbers, inside an Inquiry or on a Transaction.
Where SNA runs
Which to use:
- Use an SNA step in an Inquiry when the user is already going through one, for example during onboarding.
- Use transaction-initiated SNA to check a phone number you already have without showing a flow, for example when a user signs in on a new device.
Android
Add all three artifacts:
- Use the same version
X.Y.Zfor all three. - Add
sna-implonce. The Inquiry SDK uses it for SNA steps, and your code calls itsrunfor Transactions. Don’t add another SNA artifact. - Set
minSdkVersionto 24 or higher, becausesna-implneeds Android 7.0. - For the rest of the Inquiry setup, see the Android Integration Guide.
iOS
- For Sentinel, select
PersonaSentinelfrominquiry-ios-2, as in Install. - For SNA steps in Inquiries, follow the SNA section of the iOS Integration Guide. It adds
PersonaSnaand passesPersonaSnaAdapter()to the Inquiry builder’s.snaAdapter. - Transaction-initiated SNA with
runisn’t released on iOS yet.
Client tokens
- Inquiries don’t use your SNA client token.
- Sentinel and transaction-initiated SNA can share one client token. List
sentinel.collect,txn.writeandverification.sna.submitin itspermissions.
Size impact
Sizes are approximate and change from release to release.
- The Android figures are from a release build with R8, arm64-v8a APK, of a minimal app.
- The iOS figure is the framework’s size in Persona’s framework size report. It isn’t the increase in your app’s download size, so measure in your app.
Next steps
For more on Sentinel, see:
- Sentinel overview
- Sentinel Android Integration Guide
- Sentinel iOS Integration Guide
- Sentinel Web Integration Guide
For the Inquiry SDK, see the Android and iOS Integration Guides.

