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

# How FlowPilot works

> The parts of the platform and how a flow travels from the editor to a device.

FlowPilot has a few moving parts. This page explains what each one does, then traces the path a flow takes from the moment you design it to the moment a user sees it on their phone.

## The parts of the platform

There are three pieces you work with:

* **Dashboard and Flow Editor** (web): where you design flows, manage placements, and run experiments. This is where flow builders spend their time.
* **Backend** (hosted by FlowPilot): stores your flows, decides which flow to serve for a given placement and user, and ingests analytics events. You rarely call it directly.
* **A FlowPilot SDK**: you add this to your app. It asks the backend what to show, then renders the flow natively on device. FlowPilot ships two SDKs that behave the same way: the [iOS SDK](/ios-sdk/index) (Swift) and the [Expo SDK](/expo-sdk/index) (React Native).

You design in the dashboard, the backend stores and serves, and the SDK renders. You do not write rendering code for each flow. The SDK draws whatever the editor produced, using native views (no web view).

## The data model

Everything in FlowPilot is scoped like this:

```text theme={null}
workspace -> app -> flow / placement / experiment
```

* **Workspace**: your organization. One workspace maps to one Clerk organization.
* **App**: one platform target inside a workspace, for example your iOS or Android app. An app owns its own flows, placements, and experiments. Each app has an **App ID** the SDK needs at launch.
* **Flow**: an ordered set of screens plus logic. A flow has versions. You publish a version to make it servable.
* **Placement**: a named trigger point in your app, for example `onboarding`. Your app asks the SDK about a placement, and the backend decides which flow, if any, to return.
* **Experiment**: an A/B test attached to a placement. It splits traffic across variants, each pointing at a different flow version.

See [Core concepts](/get-started/core-concepts) for the full vocabulary.

## The lifecycle of a flow

<Steps>
  <Step title="Build in the editor">
    Design the screens and logic in the Flow Editor, in either [Simple or Advanced mode](/editor/editing-modes).
  </Step>

  <Step title="Publish a version">
    Publishing freezes the current design as a numbered version. A draft is never served.
  </Step>

  <Step title="Attach to a placement">
    Point a placement at the published version. Optionally put the placement behind an experiment so different users get different versions.
  </Step>

  <Step title="App asks the SDK">
    Your app calls the SDK with the placement key, for example `onboarding`.
  </Step>

  <Step title="The backend resolves the flow">
    The SDK sends a resolve request. The backend applies audience targeting and any experiment assignment, then returns the matching flow (or nothing).
  </Step>

  <Step title="The SDK renders natively">
    The SDK draws the flow on device using native views.
  </Step>

  <Step title="Interactions emit events">
    As the user moves through the flow, the SDK sends analytics events (screen views, completions, conversions) back to the backend.
  </Step>
</Steps>

### Diagram

```mermaid theme={null}
flowchart LR
    A[Design in<br/>Flow Editor] --> B[Publish<br/>a version]
    B --> C[Attach to<br/>a placement]
    C --> D[App calls SDK<br/>with placement key]
    D --> E[Backend resolves:<br/>audience + experiment]
    E --> F[SDK renders<br/>natively on device]
    F --> G[Interactions emit<br/>analytics events]
    G -.-> E
```

## Flows update over the air

Because the SDK fetches flows at runtime, republishing a flow changes what users see without an App Store release. Edit the copy on a screen, publish, and the next resolve serves the new version.

<Note>
  Over-the-air updates are subject to caching. The SDK caches resolved flows (5 minutes in production by default), so a change can take a short while to reach every device. See caching for [iOS](/ios-sdk/caching) or [Expo](/expo-sdk/caching) for the details and how to tune it.
</Note>

## Related pages

* [Core concepts](/get-started/core-concepts)
* [Placements](/dashboard/placements)
* [iOS SDK quickstart](/ios-sdk/quickstart)
* [Expo SDK quickstart](/expo-sdk/quickstart)
