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

# Read auth state from a background process

> Use getAuthStateWithoutRefresh to safely check authentication state in background tasks and app extensions without triggering a network refresh

In a background task or app extension, triggering a network refresh is unsafe. iOS can suspend or
terminate background processes at any time, and an in-flight token refresh can be interrupted,
leaving auth state inconsistent.

`getAuthStateWithoutRefresh()` is a synchronous method that reads the cached auth state without
making any network calls. Use it any time you need to check whether a user is authenticated from
outside the main app foreground context.

## How it works

* `getAuthState() async` — the standard method. Waits for the SDK to be ready and may trigger a
  token refresh. **Do not call this from a background process.**
* `getAuthStateWithoutRefresh()` — synchronous. Reads cached state only. Safe for background
  tasks, `BGTask` handlers, background `URLSession` callbacks, and app extensions.

## Implementation

Call `getAuthStateWithoutRefresh()` on the `Privy` instance you obtained from
`PrivySdk.initialize(config:)`:

```swift theme={"system"}
// In a BGTask, background URLSession handler, or app extension:
func handleBackgroundTask() {
    let privy = // your shared Privy instance

    let authState = privy.getAuthStateWithoutRefresh()

    switch authState {
    case .authenticated(let user):
        // Safe to proceed — use user.id, user.linkedAccounts, etc.
        let linkedAccounts = user.linkedAccounts
        performBackgroundWork(for: user)

    case .authenticatedUnverified:
        // A session exists in cache but hasn't been verified with Privy's backend.
        // Defer any work that requires a valid token until the app returns to foreground.
        scheduleWorkForForeground()

    case .unauthenticated:
        // No session. Nothing to do in the background.
        break

    case .notReady:
        // SDK was never initialized in this process context.
        // Common in app extensions that share a Privy reference but never called PrivySdk.initialize.
        break
    }
}
```

## AuthState cases

| Case                       | Meaning                             | What to do                               |
| -------------------------- | ----------------------------------- | ---------------------------------------- |
| `.authenticated(user)`     | Fully verified session              | Safe to proceed with background work     |
| `.authenticatedUnverified` | Cached session, not yet verified    | Defer token-dependent work to foreground |
| `.unauthenticated`         | No session                          | Nothing to do                            |
| `.notReady`                | SDK not initialized in this process | Do not proceed                           |

## Key caveats

**Do not call `user.getAccessToken()` in a background process.** It will attempt a network refresh
and is as unsafe as `getAuthState()`. Only call it once the app has returned to the foreground.

**`.authenticatedUnverified` is the most common background case.** The user's session is present in
Keychain but hasn't been confirmed with Privy's backend. This is expected — it occurs when there is
no network connectivity or when the background task runs before a foreground refresh has completed.
Treat it as "probably logged in, verify later."

**`.notReady` indicates the SDK was never initialized** in the current process context. This is
common in app extensions that hold a reference to a `Privy` instance but never called
`PrivySdk.initialize(config:)`. Handle this case gracefully and do not attempt any SDK operations.

## Returning to the foreground

When the app returns to the foreground, verify the session and promote state from
`.authenticatedUnverified` to `.authenticated` if the session is still valid:

```swift theme={"system"}
// Call from your scene or app delegate when the app becomes active
Task {
    let authState = await privy.getAuthState()
    // authState is now verified against Privy's backend
}
```

If the device was offline, call `privy.onNetworkRestored()` to trigger re-verification once
connectivity is available.
