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

# EntitlementScope

> Control which entitlements to check — and understand provisional vs verified grants

## Overview

`EntitlementScope` determines which set of entitlements [`isActive()`](./is-active) inspects. It exists because Encore grants entitlements in **two phases** — a fast provisional grant for instant UX, followed by a backend-verified grant for correctness.

## Definition

```swift theme={null}
public enum EntitlementScope: Sendable {
    case verified
    case all
}
```

## Two-phase entitlements (provisional vs verified)

When a user completes an offer, the entitlement doesn't appear all at once:

1. **Provisional** — granted immediately so the user sees their reward without waiting. With the default [`UnlockMode.optimistic`](./configure#unlock-mode), this happens the moment the user returns from the offer flow. **A provisional grant can later be revoked** if the backend can't verify the underlying transaction (e.g. the purchase was refunded, fraudulent, or never confirmed).
2. **Verified** — granted once the backend confirms the transaction (via the App Store Server Notification webhook). A verified grant is durable.

### How each scope reads the two phases

| Scope            | What it inspects                                                                                                                       | Returns `true` for a provisional grant? |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| `.all` (default) | The merged set of everything currently granted to the user — provisional **and** verified. Broadest and fastest.                       | Yes                                     |
| `.verified`      | The provisional set **or** the verified set, triggering a smart refresh when a provisional grant nears expiry to pick up verification. | Yes                                     |

<Note>
  Both scopes surface provisional grants — neither is "verified-only." The difference is that `.verified` actively refreshes against the backend's verified set as provisional grants age, making it the right scope to drive toward a confirmed outcome. Use it when you want the SDK to chase verification; use `.all` for the cheapest "did the user just earn something" check.
</Note>

### Which scope should I gate on?

* **Reversible / instant UX** — unlocking a screen, flipping a "premium" badge, hiding an upsell. Gate on **`.all`**. If a provisional grant is later revoked, you simply re-lock the UI; nothing was lost.

  ```swift theme={null}
  if await Encore.shared.isActive(.freeTrial(), in: .all) {
      showPremiumTab()   // safe to reverse later
  }
  ```

* **Irreversible / expensive grants** — minting durable credits, shipping a physical reward, writing a permanent server-side flag. Prefer **`.verified`** so the SDK is driving toward (and refreshing against) the backend's confirmed state before you commit. For grants you can never take back, wait until verification actually lands rather than acting on the first provisional signal.

  ```swift theme={null}
  if await Encore.shared.isActive(.credit(), in: .verified) {
      grantDurableCredits()   // only after verification
  }
  ```

### When verification fails

A provisional grant that the backend can't verify is **revoked** — the entitlement disappears from both scopes. To react in real time, subscribe with [`isActivePublisher(for:in:)`](./is-active-publisher) and re-lock whatever you optimistically unlocked:

```swift theme={null}
Encore.shared
    .isActivePublisher(for: .freeTrial, in: .all)
    .sink { isActive in
        isActive ? showPremiumTab() : hidePremiumTab()
    }
    .store(in: &cancellables)
```

If you only ever want to act on confirmed grants — never on provisional ones that might be revoked — configure the SDK with [`UnlockMode.strict`](./configure#unlock-mode), which withholds the grant until the advertiser postback verifies the conversion.

## Related

* [`isActive()`](./is-active) — query a scope once.
* [`isActivePublisher()`](./is-active-publisher) — observe a scope reactively.
* [`configure()` → Unlock mode](./configure#unlock-mode) — choose optimistic vs strict granting.
