onboarding or paywall. Your app calls the SDK with a placement key, and FlowPilot decides which flow (if any) to show at that point based on the placement’s default flow, its audience rules, and any active experiment.
Placements are the bridge between the dashboard and the SDK. They are the most important dashboard concept for anyone integrating the SDK, because they decouple “where in my app” from “which flow runs there”. You can swap the flow a placement serves at any time, without shipping a new app release.
The mental model
There are two sides to every placement, and they are linked by a single string, the placement key.-
In your app code, you trigger a placement by its key:
-
In the dashboard, a placement with the matching key holds the configuration that decides what
"onboarding"resolves to.
The dashboard’s SDK Integration card shows a short snippet like
FlowPilot.trigger("onboarding"). That is shorthand for the real iOS call, which is presentPlacement(_:from:). See Presenting placements for the actual API.What a placement holds
| Field | What it is |
|---|---|
| Placement ID (key) | The string your app passes to the SDK. Lowercase letters, numbers, and underscores. Unique within an app. |
| Platforms | The platforms this placement applies to: iOS, Android, Web. The device platform must be in this list to resolve a flow. |
| Default flow | The published flow version served when nothing else takes priority. Stored as a default_flow_version_id (an exact published version, not “the latest”). |
| Audience filter (optional) | Rules that decide whether a user qualifies. No filter means everyone qualifies. See Audience targeting. |
| Active experiment (optional) | A running A/B test bound to the placement. When present and running, it can serve a variant flow instead of the default. |
| Status | active or paused. A paused placement resolves to nothing. |
| Description (optional) | A note for your team. Not shown to users. |
How resolution works
When the SDK asks about a placement key, the backend runs this sequence. The first step that fails returns no flow.Find the placement
Look up the placement by app and key. If it does not exist, or its status is paused, resolution stops and no flow is returned.
Match the platform
The device’s platform (
ios, android, or web) must be in the placement’s platforms list. If it is not, no flow is returned.Check the audience filter
If the placement has an audience filter, the user’s attributes must match it. If they do not, no flow is returned. No filter means everyone passes this step.
Apply an active experiment
If a running experiment is bound to the placement, the user is assigned to a variant (sticky, the same user always gets the same variant). That variant’s flow version is served. The experiment can have its own audience filter that gates enrollment.
Fall back to the default flow
If no experiment applies, the placement’s default flow version is served.
resolve_no_flow event. For the exact request and response contract, see SDK REST API.
The Placements list
Open Placements from the sidebar. The page is titled Placements with the subtitle “Manage how flows and experiments are triggered in your app”. The list is scoped to the app you currently have selected.- New Placement: the button in the page header opens the create wizard. See Creating a placement.
- Search: the Search placements by ID or description box filters by a case-insensitive match on the placement ID or description.
- Status tabs: All, Active, Paused.
- Platform filter: All Platforms, iOS, Android, Web. This matches placements that include the chosen platform.
- Testing (with a flask icon) when an experiment is bound to the placement.
- Active when the placement is active and has no experiment.
- Paused when the placement is paused.
...) menu has View Details, Edit (opens the placement in edit mode), and Delete. Clicking the placement ID also opens the detail page.
TODO: screenshot of the Placements list (header, filter bar, status badges, and the actions menu).
Common mistakes
- Key mismatch. The placement key in your code must exactly match the placement ID in the dashboard.
onboardingandOnboardingare different. The dashboard lowercases IDs for you, so match that in code. - Wrong app. Placements are app-scoped. If your app’s SDK is configured with a different
appIdthan the app that holds the placement, it will not resolve. Confirm the app switcher shows the right app. - Platform not included. A placement with only Android selected returns no flow to an iOS device. Make sure iOS is in the platforms list.
- Paused placement. A paused placement always resolves to nothing. Re-activate it from the detail page when you are ready.