Returning.AIDevelopers
v1

Guides / Mobile Widget SDKs

.md

Mobile Widget SDKs

Authentication

The mobile app obtains a short-lived embed token from its own trusted backend. Returning.AI access credentials never enter the app.

Server-authenticated mobile widget

The native SDK owns the widget exchange while your backend owns customer identity and long-lived credentials.

  1. Request an embed token

    Signed-in mobile app

    Call your own authenticated backend. Do not send a customer identifier selected by an untrusted app screen.

  2. Read the current host session and map it to the identifiers configured for the target Returning.AI widget.

  3. Mint the embed token

    Your backend and Returning.AI

    Use server-only access credentials to call the Returning.AI token endpoint and return only the short-lived embed token.

  4. Exchange inside the native SDK

    Mobile Widget SDK

    The provider supplies the embed token. The SDK authenticates the configured widget with its exact clientOrigin.

  5. Deliver the access token

    SDK-owned WebView

    The WebView receives only the exchanged access token and expiry. The embed token does not cross the bridge.

Mint the token on your backend

Your backend calls the Returning.AI endpoint after it has authenticated the app user. Replace the example identifier with the configured mapping for that widget.

your-server-to-returning.http
POST https://api-v2.returning.ai/v2/api/widget-access-keys/token
Content-Type: application/json

{
  "accessId": "SERVER_ACCESS_ID",
  "accessKey": "SERVER_ACCESS_KEY",
  "userIdentifiers": {
    "data-customer-id": "VALUE_FROM_TRUSTED_HOST_SESSION"
  }
}

// Returning.AI response:
// { "data": { "embedToken": "...", "expiresIn": 900 } }

Flatten the successful upstream response for the app. Keep the response non-cacheable and return safe errors without upstream bodies or credentials.

your-server-to-app.http
200 OK
Cache-Control: no-store
Content-Type: application/json

{
  "embedToken": "SHORT_LIVED_TOKEN",
  "expiresIn": 900
}

Connect the token provider

Each platform exposes the same asynchronous provider contract using its native language:

Flutter
Future<String> Function()
Android
suspend fun invoke(): String
iOS
@Sendable () async throws → String
React Native
() → Promise<string>

Allow the exact client origin

clientOrigin is an HTTPS origin without a path, query, or fragment. It is configured per widget. Another widget working with the same origin does not prove this widget is allowlisted.

An allowlist miss normally returns 403 Domain not authorized during native authentication and may appear as a WebView HTTP 502.

Return a fresh token after expiry

When the widget session expires, the SDK clears its native access-token cache. The next authentication request calls the provider again. Fetch a new embed token from your backend instead of returning a cached value.

Continue with a platform guide: Flutter, Android, iOS, or React Native.