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

# Session Management

> Reference for managing OneSDK sessions

## Overview

The Session API provides methods to access and manage session information after SDK initialization. Session data includes entity identifiers, session tokens, and metadata that persists throughout the verification flow.

## Accessing the Session

The session is available through the SDK context after initialization:

```javascript theme={null}
const oneSDKInstance = await OneSdk({
  mode: 'production',
  session: { token: 'your-token' }
});

// Access session methods
const sessionId = oneSDKInstance.session.getSessionId();
```

## Methods

### `getSessionId()`

Returns the current session identifier.

**Signature:**

```typescript theme={null}
getSessionId(): string
```

**Returns:** `string` - The unique session ID generated when the session was created.

**Description:**
The session ID is a unique identifier for this verification session. It's used internally by the SDK to maintain state and can be included in support requests or logs to help trace issues. This ID remains constant throughout the session lifecycle.

**Example:**

```javascript theme={null}
const sessionId = oneSDKInstance.session.getSessionId();
console.log('Session ID:', sessionId);

// Use in support requests or logs
console.log('Support ID:', sessionId);
```

***

### `getEntityId()`

Returns the entity ID associated with this session, if available.

**Signature:**

```typescript theme={null}
getEntityId(): string | null
```

**Returns:** `string | null` - The entity ID representing the individual or business being verified, or `null` if not yet assigned.

**Description:**
The entity ID uniquely identifies the person or business undergoing verification in your system. It's typically set when the session is created on your backend and links the SDK session to a profile in the Frankie platform. Returns `null` if the session hasn't been associated with an entity yet (e.g., during initial setup or before verification begins).

**Use Cases:**

* Reference the entity when calling backend APIs
* Track entity across multiple verification sessions

**Example:**

```javascript theme={null}
const entityId = oneSDKInstance.session.getEntityId();
if (entityId) {
  console.log('Entity ID:', entityId);
  // Fetch data from your backend API using entityId
  const userData = await fetch(`/api/users/${entityId}`).then(r => r.json());
} else {
  console.log('No entity associated yet');
}
```

***

### `getReference()`

Returns the reference identifier for this session.

**Signature:**

```typescript theme={null}
getReference(): string | null
```

**Returns:** `string | null` - A custom reference string you provided when creating the session, or `null` if no reference was set.

**Description:**
The reference is an optional custom identifier you can set when generating the session token on your backend. It allows you to link the OneSDK session to your own internal reference system (e.g., application ID, customer ID, transaction ID). This is particularly useful for correlating verification sessions with records in your own database.

**Example:**

```javascript theme={null}
const reference = oneSDKInstance.session.getReference();
if (reference) {
  console.log('Application Reference:', reference);
  // Look up application in your system
  const application = await getApplicationByReference(reference);
} else {
  console.log('No reference set');
}
```

***

### `isPersisted()`

Checks whether the session token was loaded from storage (persisted from a previous initialization).

**Signature:**

```typescript theme={null}
isPersisted(): boolean
```

**Returns:** `boolean` - `true` if the session was restored from browser storage, `false` if it's a newly created session.

**Description:**
When you initialize the SDK with `persist: true`, the session token is stored in browser storage (localStorage or sessionStorage). On subsequent page loads or SDK initializations, the SDK automatically checks for and restores the stored token. This method tells you whether the current session is a restored one or a freshly created one.

**Use Cases:**

* Determine if a user is resuming a previous verification session
* Show different UI for new vs. returning users
* Track session continuity for analytics
* Decide whether to show onboarding instructions

**Example:**

```javascript theme={null}
if (oneSDKInstance.session.isPersisted()) {
  console.log('Welcome back! Resuming your verification...');
  // Skip onboarding, go directly to where they left off
  resumeVerification();
} else {
  console.log('Starting new verification session');
  // Show onboarding/instructions
  showWelcomeScreen();
}
```

***

### `unpersist()`

Removes the session token from storage. After calling this, the next SDK initialization will not reuse the stored token.

**Signature:**

```typescript theme={null}
unpersist(): void
```

**Returns:** `void` - No return value.

**Description:**
Removes the currently persisted session token from browser storage. This is important for security and user privacy - always call this method when:

* User logs out
* User explicitly ends their verification session
* Session expires or becomes invalid
* User switches accounts

