Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data/events/common.mdx
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
---
title: 'Common fields'
description: 'Reference for the common and contextual fields shared across all Formo events, including event type, timestamps, device context, and session identifiers.'

Check warning on line 3 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L3

Use 'formo' instead of 'Formo'.
---

Formo defines some common fields (event type, timestamps, and more) across all API calls that make up the core event data structure.

Check warning on line 6 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L6

Use 'formo' instead of 'Formo'.
This guide covers the common and contextual fields in detail.

## Common Fields

> The Formo SDKs populate the required information automatically.

Check warning on line 11 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L11

Use 'formo' instead of 'Formo'.

| Name | Datatype | Required | Description |
|:-----|:----------|:---------|:------------|
| `type` | String | ✓ | Captures the type of event. Values can be either identify, track, connect, signature, transaction, and others. |
| `channel` | String | ✓ | Identifies the source of the event. The Formo SDKs emit `web`, `mobile`, or `server`. Other values such as `onchain`, `import`, and `api` are reserved for platform and import-pipeline ingestion, not SDK-emitted events. |

Check warning on line 16 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L16

Use 'formo' instead of 'Formo'.
| `version` | String | ✓ | Version of the event spec. |
| `project_id` | String | ✓ | Unique identification for the project in the database. |
| `session_id` | String | ✓ | Privacy-friendly daily changing session identifier. |
| `session_id` | String | ✓ | Session identifier. On **web** this is a privacy-friendly, daily-changing value derived server-side at ingestion, so no cookie is required. The **mobile** SDK supplies its own instead, which rotates after 30 minutes of inactivity — see [Session management](/sdks/mobile#session-management). |
| `anonymous_id` | String | ✓ | Pseudo-identifier for the user in cases where userId is absent. Equivalent to a device ID. |

Check warning on line 20 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L20

Did you really mean 'userId'?
| `user_id` | String | | Unique identification for the user in the database. |
| `address` | String | | Unique wallet address of the user. |
| `event` | String | | Captures the user action that you want to record. |
| `context` | Object | ✓ | Contains all additional user information. |
| `properties` | Object | | Passes all relevant information associated with the event. |
| `original_timestamp` | Timestamp | ✓ | Records the actual time (in UTC) when the event occurred.|
| `sent_at` | Timestamp | ✓ | Captures the time (in UTC) when the event was sent from the client to Formo.|

Check warning on line 27 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L27

Use 'formo' instead of 'Formo'.
| `received_at` | Timestamp | ✓ | Time in UTC when Formo ingests the event. |

Check warning on line 28 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L28

Use 'formo' instead of 'Formo'.
| `timestamp` | Timestamp | ✓ | Formo calculates this field to account for any client-side clock skew using the formula: timestamp = received_at - (sent_at - original_timestamp). Note that this time is in UTC. |

Check warning on line 29 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L29

Use 'formo' instead of 'Formo'.

Check warning on line 29 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L29

Did you really mean 'original_timestamp'?
| `message_id` | String | ✓ | Unique identification for the event.|

## Contextual Fields
Expand Down Expand Up @@ -59,11 +59,11 @@
| `page_title` | String | | Title of the page. |
| `library_name` | String | | Name of the SDK used to capture the event. |
| `library_version` | String | | Version of the SDK used to capture the event. |
| `browser` | String | | Name of the browser (e.g., chrome, firefox, safari). |

Check warning on line 62 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L62

Did you really mean 'firefox'?
| `screen_width` | Number | | Width of the device screen in pixels. |
| `screen_height` | Number | | Height of the device screen in pixels. |
| `screen_density` | Number | | Pixel density of the device screen (devicePixelRatio). |
| `viewport_width` | Number | | Width of the browser viewport in pixels. |

Check warning on line 66 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L66

Did you really mean 'viewport'?
| `viewport_height` | Number | | Height of the browser viewport in pixels. |

## Timestamps
Expand All @@ -76,10 +76,10 @@

| Name | Calculated / Value |
|--------------------|-----------------------------------------------------------------------------------|
| original_timestamp | Time on the client device when call was invoked OR The timestamp value manually passed in through server-side libraries. |

Check warning on line 79 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L79

Did you really mean 'original_timestamp'?
| sent_at | Time on client device when call was sent OR sent_at value manually passed in. |

Check warning on line 80 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L80

Did you really mean 'sent_at'?

Check warning on line 80 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L80

Did you really mean 'sent_at'?
| received_at | Time on Formo server clock when call was received |

Check warning on line 81 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L81

Did you really mean 'received_at'?

Check warning on line 81 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L81

Use 'formo' instead of 'Formo'.
| timestamp | Calculated by Formo to correct client-device clock skew using the following formula: `received_at - (sent_at - original_timestamp)` |

Check warning on line 82 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L82

Use 'formo' instead of 'Formo'.

### Original Timestamp

Expand All @@ -88,9 +88,9 @@
> Note: The `original_timestamp` timestamp is not useful for any analysis since it's not always trustworthy as it can be easily adjusted and affected by clock skew.

### Sent At
The `sent_at` timestamp specifies the clock time for the client's device when the network request was made to the Formo API.

Check warning on line 91 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L91

Use 'formo' instead of 'Formo'.

For libraries and systems that send batched requests, there can be a long gap between a datapoint's timestamp and sent_at. Combined with `received_at`, Formo uses `sent_at` to correct the `original_timestamp` in situations where a user's device clock cannot be trusted (mobile phones and browsers). The `sent_at` and `received_at` timestamps are assumed to occur at the same time (maximum a few hundred milliseconds), and therefore the difference is the user's device clock skew, which can be applied back to correct the timestamp.

Check warning on line 93 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L93

Did you really mean 'datapoint's'?

Check warning on line 93 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L93

Did you really mean 'sent_at'?

Check warning on line 93 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L93

Use 'formo' instead of 'Formo'.

> Note: The `sent_at` timestamp is not useful for any analysis since it's tainted by user's clock skew.

Expand All @@ -102,9 +102,9 @@

The `timestamp` specifies when the data point occurred, corrected for client-device clock skew. This is the timestamp that is passed to downstream destinations and used for historical replays. It is important to use this timestamp for importing historical data to the API.

Formo automatically generates `timestamp` and you cannot manually set one directly in the call payload.

Check warning on line 105 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L105

Use 'formo' instead of 'Formo'.

Formo calculates timestamp as `timestamp = received_at - (sent_at - original_timestamp)`.

Check warning on line 107 in data/events/common.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

data/events/common.mdx#L107

Use 'formo' instead of 'Formo'.

## Sample Event

Expand Down
78 changes: 77 additions & 1 deletion sdks/mobile.mdx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
title: 'Mobile'
icon: mobile
description: 'Track user events in your mobile apps with the Formo React Native SDK. Measure what matters onchain with full device context and wallet event tracking.'

Check warning on line 4 in sdks/mobile.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

sdks/mobile.mdx#L4

Use 'formo' instead of 'Formo'.
---

<Warning>The mobile SDK is still in active development. [Contact support](https://formo.so/support) to get access.</Warning>

The Formo React Native SDK is designed for mobile apps and implements the standard [Events API](/data/events/overview#events-api) with rich mobile context including device information, network status, and app metadata.

Check warning on line 9 in sdks/mobile.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

sdks/mobile.mdx#L9

Use 'formo' instead of 'Formo'.

## Installation

Expand All @@ -30,6 +30,14 @@

If neither is installed, provide app metadata via the `app` option instead.

For **Android install attribution** (knowing which site or campaign a user came from before installing), also install:

```bash
npm install react-native-play-install-referrer
```

This one requires a native rebuild of your Android app. Without it the SDK still works — install attribution is simply skipped, and a warning is logged on startup. See [Web-to-mobile attribution](#web-to-mobile-attribution).

### iOS Setup (bare React Native only)

If you're using bare React Native (not Expo), run pod install after adding native dependencies:
Expand Down Expand Up @@ -136,6 +144,10 @@
Include `formo` in the dependency array. The SDK initializes asynchronously, so including it ensures the screen event fires once initialization completes.
</Note>

Screen views are sent as `page` events so they flow through the same analytics as web page views. The screen name is recorded in the `app://` scheme — `formo.screen('Wallet')` is sent with a `page_url` of `app://Wallet`, and a router-style name like `formo.screen('/tabs/leaderboard')` is sent as `app:///tabs/leaderboard`.

Formo derives the rest for you: your app becomes the equivalent of a web origin (from the app name or bundle ID in the event context), and the screen name becomes the page path — so screens appear alongside web pages in reports like Top Pages.

Check warning on line 149 in sdks/mobile.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

sdks/mobile.mdx#L149

Use 'formo' instead of 'Formo'.

### With React Navigation

Automatically track all screen transitions:
Expand Down Expand Up @@ -296,13 +308,62 @@

Example deep link: `myapp://home?utm_source=twitter&utm_campaign=launch&ref=friend123`

## Web-to-mobile attribution

Deep link attribution tells you where a user came from once the app is *already installed*. Web-to-mobile attribution answers the earlier question: **which site or campaign led someone to install the app in the first place.**

### Android

Google Play passes a referrer through the install, so this is captured reliably. Point your marketing links at your Play Store listing with a `referrer` parameter:

```
https://play.google.com/store/apps/details?id=<your.package>&referrer=utm_source%3Dexample.com%26utm_campaign%3Dspring
```

On first launch the SDK reads that value and attaches it to the [`Application Installed`](#mobile-lifecycle-events) event, and to the traffic source used by subsequent events:

```json
{
"event": "Application Installed",
"properties": {
"version": "1.1.0",
"build": "42",
"utm_source": "example.com",
"utm_campaign": "spring"
}
}
```

Requires `react-native-play-install-referrer` and a native rebuild — see [Installation](#optional-dependencies). The lookup runs once, on the first launch after install.

### iOS

<Note>
Not supported. Apple does not expose an install-referrer API, so an install cannot be attributed to a referring website from within the SDK. This requires a third-party attribution service such as Branch or AppsFlyer. On iOS this capture is a no-op — deep link attribution still works normally.
</Note>

### Disabling

Both attribution sources are on by default and can be turned off individually:

```tsx
options={{
attribution: {
deeplinks: true, // capture UTM/ref from deep links
installReferrer: false, // skip the Play Install Referrer lookup
},
}}
```

Passing `attribution: false` disables both.

## Configuration

### Provider props

| Prop | Type | Required | Description |
|:-----|:-----|:---------|:------------|
| `writeKey` | String | Yes | Your Formo project write key. |

Check warning on line 366 in sdks/mobile.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

sdks/mobile.mdx#L366

Use 'formo' instead of 'Formo'.
| `asyncStorage` | AsyncStorage | Yes | AsyncStorage instance for persistent storage. |
| `options` | Object | No | Configuration options (see below). |
| `disabled` | Boolean | No | Disable the SDK entirely. |
Expand Down Expand Up @@ -512,6 +573,7 @@
| `device_model` | Device model (iPhone 14 Pro, Pixel 8). |
| `device_manufacturer` | Device manufacturer (Apple, Google, Samsung). |
| `device_type` | Device type (mobile, tablet). |
| `user_agent` | Device user agent. Taken from the platform when available, otherwise derived from the device and OS above. Used to resolve device and OS in analytics. |
| `screen_width` | Screen width in pixels. |
| `screen_height` | Screen height in pixels. |
| `screen_density` | Pixel density (devicePixelRatio). |
Expand All @@ -526,12 +588,25 @@

## Session management

The SDK assigns a `session_id` to every event. A session groups one user's burst of activity into a single visit, and powers the Sessions, Session duration, and Bounce rate metrics on your dashboard. No configuration is required.

| Behavior | Detail |
|:---------|:------------|
| Session start | The first event after install, or the first event after a session expires. |
| Session timeout | 30 minutes of inactivity. The next event after that starts a new session. |
| Persistence | A session survives app restarts — it expires on inactivity, not on close. |
| Reset | `reset()` ends the current session and starts a new one. |

<Note>
This differs from the web SDK, where `session_id` is derived server-side as a daily-changing value. That derivation relies on the request's origin, IP and browser user agent — signals a native app does not provide meaningfully — so the mobile SDK supplies its own session instead.
</Note>

Reset the current user session:

```tsx
const formo = useFormo();

// Clear current user session (anonymous_id, user_id, etc.)
// Clear current user identifiers (anonymous_id, session_id, user_id)
formo.reset();
```

Expand All @@ -556,7 +631,7 @@
1. Enable debug logging in development
2. Trigger a screen view or custom event
3. Check the console for event logs
4. Verify events appear in the [Activity page](https://app.formo.so) on your Formo dashboard

Check warning on line 634 in sdks/mobile.mdx

View check run for this annotation

Mintlify / Mintlify Validation (formo) - vale-spellcheck

sdks/mobile.mdx#L634

Use 'formo' instead of 'Formo'.

## Peer dependencies

Expand All @@ -570,3 +645,4 @@
| `expo-application` | >=5.0.0 | No (for auto version/build detection in Expo) |
| `expo-device` | >=5.0.0 | No (for device info in Expo) |
| `react-native-device-info` | >=10.0.0 | No (for auto version/build detection in bare RN) |
| `react-native-play-install-referrer` | >=1.1.8 | No (for Android web-to-mobile install attribution) |