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

# Mobile SDKs (iOS, Android, Flutter)

> How the native Authmatech mobile SDKs run silent verification on the device, register a session, and hand off to your backend — for iOS, Android, and Flutter.

The native Authmatech mobile SDKs run silent verification directly on the device, over the customer's **mobile-data** connection, for the highest match rates. The SDK confirms the number with the mobile network in the background, registers a session with Authmatech, and returns a short-lived identity result your backend uses to complete the verification. Your **server-side API key never goes in the app**.

<Note>
  The iOS, Android, and Flutter SDKs share the same integration model and method names, so the steps below apply to all three — the snippets differ only in language. Native packages are provisioned per integration: contact [connect@authmatech.com](mailto:connect@authmatech.com) or your solutions engineer for the package, your `clientId`, your `sdkToken`, and the verification URL for your account.
</Note>

## The model

Regardless of platform, the flow is the same four steps:

<Steps>
  <Step title="Initialize">
    Configure the SDK with your `backendBaseURL`, your public `clientId`, and a `sdkToken`. The `sdkToken` is a narrow-scoped, app-safe credential — it can only register sessions and can never call the server APIs. The server API key is never embedded in the app.
  </Step>

  <Step title="Run the silent check over mobile data">
    The SDK opens the verification URL issued for your account over the device's mobile-data connection. The mobile network silently confirms the number, and the SDK receives an encrypted identity code (`authmatechCode`) plus the operator id (`MNOID`).
  </Step>

  <Step title="Register the session">
    The SDK calls [`POST /v1/api/sdk/session`](/api/overview) with the `X-SDK-TOKEN` and `X-CLIENT-ID` headers and gets back an `sdkSessionId`. This happens automatically inside the SDK.
  </Step>

  <Step title="Verify on your backend">
    Your app forwards `authmatechCode`, `MNOID`, and `sdkSessionId` to **your** backend, which calls [`POST /v1/api/verify`](/guides/verify) with the `X-API-KEY`. Map `authmatechCode → encryptedMobileNumber` and `MNOID → operatorId`.
  </Step>
</Steps>

<Warning>
  The result fields are sensitive. Forward `authmatechCode` to your backend over TLS only — never log it, cache it, or render it in the UI.
</Warning>

## Install & integrate

<Tabs>
  <Tab title="iOS">
    **Requirements:** iOS 12.0+, Swift 5.3+.

    **Swift Package Manager** — add the package in Xcode (**File → Add Package Dependencies**) or in `Package.swift`:

    ```swift theme={null}
    dependencies: [
      .package(url: "https://github.com/authmatech/authmatech-sdk-ios.git", from: "1.0.8")
    ]
    ```

    **CocoaPods:**

    ```ruby theme={null}
    pod 'authmatech-sdk-ios', :git => 'https://github.com/authmatech/authmatech-sdk-ios.git', :tag => '1.0.8'
    ```

    **Initialize once at app startup:**

    ```swift theme={null}
    import AuthmatechSDK

    AuthmatechSDK.initialize(
      config: AuthmatechSDKConfig(
        backendBaseURL: URL(string: "https://service.authmatech.com")!,
        clientId: "YOUR_CLIENT_ID",
        sdkToken: "YOUR_SDK_TOKEN"   // app-safe; never your API key
      )
    )
    ```

    **Run a verification** — `openWithDataCellular` forces the request over the mobile-data connection and returns the result on the main callback:

    ```swift theme={null}
    let verificationUrl = URL(string: "https://verify.authmatech.com/check")! // provided by Authmatech

    AuthmatechSDK.getInstance().openWithDataCellular(url: verificationUrl, debug: false) { result in
      if let error = result["error"] as? String {
        // no result — route to a fallback (manual entry / retry on mobile data)
        return
      }

      guard
        let authmatechCode = result["authmatechCode"] as? String,
        let mnoId          = result["MNOID"] as? String,
        let sdkSessionId   = result["sdkSessionId"] as? String
      else { return }

      // Forward to YOUR backend over TLS — never call Verify from the app.
      sendToYourBackend(authmatechCode: authmatechCode,
                        mnoId: mnoId,
                        sdkSessionId: sdkSessionId,
                        mobileNumber: enteredMobileNumber)
    }
    ```
  </Tab>

  <Tab title="Android">
    **Requirements:** Android 8.0 (API 26)+.

    Add the dependency (exact coordinates are provided with your package):

    ```groovy theme={null}
    dependencies {
      implementation 'com.authmatech.sdk:authmatech-sdk-android:1.0.0'
    }
    ```

    **Initialize** the SDK with your context and the same `clientId` / `sdkToken`, then run the check. The API mirrors iOS:

    ```kotlin theme={null}
    import com.authmatech.sdk.AuthmatechSDK
    import java.net.URL

    // Initialize once (e.g. in Application.onCreate)
    AuthmatechSDK.initializeSdk(context)

    val verificationUrl = URL("https://verify.authmatech.com/check") // provided by Authmatech

    val result = AuthmatechSDK.getInstance()
      .openWithDataCellular(verificationUrl, debug = false) // JSONObject

    val authmatechCode = result.optString("authmatechCode")
    val mnoId          = result.optString("MNOID")
    val sdkSessionId   = result.optString("sdkSessionId")

    // Forward authmatechCode, MNOID, sdkSessionId + the entered number to YOUR backend.
    ```

    <Note>
      Run `openWithDataCellular` off the main thread — it performs network I/O. The result keys (`authmatechCode`, `MNOID`, `sdkSessionId`) and the backend hand-off are identical to iOS.
    </Note>
  </Tab>

  <Tab title="Flutter">
    The Flutter SDK wraps the same native behavior behind one method, so the integration mirrors iOS and Android. The package is provisioned per integration — contact [connect@authmatech.com](mailto:connect@authmatech.com) for the plugin and your credentials.

    ```dart theme={null}
    import 'package:authmatech_sdk/authmatech_sdk.dart';

    // Initialize once at startup
    await AuthmatechSdk.initialize(
      backendBaseURL: 'https://service.authmatech.com',
      clientId: 'YOUR_CLIENT_ID',
      sdkToken: 'YOUR_SDK_TOKEN', // app-safe; never your API key
    );

    // Run a verification over mobile data
    final result = await AuthmatechSdk.openWithDataCellular(
      url: 'https://verify.authmatech.com/check', // provided by Authmatech
    );

    final authmatechCode = result['authmatechCode'];
    final mnoId          = result['MNOID'];
    final sdkSessionId   = result['sdkSessionId'];

    // Forward those + the entered number to YOUR backend, which calls Verify.
    ```
  </Tab>
