Skip to main content
Para doesn’t provide a pre-built modal for mobile — you authenticate by calling SDK methods directly. This guide shows how to authenticate users with email or phone using authenticateWithEmailOrPhone(), which handles the entire auth flow in a single call.
These methods are long-running — they internally poll for session completion and wait for the user to finish interacting with the portal. Call them from a provider or higher-order component that will not unmount during the authentication flow. If the component unmounts while the method is running, the authentication will be interrupted.
You are responsible for opening the portal URLs that Para generates during authentication. Use para.onStatePhaseChange() to listen for these URLs and open them in the device browser. See Handling Portal URLs below.

Prerequisites

Before implementing authentication, ensure you have completed the basic Para setup for your React Native or Expo application.

Email / Phone Authentication

Use para.authenticateWithEmailOrPhone() to authenticate a user by email or phone. The method handles the complete flow: determining whether the user is new or returning, session polling, and wallet creation. Combine it with the state listener below to open portal URLs, and handle OTP input when authPhase is 'awaiting_account_verification'.
For phone number authentication, pass { phone: '+1234567890' } instead of { email }:

Handling Portal URLs

During authentication, Para’s state machine emits portal URLs that the user must interact with (e.g. entering a verification code, creating a passkey, or entering a password). Since you’re building a custom UI, you need to subscribe to state changes and open these URLs using the in-app browser. Use para.onStatePhaseChange() to receive a StateSnapshot containing authStateInfo — a flat object with all the URLs and flags you need:

authStateInfo Fields

When authPhase is 'awaiting_account_verification', the user is a non-basic-login new signup who has been sent an OTP code via email or SMS. There is no URL to open — you must show a code input field and call para.verifyNewAccount({ verificationCode }). If the user needs a new code, call para.resendVerificationCode({ type: 'SIGNUP' }). The simplified method is waiting for this step to complete before it proceeds. See the full example above.

State Phase Reference

The StateSnapshot returned by para.onStatePhaseChange() contains three phase fields that tell you exactly where in the flow the user is. Use these to drive your UI.

corePhase — Top-Level Lifecycle

authPhase — Authentication Flow Detail

Basic login vs passkey/password/PIN: Basic login users complete their entire authentication through a portal URL — the verificationUrl handles OTP entry, passkey creation, etc. in a single hosted flow. Passkey, password, and PIN users go through a two-step process where OTP verification happens in your app (via awaiting_account_verification) and biometric setup happens in the portal (via awaiting_session_start).

walletPhase — Wallet Setup Detail

Method Reference

This method must be paired with para.onStatePhaseChange() to handle portal URLs that appear during authentication (verification, passkey, password, PIN). See the guide for your platform for the full state listener pattern.

Cancelling Authentication

The method accepts polling callbacks with an isCanceled function. Return true from isCanceled to stop the polling loop — for example, when the user dismisses the in-app browser or navigates away. The cancellation is clean: no error is thrown, and the optional onCancel callback is fired.
Calling para.logout() also cancels all active polling and resets the state phases back to unauthenticated. This is useful for implementing a “Cancel” button that fully resets the auth flow:

Handling Results

Next Steps