Onboarding funnel (web → app)

A hosted web funnel that runs before the user installs — quiz and info steps, an email capture, then an App Store handoff. The captured answers + email follow the user into the app on first launch, with no third-party attribution SDK to wire up.

How it works

  • You run the funnel from an ad, link-in-bio, or QR code at appmate.cloud/onboarding/{appSlug}.
  • The visitor answers a few steps and (optionally) leaves an email. On the final screen they tap through to the App Store.
  • On completion AppMate stores an OnboardingSubmission and mints a short-lived claim token (prefixed amob_) — left on the clipboard for the deferred handoff.
  • On first launch the iOS SDK reads the token, redeems it for the answers + email, and your app opens already personalized.
AppMate carries the answers and email; it never sees or grants your app's entitlements. What you do with a captured answer (preset a plan, pre-fill signup, route to a paywall) is entirely app-side.

Configure the funnel

Author the config in the dashboard's JSON editor, or via the MCP update_onboarding_draft tool / the REST API. A config is an intro, an ordered list of steps, and a handoff:

json
{
  "type": "onboarding",
  "intro": {
    "title": "Let's get you set up",
    "subtitle": "A couple of quick questions to tailor the app to you.",
    "startLabel": "Get started",
    "eyebrow": "60-second setup"
  },
  "steps": [
    {
      "kind": "question",
      "id": "goal",
      "prompt": "What brings you here?",
      "selectMode": "single",
      "autoAdvance": true,
      "required": true,
      "options": [
        { "id": "save_time", "label": "Save time", "emoji": "⚡" },
        { "id": "get_organized", "label": "Get organized", "emoji": "🗂️" }
      ]
    },
    {
      "kind": "info",
      "id": "value",
      "title": "You're going to love this",
      "body": "We'll set up a starting point that fits your answers."
    },
    {
      "kind": "email_capture",
      "id": "email",
      "title": "Where should we send your setup?",
      "placeholder": "you@example.com",
      "required": false
    }
  ],
  "handoff": {
    "title": "You're all set — get the app",
    "body": "Install and open the app. Your answers will be waiting.",
    "ctaLabel": "Download on the App Store",
    "appStoreUrl": "https://apps.apple.com/app/id000000000"
  }
}

Step kinds

  • question — tap-to-answer options. selectMode: "single" (default) with autoAdvance: true moves on instantly; "multi" lets the user pick several and tap Continue. Set required to force an answer.
  • info — a copy/image screen with a Continue button. No input; use it to build the pitch or reflect answers back.
  • email_capture — the lead-capture field. required defaults to true; set it false to allow Skip.

Step and option ids are snake_case and must be unique — they key the captured answers. Publishing returns advisory warnings for a missing email step, a handoff with no appStoreUrl, duplicate ids, etc.

Recover answers in your app (deferred handoff)

On first launch — or right after sign-up, once you have a stable userId — ask the SDK for the result:

swift
Task {
    if let result = await RetentionFlow.fetchOnboardingResult(userId: user?.id) {
        if let goal = result.values(forStep: "goal").first {
            applyStartingPreset(for: goal)
        }
        if let email = result.email { prefillSignup(email: email) }
    }
}
The SDK reads the claim token from the clipboard, which shows the standard iOS paste banner. Call this at a natural “setting things up” moment so the banner reads as expected. Returns nil for organic installs (no token present).

In-app funnel

To run the same funnel for an already-installed user (a “redo setup” button), present it in a Safari sheet — the SDK claims the result for you:

swift
RetentionFlow.startOnboardingFlow(userId: user.id) { result in
    guard let result else { return }
    apply(result)
}

Where the data lands

  • Dashboard → your app → Onboarding funnel completions — answers, email, and claim status per row, with CSV export.
  • Programmatically: GET /api/v1/apps/{appId}/onboarding/submissions or the MCP list_onboarding_submissions / export_onboarding_csv tools.

Embed it

Drop the funnel into a marketing page with the bare iframe variant:

html
<iframe
  src="https://appmate.cloud/embed/onboarding/my-app"
  loading="lazy"
  style="border:0; width:100%; height:560px;">
</iframe>

See the deep link contract for the onboarding_complete return action and the iOS SDK for the full API.