BrekkyDocs

Getting started

  • Introduction
  • Quickstart
  • Core concepts

Guides

  • Install the tracker
  • Track custom events
  • Identify users
  • Cross-app handoffs
  • Dashboard
  • Team & roles

Reference

  • SDK reference
  • MCP
  • FAQ
Open dashboard
⌘K
Log inCreate free accountSign up

Cross-app handoffs

Stamp a hop from one app to another so Sessions can show where the visit continued.

Mobile and web do not share storage. Opening your website from the iOS app starts a new session, by design. A handoff does not merge those visits. It stamps the same handoff_id on both so the dashboard can link them.

Use this when someone taps Upgrade in the app and lands on billing in the browser, or when an email or SMS opens a page in your product. Call identify with the same user id on both sides so Visitors still groups the person.

Do not put a user id in the URL. bk_h is only attribution. Auth stays your login flow.

How it works

  • The source app calls Brekky.handoffUrl(url). That mints a UUID, appends ?bk_h=, and sends a reserved handoff_started event.
  • Open that URL. The web snippet reads bk_h on load, strips it with replaceState, and sends handoff_received once. Native destinations call Brekky.consumeHandoff(url).
  • Later events on the destination keep handoff_id in context until reset() or a new hop.

In Sessions you will see a banner such as "Continued on Web App" or "Opened from iOS", with a link to the other visit when both sides have landed.

React Native (source)

BetterKnocks-style upgrade tap: build the URL, then open it. Optional properties (reason, plan) land on handoff_started.

React Native
import { Linking } from 'react-native';

const url = await Brekky.handoffUrl(
  'https://app.example.com/account/billing',
  { reason: 'upgrade', plan: 'pro' },
);
await Linking.openURL(url);

Web (destination)

The snippet consumes ?bk_h= automatically. You only call handoffUrl if the website is the source (for example a "open in the app" link).

JavaScript
const url = await Brekky.handoffUrl(
  'https://app.example.com/account/billing',
  { reason: 'upgrade', plan: 'pro' },
);
window.location.assign(url);

// Destination: the snippet reads ?bk_h= on load.
// Native destinations: Brekky.consumeHandoff(url);

iOS, Android, Flutter, Node

Swift
let url = Brekky.shared.handoffURL(
  "https://app.example.com/account/billing",
  properties: ["reason": "upgrade", "plan": "pro"]
)
UIApplication.shared.open(URL(string: url)!)

// Destination:
Brekky.shared.consumeHandoff(incomingURL.absoluteString)
Kotlin
val url = Brekky.handoffUrl(
  "https://app.example.com/account/billing",
  mapOf("reason" to "upgrade", "plan" to "pro"),
)
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))

// Destination:
Brekky.consumeHandoff(intent.data?.toString())
Dart
final url = await Brekky.handoffUrl(
  'https://app.example.com/account/billing',
  {'reason': 'upgrade', 'plan': 'pro'},
);
// Open url with url_launcher (or your host).

// If Flutter is the destination:
await Brekky.consumeHandoff(incomingUrl);
Node
const url = await Brekky.handoffUrl(
  'https://app.example.com/account/billing',
  { reason: 'upgrade', plan: 'pro' },
);
// Put url in an email or SMS.

// If Node is the destination (rare):
await Brekky.consumeHandoff(incomingUrl);

Rules

  • handoff_started and handoff_received are reserved. Do not send them with track().
  • The query param is bk_h. The value is a lowercase UUID. First writer wins per project, id, and direction.
  • In-app browsers often send a null referrer. The stamp is the link, not the referrer.
Next: Dashboard