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

# Setup guide

> Step-by-step guide to implementing LearnInk in a mobile WebView

This guide walks through the steps to embed LearnInk inside your mobile app using a WebView, with seamless single sign-on via your backend.

## How the authentication model works

The WebView integration uses a short-lived **sign-in token** to authenticate a user into the LearnInk WebView without prompting for a separate username/password.

* Your **mobile app never talks to LearnInk directly** for authentication
* Your mobile app calls **your backend**
* Your backend calls LearnInk using your **API key** and gets a **token**
* Your app loads the WebView with `token=...` in the URL

This keeps your API key private and ensures users can only access LearnInk as themselves (because you control how app users map to LearnInk users).

You’ll build two things:

1. A backend endpoint that returns a short-lived LearnInk sign-in token to your app
2. A mobile WebView screen that loads LearnInk and handles post messages (close + session refresh)

***

## Before you start

Make sure you have:

* ✅ Your **org ID**
* ✅ A **LearnInk API key** stored server-side
* ✅ Access to the **staging environment** for testing

We also recommend deciding up front what you’ll use as the LearnInk user `id`:

* It should be **stable** (doesn’t change if the user updates their profile)
* It should be **unique** within your organisation
* It should not be a mutable contact detail like phone number or email (unless your system treats it as immutable)

***

## Step 1 — Create a backend “token” endpoint

Your LearnInk API key must only be used from your backend. Your mobile app should call **your** backend, and your backend should call LearnInk.

### Recommended backend contract

Expose a single endpoint in your API that returns a token for the currently authenticated app user.

Example response:

```json theme={null}
{ "token": "..." }
```

If token generation fails, return an error in your normal API format (and handle it gracefully in the app by showing a retry).

At a high level your endpoint should:

1. Authenticate the incoming request using your normal auth/session mechanism
2. Determine the caller’s user identifier (the `id` you use in your system)
3. Call the LearnInk **Identify API** to get a short-lived sign-in token
4. Return `{ "token": "..." }` to your app

<Warning>
  Do not call LearnInk directly from your mobile app. Never ship your LearnInk API key in client-side code.
</Warning>

For the full request/response schema, see the API reference:

* [Identify API reference](/api-reference/identify)

***

## Step 2 — Construct the WebView URL

The WebView URL looks like:

```
https://m.learn.ink/{orgId}/{path}?webview=true&token={token}
```

* `orgId`: your organisation ID
* `path` (optional): where the user lands (e.g. `/learning`, `/courses`)
* `webview=true`: enables WebView mode (shows a close button and enables post messages)
* `token`: the short-lived sign-in token from your backend (recommended)

<Note>
  Tokens are short-lived. Generate a fresh token whenever the user opens the WebView (and when LearnInk requests a refresh via `SESSION_EXPIRED`).
</Note>

***

## Step 3 — Implement the WebView screen

We recommend presenting LearnInk as either:

* A **full-screen modal**, or
* A **dedicated screen** in your navigation stack

Load the constructed URL in your WebView component.

### UX recommendations

* Show a loading state while the WebView is initialising
* Provide a clear way to exit (LearnInk shows an in-WebView close button; your app should also respect OS back navigation)
* Treat the LearnInk WebView as a “destination screen” to reduce nested scrolling and layout issues

***

## Step 4 — Handle post messages from LearnInk

LearnInk sends post messages to your app. You should handle:

* `CLOSE`: user tapped the close button inside the WebView
  * Dismiss the modal/screen
* `SESSION_EXPIRED`: the user’s session expired and a new token is needed
  * Call your backend to fetch a fresh token
  * Rebuild the URL and reload the WebView

### Common pitfalls

* **Caching tokens**: tokens should not be stored and reused. Fetch a fresh token for each WebView session.
* **Using contact details as IDs**: use a stable internal user ID rather than email/phone, unless those are immutable in your system.
* **Skipping request auth**: always authenticate the request from your app to your backend token endpoint.

***

## Testing checklist (recommended)

Before going live, verify:

* Opening the training entry point generates a token and loads the WebView successfully
* The close button sends `CLOSE` and your app dismisses the WebView
* Forcing a session refresh (or waiting for expiry) triggers `SESSION_EXPIRED` and your app reloads with a fresh token
* Push notification events are received and forwarded (see the push notifications guide)

<Card title="Push notifications setup guide" icon="bell" href="/integration/push-notifications" horizontal>
  Receive LearnInk notification events via webhook and forward them through your push provider.
</Card>

## Sample implementations

Use the reference implementations for your framework:

<CardGroup cols={3}>
  <Card title="React Native" icon="react" href="/integration/webview-react-native">
    JavaScript and TypeScript
  </Card>

  <Card title="Flutter" icon="mobile" href="/integration/webview-flutter">
    Dart
  </Card>

  <Card title="Kotlin" icon="android" href="/integration/webview-kotlin">
    Native Android
  </Card>
</CardGroup>
