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

# Gating modes

> off, internal_only, and internal_and_live — what each gating mode allows, and how fast a change takes effect.

Every app has a gating mode, set from [the dashboard](/sdk/dashboard-review-tab#settings).
It's the single switch that controls whether review mode can ever activate on a device, and
on which kind of build.

| Mode                | Live (App Store) builds | Internal (TestFlight/dev) builds |
| ------------------- | ----------------------- | -------------------------------- |
| `off`               | Never activates         | Never activates                  |
| `internal_only`     | Never activates         | Activates once paired            |
| `internal_and_live` | Activates once paired   | Activates once paired            |

* **`off`** — the SDK never activates on any device, on any build. Devices can still attempt
  to pair, but pairing is denied the same way any other disallowed activation is.
* **`internal_only`** — review mode works on TestFlight and development builds, never on a
  build downloaded from the App Store.
* **`internal_and_live`** — review mode works everywhere, including builds your end users
  install from the App Store. Use this deliberately — it's the only mode where a paired
  reviewer's device keeps working after you ship to production.

## What counts as an internal build

An **internal build** is any build the SDK detects as TestFlight or a development/simulator
build, via the build's own characteristics (debug build, simulator, or a TestFlight App
Store receipt). Everything else — a build downloaded from the App Store — is a **live
build**. The SDK reports the build type it detects; the backend is what enforces the app's
gating policy against that reported type on every activation and revalidation call, so
gating is never a decision the client makes on its own.

## How fast a change takes effect

Gating is enforced **server-side**, on every activation and on every revalidation check —
never decided by the client on its own. That means changing an app's gating mode (or
revoking a device) doesn't require a new build or a client update to take effect; it takes
effect the next time each paired device checks in.

<Warning>
  Flipping an app's gating mode — including switching it to `off` — is not instant. A device
  only re-checks on its next revalidation (cold launch or app foreground), and a session
  that's already authenticated at that moment stays valid for up to its access token's
  1-hour lifetime even after that. So the real worst case is roughly an hour after the
  device next comes to the foreground — and a device that's backgrounded and never comes
  back to the foreground never re-checks at all, though its access token still expires
  naturally on its own 1-hour clock, so it can't keep authenticating indefinitely either way.
</Warning>

Internal builds get a 24-hour offline grace window and stay visible without a network
connection for up to that long after their last successful check; live (App Store) builds
don't — see [Troubleshooting](/sdk/troubleshooting#comments-not-syncing) for what that looks
like in practice.
