Skip to Content
Getting StartedMobile Integration

Mobile Integration

Integrate React Native and other mobile apps with the Loop comms platform using the REST API for event firing, push notification delivery, and deep linking.

REST API for Events

Mobile apps interact with the comms platform via the REST API rather than importing @loop/contracts directly. All endpoints accept JSON and require a Bearer token.

Fire an Event

POST https://comms.loop.health/api/events Content-Type: application/json Authorization: Bearer <API_KEY> { "event": "lead.captured.v1", "payload": { "eventId": "550e8400-e29b-41d4-a716-446655440000", "occurredAt": "2026-05-19T12:00:00Z", "brandId": "your-brand-uuid", "email": "user@example.com", "source": "quiz_completion", "attribution": {}, "personId": null } }

Response Format

{ "ok": true, "eventId": "550e8400-e29b-41d4-a716-446655440000", "accepted": true }

Error responses follow the standard structure:

{ "ok": false, "error": { "code": "VALIDATION_ERROR", "message": "payload.email is required" } }

Push Notification Setup

The comms platform delivers push notifications through APNs (iOS) and FCM (Android). Your mobile app needs to register device tokens.

1. Register the Device Token

After obtaining the push token from the OS, register it with the comms platform:

POST https://comms.loop.health/api/devices Content-Type: application/json Authorization: Bearer <USER_TOKEN> { "personId": "user-uuid", "platform": "ios", "token": "device-push-token", "appVersion": "2.4.0" }

2. Handle Token Refresh

Tokens can change. Re-register on every app launch:

useEffect(() => { const unsubscribe = messaging().onTokenRefresh(async (token) => { await registerDeviceToken(token); }); return unsubscribe; }, []);

3. Notification Payload Structure

Push notifications from the comms platform include:

FieldTypeDescription
titlestringNotification title
bodystringNotification body text
data.deepLinkstringDeep link URL to open in-app
data.compositionIdstringTemplate composition ID for tracking
data.brandIdstringBrand identifier

Deep Linking

The comms platform attaches deep links to push notifications, emails, and SMS messages. Configure your app to handle the loophealth:// scheme.

const linking = { prefixes: ['loophealth://', 'https://app.loop.health'], config: { screens: { Protocol: 'protocol/:protocolId', Labs: 'labs/:labId', Chat: 'chat', Profile: 'profile', Supply: 'supply/:orderId', }, }, };

Handle Notification Tap

messaging().onNotificationOpenedApp((remoteMessage) => { const deepLink = remoteMessage.data?.deepLink; if (deepLink) { Linking.openURL(deepLink); } });

Offline Queueing

Mobile apps frequently lose connectivity. Queue events locally and flush when the network is available.

  1. Store events in local storage (AsyncStorage or MMKV) when offline
  2. Retry on reconnect using NetInfo listener
  3. Deduplicate using the eventId field — the server ignores duplicate eventId values
import NetInfo from '@react-native-community/netinfo'; const eventQueue: QueuedEvent[] = []; async function fireEvent(event: string, payload: Record<string, unknown>) { const entry = { event, payload, queuedAt: Date.now() }; const { isConnected } = await NetInfo.fetch(); if (isConnected) { const ok = await sendToApi(entry); if (!ok) eventQueue.push(entry); } else { eventQueue.push(entry); } } NetInfo.addEventListener((state) => { if (state.isConnected) flushQueue(); });

Queue Limits

SettingRecommended Value
Max queue size500 events
Max event age72 hours
Flush batch size50 events
Retry delayExponential backoff (1s → 60s)

Events older than 72 hours should be discarded — the server rejects stale events to prevent out-of-order processing.

Next Steps