After calling `unpersist()`, the next SDK initialization will require a fresh token (it won't automatically restore the old one).

**Important:** This only removes the token from storage; it doesn't invalidate the session on the server. The session remains valid until it expires or is explicitly invalidated via your backend.

**Example:**

```javascript theme={null}
function handleLogout() {
  // Clear persisted session from browser storage
  oneSDKInstance.session.unpersist();
  console.log('Session cleared from storage');

  // Also invalidate on backend (optional but recommended)
  await revokeSessionOnBackend(sessionId);

  // Redirect to login
  window.location.href = '/login';
}
```

***

### `getFrankie2customer()`

Returns the frankie2customer flag value.

**Signature:**

```typescript theme={null}
getFrankie2customer(): boolean | undefined
```

**Returns:** `boolean | undefined` - The frankie2customer flag value, or `undefined` if not set.

**Description:**
Internal flag that indicates whether this session uses the Frankie v2 API. This is used in specific integration scenarios for customers using the v2 API.

**Note:** This is primarily for internal use and specific partnership integrations. Standard SDK implementations typically don't need to check this value.

**Example:**

```javascript theme={null}
const isFrankie2customer = oneSDKInstance.session.getFrankie2customer();
if (isFrankie2customer) {
  console.log('Using Frankie v2 API');
} else {
  console.log('Standard API integration');
}
```

***

### `getExtraData()`

Returns additional session metadata that may include document requirements and configuration.

**Signature:**

```typescript theme={null}
getExtraData(): {
  linkExpiry?: string;
  [key: string]: any;
}
```

**Returns:** Object with optional properties containing session metadata. All properties are optional and may be `undefined`.

**Description:**
Extra data contains session-specific metadata that can be set when generating the session token on your backend. This is particularly useful for scenarios where you need to pass custom configuration or context to the SDK.

**Properties:**

| Property      | Type                  | Description                                                                                                                                |
| ------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `linkExpiry`  | `string \| undefined` | Session link expiration timestamp or date string. Format depends on your backend implementation (could be ISO 8601, Unix timestamp, etc.). |
| Custom fields | `any`                 | Additional custom metadata fields that you set when generating the session token on your backend.                                          |

**Example:**

```javascript theme={null}
const extraData = oneSDKInstance.session.getExtraData();

if (extraData.linkExpiry) {
  console.log('Session expires:', extraData.linkExpiry);
  // Parse and show expiration warning
  const expiryDate = new Date(extraData.linkExpiry);
  if (expiryDate < new Date()) {
    showExpiryWarning();
  }
}

// Access custom metadata if you set any
if (extraData.customField) {
  console.log('Custom data:', extraData.customField);
}
```

***

### `getExpirationEpoch()`

Returns the session expiration time as a Unix epoch timestamp.

**Signature:**

```typescript theme={null}
getExpirationEpoch(): number
```

**Returns:** `number` - Unix timestamp in **seconds** since epoch (January 1, 1970 00:00:00 UTC).

**Description:**
Every session has an expiration time after which it becomes invalid. This method returns the exact timestamp when the session expires. You should monitor this value to warn users before expiration or to refresh sessions proactively.

**Important:** The returned value is in **seconds**, not milliseconds. When using with JavaScript `Date`, multiply by 1000: `new Date(epoch * 1000)`.

**Use Cases:**

* Display countdown timer to users
* Warn users before session expires
* Automatically refresh/extend sessions
* Determine if session is still valid

**Example:**

```javascript theme={null}
const expirationEpoch = oneSDKInstance.session.getExpirationEpoch();

// Convert to JavaScript Date (note: multiply by 1000)
const expirationDate = new Date(expirationEpoch * 1000);
console.log('Session expires at:', expirationDate.toLocaleString());

// Check if session is expired
const now = Date.now();
const isExpired = now > (expirationEpoch * 1000);

if (isExpired) {
  console.warn('Session has expired!');
  handleExpiredSession();
} else {
  // Calculate time remaining
  const timeRemaining = (expirationEpoch * 1000) - now;
  const minutesRemaining = Math.floor(timeRemaining / 60000);

  console.log(`Session expires in ${minutesRemaining} minutes`);

  // Warn if less than 5 minutes remaining
  if (minutesRemaining < 5) {
    showExpirationWarning(`Your session will expire in ${minutesRemaining} minutes`);
  }
}
```

## Session Persistence

When initializing the SDK with `persist: true`, the session token is stored in browser storage. On subsequent initializations, the stored token takes priority if valid.

**Important:** Even with `persist: true`, you must still provide a token in the `session.token` parameter. The SDK will:

1. Check if a valid stored token exists
2. If yes and the stored token is valid, **use the stored token** (it takes priority over the provided token)
3. If no stored token or stored token is invalid, use the provided token and store it

A stored token is considered **invalid** if it has a different entity ID, a different customer reference, or has expired. Invalid tokens are rejected gracefully — a `warning` event is emitted, and the SDK falls back to the provided token. No error is thrown.

<Warning>
  **No token refresh mechanism.** If a session expires mid-flow, there is no way to refresh it. The user must restart the verification flow with a new token obtained from your backend. To avoid this, monitor `getExpirationEpoch()` and warn users before their session expires.
</Warning>

### Enable Persistence

```javascript theme={null}
// First initialization - token is stored
const oneSDKInstance = await OneSdk({
  mode: 'production',
  session: {
    token: 'your-token',  // Required - will be stored
    persist: true
  }
});

// Subsequent initialization - stored token is used if valid
const oneSDKInstance = await OneSdk({
  mode: 'production',
  session: {
    token: 'new-token',  // Required but may not be used if stored token is valid
    persist: true
  }
});
```

### Check and Clear Persistence

```javascript theme={null}
// Check if current session is persisted
if (oneSDKInstance.session.isPersisted()) {
  console.log('This session was restored from storage');

  // Clear it when done (e.g., on logout)
  oneSDKInstance.session.unpersist();
}
```

### Use Cases for Persistence

**When to enable:**

* Multi-page flows where users navigate between pages
* Resumable verification processes
* Saving progress across browser refreshes

**When to disable:**

* One-time verification flows
* Public/shared device scenarios
* When security requires fresh sessions each time

## Complete Example

Here's a comprehensive example showing session management in a verification flow:

```javascript theme={null}
import OneSdk from '@frankieone/one-sdk';

async function initializeVerification() {
  try {
    // Initialize SDK
    const sdk = await OneSdk({
      mode: 'production',
      session: {
        token: await fetchTokenFromBackend(),
        persist: true,
        appReference: 'my-app-v1.0.0'
      }
    });

    // Log session information
    console.log('Session initialized:', {
      sessionId: sdk.session.getSessionId(),
      entityId: sdk.session.getEntityId(),
      reference: sdk.session.getReference(),
      isPersisted: sdk.session.isPersisted(),
      expiresAt: new Date(sdk.session.getExpirationEpoch() * 1000)
    });

    // Check extra data for custom metadata
    const extraData = sdk.session.getExtraData();
    if (extraData.linkExpiry) {
      console.log('Session link expires:', extraData.linkExpiry);
    }

    // Monitor session expiration
    const expirationEpoch = sdk.session.getExpirationEpoch();
    const timeUntilExpiry = (expirationEpoch * 1000) - Date.now();

    if (timeUntilExpiry < 5 * 60 * 1000) {
      console.warn('Session expires in less than 5 minutes');
    }

    // Set up expiration warning
    setTimeout(() => {
      alert('Your session is about to expire. Please complete verification soon.');
    }, timeUntilExpiry - (2 * 60 * 1000)); // Warn 2 minutes before expiry

    return sdk;

  } catch (error) {
    console.error('Failed to initialize:', error);
    throw error;
  }
}

function logout(sdk) {
  // Clear persisted session on logout
  sdk.session.unpersist();
  console.log('Session cleared');
}

// Initialize
const sdk = await initializeVerification();

// Later, on logout
logout(sdk);
```

## Session Lifecycle

```mermaid theme={null}
sequenceDiagram
    participant Backend
    participant App
    participant SDK
    participant Storage

    App->>Backend: Request session token
    Backend->>App: Return token
    App->>SDK: Initialize with token (persist: true)
    SDK->>Storage: Store token
    SDK->>App: Return SDK context

    Note over App,SDK: User navigates away / refreshes page

    App->>SDK: Initialize (with token, persist: true)
    SDK->>Storage: Check for stored token
    Storage->>SDK: Return stored token
    SDK->>SDK: Validate stored token (expiry, entityId, reference)
    alt Stored token valid
        SDK->>App: Return SDK context (isPersisted: true, uses stored token)
    else Stored token invalid
        SDK->>Storage: Store new token
        SDK->>App: Return SDK context (isPersisted: false, uses provided token)
    end

    App->>SDK: session.unpersist()
    SDK->>Storage: Remove token
```

## Best Practices

1. **Always check expiration**: Monitor `getExpirationEpoch()` and warn users before their session expires. There is no refresh mechanism — expired sessions require a new token and the user must restart the flow.

2. **Clear sessions on logout**: Call `unpersist()` when users log out to prevent session reuse.

3. **Log session IDs for debugging**: Include `getSessionId()` in error reports to help support teams.

4. **Use appReference**: Set a meaningful `appReference` during initialization for better tracking.

5. **Handle missing entity IDs**: `getEntityId()` may return null before verification completes.

6. **Validate extra data**: Always check if extra data properties exist before using them.

## Common Issues

### Session expires during verification

There is no token refresh mechanism. If the session expires mid-flow, the user must restart with a new token. Proactively warn users before their session expires to avoid losing progress:

```javascript theme={null}
const expirationEpoch = sdk.session.getExpirationEpoch();
const timeLeft = (expirationEpoch * 1000) - Date.now();
const fiveMinutes = 5 * 60 * 1000;

if (timeLeft < 0) {
  // Already expired — the user must start over
  showMessage('Your session has expired. Please start the verification process again.');
  redirectToStart();
} else if (timeLeft < fiveMinutes) {
  // Expiring soon — warn the user
  showWarning(`Your session will expire in ${Math.floor(timeLeft / 60000)} minutes.`);
}
```

### Persisted session not working

Ensure your app has the necessary storage permissions and isn't running in private/incognito mode:

```javascript theme={null}
try {
  const sdk = await OneSdk({
    session: { token: 'token', persist: true }
  });
} catch (error) {
  if (error.message.includes('storage')) {
    console.warn('Session persistence not available');
    // Fall back to non-persistent mode
  }
}
```

## Related

* [SDK Initialization](/docs/sdk-reference/sdk-initialization)
* [Event System](/docs/sdk-reference/events)
* [Error Handling](/docs/sdk-reference/error-handling)