</Tabs>

## The result

A successful call returns three values your integration uses:

| Field            | Maps to (Verify API)    | Use it for                                                                                                                                                               |
| ---------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `authmatechCode` | `encryptedMobileNumber` | The encrypted identity code your backend submits to Verify. Sensitive — forward over TLS only.                                                                           |
| `MNOID`          | `operatorId`            | The mobile operator that confirmed the session.                                                                                                                          |
| `sdkSessionId`   | `sdkSessionId`          | Links the verification to the registered session so [Shield](/guides/trust-shield-detect) and [Detect](/guides/trust-shield-detect) can reason about the device context. |

## Why native over the browser

* **Higher match rates** — a native app can prefer the cellular interface even when Wi-Fi is connected.
* **Richer device signals** — platform, OS, model, and integrity flags feed directly into [Shield](/guides/trust-shield-detect) and [Detect](/guides/trust-shield-detect).

## Error handling & fallback

Silent verification needs an active **mobile-data** connection. On Wi-Fi, VPN, or some roaming networks it can't complete, and the SDK returns an error instead of a result. Catch it and route the customer to a fallback — manual entry or retry on mobile data — never back to an SMS OTP.

| Error code                        | Meaning                                                             |
| --------------------------------- | ------------------------------------------------------------------- |
| `sdk_no_data_connectivity`        | No mobile-data connection (e.g. Wi-Fi only, data off)               |
| `sdk_connection_error`            | The mobile-data connection could not be established or was lost     |
| `sdk_network_error`               | A network-level failure occurred before a result was returned       |
| `sdk_no_he_result`                | The network identity wasn't returned (often Wi-Fi/VPN)              |
| `sdk_invalid_response`            | The verification response could not be parsed                       |
| `sdk_session_registration_failed` | The session couldn't be registered (verification can still proceed) |
| `sdk_redirect_error`              | An invalid redirect, or too many redirects                          |
| `invalid_scheme`                  | The verification URL must use `https`                               |

<Note>
  If session registration fails, the SDK still returns the result so verification can continue — the linked device signals simply degrade gracefully.
</Note>

## Related

<CardGroup cols={2}>
  <Card title="Web SDK reference" icon="js" href="/sdks/web">
    The browser flow with `authmatech-sdk-web`.
  </Card>

  <Card title="API: register an SDK session" icon="code" href="/api/overview">
    The endpoint the SDK registers against.
  </Card>
</CardGroup>
