---
title: "Fallback flows"
description: "Set up local fallback flows in Adapty to keep your flow visible when the device is offline."
---

To maintain a fluid user experience, it's important to set up **fallback versions** of your [flows](adapty-flow-builder).

When your application requests a flow, the Adapty SDK contacts our servers to fetch its configuration. If the device cannot reach Adapty (network issue, server outage), the SDK falls back to local data:

- If the user has already seen the flow once, the SDK serves the cached copy.
- If no cache exists, the SDK loads a fallback configuration file bundled inside the app.

Adapty automatically generates these fallback files. The flow fallback bundle is shared with paywalls — a single JSON file per platform contains fallback variations for both. The SDK reads whichever section it needs.

:::important
Flow fallbacks ship in the **Adapty SDK 4.0+** bundle. If you select an earlier SDK version in the download dialog, the file contains paywall and onboarding variations only — no flows. Make sure your app is on a flow-aware SDK release before relying on a flow fallback.
:::

## Before you start

1. Create a [flow](adapty-flow-builder) in the Flow Builder.
2. [Create a placement](create-placement) for the flow.

## Download the fallback file

1. Open the **[Placements](https://app.adapty.io/placements)** page.
2. Click the **Fallbacks** button at the top right.
3. Select your target platform from the dropdown.
4. Choose the SDK version that matches the one shipped in your app. Pick **Adapty SDK v4.0.0 and higher** (or a later option) to receive a bundle that includes flows.

The browser downloads a JSON file per platform — for example, `ios_4_0_0_fallback.json`.

<details>
   <summary>Example flow fallback entry (click to expand)</summary>

```json
"PLACEMENT_ID": {
  "data": [
    {
      "developer_id": "PLACEMENT_ID",
      "variation_id": "cb1c0ef8-aecd-4a53-a6f3-b98266e66884",
      "flow_id": "daf25858-3fa2-4981-8500-9c8a30e5b7e6",
      "flow_name": "FLOW_NAME",
      "flow_version_id": "FLOW_VERSION_ID",
      "placement_audience_version_id": "a9eb3ab8-3178-477d-84d4-ef9d3978e48b",
      "audience_name": "All Users",
      "ab_test_name": "",
      "cross_placement_info": null,
      "weight": 100,
      "variations": [
        {
          "variation_id": "cb1c0ef8-aecd-4a53-a6f3-b98266e66884",
          "paywall_id": "PAYWALL_ID",
          "paywall_name": "PAYWALL_NAME",
          "ab_test_name": "",
          "products": [],
          "revision": 1,
          "custom_payload": null,
          "weight": 100
        }
      ],
      "remote_configs": []
    }
  ],
  "meta": {
    "placement": {
      "developer_id": "PLACEMENT_ID",
      "is_tracking_purchases": true,
      "audience_name": "All Users",
      "placement_audience_version_id": "a9eb3ab8-3178-477d-84d4-ef9d3978e48b",
      "revision": 0,
      "ab_test_name": ""
    }
  }
}
```

The exact shape can change between SDK versions. Always use the file Adapty generated for your SDK version rather than hand-rolling one.
</details>

## After the download

Add the file to your app code, then follow the platform-specific setup guide. The same APIs that load paywall fallbacks also load flow fallbacks once your app is on a flow-aware SDK release:

- [iOS](ios-use-fallback-paywalls)

## Limitations

Fallback flows are hard-coded and locally stored, so they don't carry the full dynamic capabilities of live flows:

- **One variation per placement.** If a placement has more than one flow (different audiences, A/B test variants), the fallback file uses the variation with the highest weight, or the widest audience.
- **No A/B testing.** A live flow A/B test resolves on the server; the fallback always serves a single chosen variation.
- **No remote updates.** Updating the fallback requires a new app release. For runtime updates you'd otherwise make via remote config, push them through the live flow instead.
- **Default locale only.** The fallback uses the `en` locale; localized variants aren't bundled.