Skip to content
Sendora Cloud
Create account
SDKs

First-party SDKs for every platform.

Same four-method mental model on every platform: init, identify, track, push.registerToken. Every SDK ships with types, background retries, automatic consent handling, and (where applicable) per-platform push wiring.

Core methods available on every SDK:

  • init / configure — supply pk_prod_* public key. Org / project derived from the key.
  • identify(userId, traits) — bind the current device to a user. Persists to localStorage on web / EncryptedSharedPreferences on Android / Keychain on iOS — survives page reload + cold launch. Future events + push sends target this id.
  • track(eventName, properties) — emit a custom analytics event. Workflows trigger off these.
  • push.registerToken(token, platform) — register an APNs / FCM / Web Push subscription. Platform enum: ios | android | web.

Push-adjacent helpers (where each platform supports them):

  • iOS: push.requestAuthorization() (UNUserNotificationCenter prompt), push.trackOpen(sendId), liveActivities.track(activity, ...) (ActivityKit token watcher), geofences.start() / refresh() / stop(), SendoraCloudCriticalAlerts.requestPermission(_:).
  • Android: push.trackOpen(sendId), liveActivities.start(fcmToken, ...) / handleFcmMessage(...), geofences.start(ctx) / refresh(ctx) / stop(ctx) / handleBroadcast(intent).
  • Web: webPush.subscribe(swPath) wraps navigator.pushManager.subscribe() with VAPID. Service worker handles push + notificationclick events — see /docs/api § Web Push SW sample.
  • React Native (bare): same JS surface as Web; bring your own @react-native-firebase/messaging for FCM token grab.

Web (SPA)

TypeScript • npm 2.12.0+

npm install @sendoracloud/sdk-web

import { SendoraCloud } from "@sendoracloud/sdk-web";

const s = SendoraCloud.init({ apiKey: "pk_prod_..." });

// Bind the user. Future track() / push sends target this id.
s.identify("u_123", { email: "alice@example.com", plan: "pro" });

// Send an event.
s.track("page.viewed", { path: "/" });

// Web Push (VAPID) — registers the subscription against this user.
await s.webPush.subscribe("/sw.js");

Web (SSR)

TypeScript • npm 0.2.0+ • Next.js / Remix / SvelteKit

npm install @sendoracloud/sdk-web-ssr @sendoracloud/sdk-web

// middleware.ts — protect routes
import { sendoraMiddleware } from "@sendoracloud/sdk-web-ssr/middleware";

export default sendoraMiddleware({
  publicKey: process.env.NEXT_PUBLIC_SENDORA_KEY!,
  protected: ["/dashboard"],
  loginPath: "/login",
});

// app/page.tsx (server component) — read session
import { cookies } from "next/headers";
import { createSendoraServerClient }
  from "@sendoracloud/sdk-web-ssr/server";

const sendora = createSendoraServerClient(cookies(), {
  publicKey: process.env.NEXT_PUBLIC_SENDORA_KEY!,
});
const session = sendora.getSession(); // null if signed out

// "use client" component — track event
import { SendoraCloud }
  from "@sendoracloud/sdk-web-ssr/client";
SendoraCloud.init({ apiKey: "pk_prod_..." })
  .track("page.viewed");

iOS

Swift • SwiftPM 3.9.0+

SwiftPM: github.com/sendoracloud/sdk-ios

import SendoraCloud

SendoraCloud.configure(apiKey: "pk_prod_...")

// Bind the user.
SendoraCloud.identify(
    userId: "u_123",
    traits: ["email": "alice@example.com", "plan": "pro"]
)

// Send an event.
SendoraCloud.trackEvent("screen.viewed", properties: ["screen": "Home"])

// Push token registration (in didRegisterForRemoteNotificationsWithDeviceToken:)
let token = deviceTokenData.map { String(format: "%02x", $0) }.joined()
SendoraCloud.push?.registerToken(token, platform: .ios) { _ in }

Android

Kotlin • JitPack 3.8.0+

implementation("com.github.sendoracloud:sdk-android:3.8.0")

SendoraCloud.init(
    context = this,
    apiKey = "pk_prod_..."
)

// Bind the user.
SendoraCloud.identify(
    userId = "u_123",
    traits = mapOf("email" to "alice@example.com", "plan" to "pro")
)

// Send an event.
SendoraCloud.trackEvent("screen.viewed", mapOf("screen" to "Home"))

// Push token registration (FCM)
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
    val token = task.result ?: return@addOnCompleteListener
    SendoraCloud.push?.registerToken(token, platform = SendoraCloudPush.Platform.ANDROID)
}

React Native

TypeScript • npm 0.16.0+ • Bare workflow

npm install @sendoracloud/sdk-react-native

import { SendoraCloud } from "@sendoracloud/sdk-react-native";

const sendora = SendoraCloud.init({ publicKey: "pk_prod_..." });

// Bind the user.
sendora.identify({ userId: "u_123", traits: { email: "alice@example.com" } });

// Send an event.
sendora.track("screen.viewed", { screen: "Home" });

// Push: bare workflow only — uses @react-native-firebase/messaging.
// platform enum: "ios" | "android" | "web".
import messaging from "@react-native-firebase/messaging";
const token = await messaging().getToken();
await sendora.push.registerToken({ token, platform: "android" });

Expo managed: see /docs/push#expo for the webhook-bridge path. Sendora dispatches via APNs / FCM directly — Expo Push Service tokens are not supported. @react-native-firebase/messaging is required only for Android FCM token grab; iOS-only RN apps can skip Firebase entirely and call iOS-native APIs (UIApplication.registerForRemoteNotifications) via a tiny native module then pass the APNs token to push.registerToken({ token, platform: 'ios' }).

Start in minutes. Scale without switching tools.

The free tier covers most side projects. Every module is turn-key and every SDK is first-party.