setEmbeddedData reference for the semantics. This page covers what differs per language.
Values reach a response only through the fields the survey declares in its Hidden Fields card. Declare
the field first, then push a value under the same name.
setEmbeddedData lives in the SDK itself, so adopting it means upgrading the SDK dependency and shipping a
new build of your app. The auto-captured fields further down do not:
those come from the survey renderer, which is loaded from your Formbricks instance at display time, so an
already-installed app picks them up with no upgrade and no rebuild.React Native
string, number, boolean or Date. null removes a key and undefined is a no-op, exactly as in the browser SDK.
Swift (iOS)
EmbeddedDataValue: .string, .number, .bool or .date. String, integer, floating-point and boolean literals convert on their own, so the common call reads as plain data; a Date needs the explicit .date(…) case.
The single-key and clear-everything forms are separate overloads, so a String that cannot be nil means reading the key from your own state can never accidentally wipe the whole bag.
Kotlin (Android)
EmbeddedDataValue, built with string(), number(), boolean() or date(). Kotlin has no undefined either, so null removes a key and the iOS warning above applies here too. As on iOS, the two clear forms are separate overloads.
Flutter
String, num, bool or DateTime; anything else is logged and skipped. null removes a key.
clearEmbeddedData() with no argument clears everything, while clearEmbeddedData(null) is a logged no-op — the same distinction the JavaScript SDK draws by argument count, so reading the key name from your own state cannot wipe the bag when that state is empty.
Value Types at a Glance
On all four,
clearEmbeddedData("key") removes one key and clearEmbeddedData() with no argument clears the whole bag.
Only React Native has a value that means “leave this key alone”. On the other three, leaving the key out of the map is the way to skip it, which is why the warnings above matter for code that builds the map from optionals.
Dates are sent as ISO 8601 on every platform, which is what a date field accepts.
Swift, Kotlin and Dart refuse a non-finite number (
NaN, infinity) at the door and log it. That guard is
not politeness: on those platforms the payload being serialized is the whole survey’s configuration, so one
unserializable value would mean no survey at all rather than one missing field. React Native matches the
browser SDK instead, where such a value simply arrives as unusable and is dropped by the renderer.Lifetime on Mobile
Same three rules as the browser, with one wording change: the bag is process scoped rather than page-load scoped.- In memory, never persisted. A cold app start begins with an empty bag and your app re-pushes. Nothing is written to
UserDefaults,SharedPreferencesor async storage, so there is no PII at rest. - Snapshot at display, then frozen. A value set while a survey is on screen reaches the next response.
- Cleared on an identity switch.
logout(), orsetUserId()with a different id, empties the bag. Identifying for the first time keeps it.
setEmbeddedData before setup(): the bag is pure memory and needs nothing running, so context pushed at launch is not silently dropped.
setUserId("a") immediately followed by setUserId("b") in the same tick clears neither the user state nor
the bag on any of the four SDKs, because the first id has not been committed yet. This is existing identity
behavior rather than something Embedded Data introduces.What Mobile Responses Auto-Capture
The reserved fields work in a WebView with no extra wiring: the survey renderer is loaded from your Formbricks instance at display time, so an already-installed app picks this up without a rebuild or an SDK upgrade.
The absent ones are absent on purpose. A WebView has no host page, so
location and document.referrer describe nothing real, and filling those fields would produce values that look valid and mean nothing. A screen name is host-supplied rather than observed, which makes it ingested data by definition: declare a screen hidden field and push it yourself with setEmbeddedData.
Lifecycle events are JavaScript-only for now. React Native,
iOS, Android and Flutter support is tracked separately and will land in a later release.