> ## Documentation Index
> Fetch the complete documentation index at: https://otpless.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# React Native SDK

> Integrate the OTPless Headless SDK in React Native for the authentication flow — add the dependency, initialize, start with a requestId, and handle callbacks.

This page covers the integration of the OTPless Headless SDK in React Native. The SDK accepts the `requestId` generated by the [Create API](/docs/server-initiated-auth/create-api), performs the authentication, and reports progress through callbacks. Your backend confirms the final result via the [Status Check API](/docs/server-initiated-auth/status-check-api).

## Requirements

| Requirement | Version |
| - | - |
| React Native | 0.64+ |
| Android Minimum SDK | 21 |
| iOS | 13.0+ |

## Step 1: Add SDK dependency

Install the OTPLESS Headless SDK at the root of your React Native project:

```bash theme={null}
npm i otpless-headless-rn
```

For iOS, install the pods:

```bash theme={null}
cd ios && pod install
```

<Note>
  Check the latest version of the [SDK on npm](https://www.npmjs.com/package/otpless-headless-rn).
</Note>

<Warning>
  Make sure your authentication channel is enabled on the [OTPLESS dashboard](https://otpless.com/dashboard/customer/channels).
</Warning>

## Step 2: Initialize the SDK

Create a `OtplessHeadlessModule` instance, initialize it with your App ID, and register the response callback:

```typescript theme={null}
import { OtplessHeadlessModule } from 'otpless-headless-rn';

const headlessModule = new OtplessHeadlessModule();

useEffect(() => {
    headlessModule.initialize("YOUR_APP_ID");
    headlessModule.setResponseCallback(onHeadlessResponse);
    return () => {
        headlessModule.clearListener();
        headlessModule.cleanup();
    };
}, []);
```

<Note>
  Replace `YOUR_APP_ID` with your actual App ID from the [OTPLESS dashboard](https://dashboard.otpless.com/login).
</Note>

## Step 3: Start authentication with the requestId

Pass the `requestId` returned by the [Create API](/docs/server-initiated-auth/create-api) to `start()`:

```typescript theme={null}
const headlessRequest = {
    requestId: "REQUEST_ID_FROM_API"
};

headlessModule.start(headlessRequest);
```

<Note>
  Start polling the [Status Check API](/docs/server-initiated-auth/status-check-api) from your backend immediately after calling `start()`. The SDK callback and the server status run in parallel.
</Note>

## Step 4: Handle callbacks

```typescript theme={null}
const onHeadlessResponse = (response: any) => {
    headlessModule.commitResponse(response);

    switch (response.responseType) {
        case "SDK_READY": {
            // SDK initialized successfully — enable your continue button
            // or proceed with user authentication.
            break;
        }
        case "FAILED": {
            // SDK initialization failed
            if (response.statusCode === 5003) {
                // Please try to initialize the SDK again.
            }
            break;
        }
        case "INITIATE": {
            // Authentication has been initiated
            if (response.statusCode !== 200) {
                handleInitiateError(response);
            } else {
                // Authentication is in progress — show a loading state.
            }
            break;
        }
        case "VERIFY": {
            // Verification failed for the attempted authentication.
            if (response.statusCode === 9106) {
                // Verification timed out — treated as AUTH_TERMINATED.
            }
            break;
        }
        case "ONETAP": {
            // Final success response — returns token / idToken
            break;
        }
        case "AUTH_TERMINATED": {
            // Auth could not complete. Emitted when pre-checks fail,
            // or when authentication was attempted and then failed.
            // Treat as a terminal failure and rely on the Status Check API
            // for the exact error.
            break;
        }
    }
};
```

## Callback reference

The SDK works in two steps — initialization and `start()` — and each step has its own set of callbacks.

#### Step 1: Initialization callbacks

Emitted when you initialize the SDK (Step 2).

| Callback | Meaning |
| - | - |
| `SDK_READY` | SDK initialization completed. |
| `FAILED` | SDK failed to initialize (e.g. `statusCode 5003`). |

#### Step 2: Start callbacks

Emitted after you invoke `start()` (Step 3).

| Callback | State | Meaning |
| - | - | - |
| `INITIATE` | Non-terminal | Authentication is in progress after pre-checks pass. |
| `VERIFY` | Non-terminal | Verification failed for the attempted authentication (e.g. `statusCode 9106` on timeout). |
| `ONETAP` | **Success — terminal** | Authentication completed successfully. Returns `token` / `idToken`. |
| `AUTH_TERMINATED` | **Failed — terminal** | Emitted in two cases: (1) pre-checks failed → terminated directly; (2) authentication was initiated and then failed. |

<Warning>
  `AUTH_TERMINATED` is a terminal failure. Always treat the [Status Check API](/docs/server-initiated-auth/status-check-api) result as authoritative.
</Warning>

<Note>
  For the `errorCode` / `statusCode` values surfaced in SDK callbacks, see [SDK Error Codes](/docs/server-initiated-auth/sdk-error-codes).
</Note>

## Next step

<Card title="Status Check API" icon="circle-check" href="/docs/server-initiated-auth/status-check-api">
  Confirm the authoritative auth status from your server.
</Card>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.