Adapter

An OnboardAdapter is how BYO mode talks to your store. Helper: createLocalAdapter (demo). Hosted mode is used internally when you pass flowId + publishableKey and omit adapter.

Resolve order

  1. If adapter is passed, use it for progress. Published config is still fetched when flowId and publishableKey are set (Path C).
  2. Else if flowId and publishableKey are set, use Hosted progress.
  3. Else fall back to createLocalAdapter.

Required methods

getProgress(input)
completeStep(input)
skipStep(input)
snooze(input)
dismiss(input)
resume(input)
resetPersonal(input)
reportOutcome(input)

Pinned input

Mutations include revision, personalGeneration, workspaceGeneration, and requestId. Return AdapterResult with changed and acceptedTransitions. See progress.

reportOutcome

Called after evaluation with applicable required keys, item states, and requirementsSatisfied. Attach integration-reported summary metadata on your backend. See summaries.

BYO example

<Onboard
  flowId="flw_..."
  publishableKey={process.env.NEXT_PUBLIC_BSW_ONBOARD_PUBLISHABLE_KEY}
  user={currentUser}
  workspaceKey={workspace.id}
  onEvent={(event, payload) => { /* analytics */ }}
  adapter={{
    getProgress: async (input) =>
      fetch(`/api/onboard/progress?${new URLSearchParams(input as Record<string, string>)}`).then((r) => r.json()),
    completeStep: async (input) =>
      fetch("/api/onboard/progress", { method: "POST", body: JSON.stringify({ action: "complete", ...input }) }).then((r) => r.json()),
    skipStep: async (input) =>
      fetch("/api/onboard/progress", { method: "POST", body: JSON.stringify({ action: "skip", ...input }) }).then((r) => r.json()),
    snooze: async (input) =>
      fetch("/api/onboard/progress", { method: "POST", body: JSON.stringify({ action: "snooze", ...input }) }).then((r) => r.json()),
    dismiss: async (input) =>
      fetch("/api/onboard/progress", { method: "POST", body: JSON.stringify({ action: "dismiss", ...input }) }).then((r) => r.json()),
    resume: async (input) =>
      fetch("/api/onboard/progress", { method: "POST", body: JSON.stringify({ action: "resume", ...input }) }).then((r) => r.json()),
    resetPersonal: async (input) =>
      fetch("/api/onboard/progress", { method: "POST", body: JSON.stringify({ action: "resetPersonal", ...input }) }).then((r) => r.json()),
    reportOutcome: async (input) =>
      fetch("/api/onboard/outcomes", { method: "POST", body: JSON.stringify(input) }).then((r) => r.json()),
  }}
/>

Related: Modes · Identity · AGENTS.md