Integration Modes

Managed UI and Headless SDK

Ringnity supports two customer styles. Managed UI is for teams that want the fastest setup. Headless SDK is for teams that need their own CRM, mobile app, or product UI.

Managed UI

Ringnity draws the launcher, chat, incoming call, active call, AI handoff, ringtone state, and waiting UI. This is the best path for quick implementation.

  • Best for websites, pilots, and small teams.
  • Client writes less code.
  • Ringnity controls UI behavior and edge states.

Headless SDK

The customer draws the UI. Ringnity manages tokens, sessions, entitlement, realtime events, call state, media adapters, push token registration, and ringtone.

  • Best for CRM, enterprise apps, and custom product UX.
  • Client owns layout and navigation.
  • Ringnity hides transport and backend complexity.

Both modes use the same token rule

Browser and mobile apps request short-lived runtime tokens from the customer backend. Only the customer backend stores the Server API key.

import express from "express";
import { RingnityServerApi } from "@ringnity/server-api";

const app = express();
app.use(express.json());

const ringnity = RingnityServerApi.create({
  apiKey: process.env.RINGNITY_SERVER_API_KEY
});

app.post("/ringnity/runtime-token", async (req, res) => {
  const token = await ringnity.tokens.createVisitorContextToken({
    visitor: {
      externalId: req.body.userId,
      name: req.body.name,
      email: req.body.email
    },
    metadata: { source: "customer-app" },
    expiresIn: 900
  });

  res.json(token);
});

app.listen(3000);

Website Examples

Managed UI website

Available now through the hosted launcher and support window.

<script src="https://api.ringnity.com/sdk/ringnity.js"></script>
<script>
  Ringnity.init({
    slug: "your-tenant-slug",
    visitor: {
      name: "Demo Customer"
    },
    notifications: {
      incomingCall: {
        soundUrl: "/sounds/ringnity-default.mp3",
        vibrate: true
      }
    }
  });
</script>

Headless website or CRM buttons

Available now for custom buttons while Ringnity owns the runtime.

import { Ringnity } from "@ringnity/web-sdk";

const ringnity = await Ringnity.create({
  slug: "your-tenant-slug",
  tokenProvider: async () => {
    const response = await fetch("/ringnity/runtime-token", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        userId: "customer-123",
        name: "Demo Customer"
      })
    });

    return response.json();
  }
});

document.querySelector("#chat")?.addEventListener("click", () => {
  void ringnity.openChat();
});

document.querySelector("#voice")?.addEventListener("click", () => {
  void ringnity.openVoice();
});

document.querySelector("#video")?.addEventListener("click", () => {
  void ringnity.openVideo();
});

Mobile Examples

Current mobile status

SDKStatusAvailable foundation
FlutterManaged UI preview + HeadlessManaged chat, AI chat, call controls, video shell, push token, foreground ringtone, Android/iOS adapter.
React NativeManaged UI preview + HeadlessManaged chat, AI chat, call controls, video shell, push token, foreground ringtone, Android/iOS bridge.
Swift iOSManaged UI preview + HeadlessSwiftUI managed screen, SPM package, URLSession object model, APNs token registration, AVAudioSession adapter.
Kotlin AndroidManaged UI preview + HeadlessNative Android managed view, Gradle package, OkHttp object model, FCM token registration, Android audio adapter.

Flutter Managed UI preview

Available for fast Flutter installs.

final callAdapter = RingnityPlatformCallAdapter();

final ringnityConfig = RingnityConfig(
  tokenProvider: fetchRingnityToken,
  callMode: RingnityCallMode.basic,
  mediaAdapter: callAdapter,
  notificationAdapter: callAdapter,
);

return RingnityWidget(
  config: ringnityConfig,
  mode: RingnityWidgetMode.full,
  conversationSubject: 'Mobile customer support',
);

Flutter Headless SDK

Available foundation for custom Flutter screens.

final callAdapter = RingnityPlatformCallAdapter();

final ringnity = await Ringnity.create(
  RingnityConfig(
    tokenProvider: fetchRingnityToken,
    callMode: RingnityCallMode.basic,
    mediaAdapter: callAdapter,
    notificationAdapter: callAdapter,
    notifications: RingnityNotificationPreferences(
      incomingCall: RingnityRingtoneOptions(
        soundName: 'ringnity_default',
        vibrate: true,
      ),
    ),
  ),
);

final conversation = await ringnity.chat.createConversation(
  subject: 'Need help',
);
final conversationId = conversation['conversationId'] as String;

await ringnity.notifications.previewRingtone();

final call = await ringnity.calls.startVideo(
  conversationId: conversationId,
);

await ringnity.notifications.stopRingtone();
await call.mute();
await call.setVideoEnabled(false);
await call.end();

React Native Managed UI preview

Available for fast React Native installs.

import {
  RingnityWidget,
  createRingnityReactNativeCallAdapter,
} from "@ringnity/react-native-sdk";

const mediaAdapter = createRingnityReactNativeCallAdapter();
const config = {
  tokenProvider: fetchRingnityToken,
  callMode: "basic",
  mediaAdapter,
  notificationAdapter: mediaAdapter
};

export function SupportScreen() {
  return (
    <RingnityWidget
      config={config}
      mode="full"
      conversationSubject="Mobile customer support"
    />
  );
}

React Native Headless SDK

Available foundation for custom React Native screens.

const mediaAdapter = createRingnityReactNativeCallAdapter();

const ringnity = await Ringnity.create({
  tokenProvider: fetchRingnityToken,
  callMode: "basic",
  mediaAdapter,
  notificationAdapter: mediaAdapter,
  notifications: {
    incomingCall: {
      soundName: "ringnity_default",
      vibrate: true
    }
  }
});

const conversation = await ringnity.chat.createConversation({
  subject: "Need help"
});
const conversationId = readConversationId(conversation);

await ringnity.notifications.previewRingtone();

const call = await ringnity.calls.startVideo({ conversationId });

await ringnity.notifications.stopRingtone();
await call.mute();
await call.setVideoEnabled(false);
await call.end();

Native Managed UI preview

SwiftUI and Android native Managed UI are available as preview surfaces for device QA.

import RingnitySDK
import SwiftUI

struct SupportView: View {
    let callAdapter = RingnityAppleCallAdapter()

    var body: some View {
        RingnityView(
            config: RingnityConfig(
                tokenProvider: fetchRingnityToken,
                callMode: .basic,
                mediaAdapter: callAdapter,
                notificationAdapter: callAdapter
            ),
            mode: .full,
            conversationSubject: "iOS customer support"
        )
    }
}

val callAdapter = RingnityAndroidCallAdapter(applicationContext)
val ringnity = Ringnity.create(
    RingnityConfig(
        tokenProvider = ::fetchRingnityToken,
        callMode = RingnityCallMode.BASIC,
        mediaAdapter = callAdapter,
        notificationAdapter = callAdapter,
    )
)

val supportView = RingnityAndroidManagedView(this)
supportView.bind(
    ringnity = ringnity,
    conversationSubject = "Android customer support",
)

setContentView(supportView)

Video rendering contract

Managed UI draws local preview, remote video, and controls. Headless SDK lets the customer place video views in their own layout.

// Available renderer injection primitives.
RingnityWidget(
  config: ringnityConfig,
  mode: RingnityWidgetMode.call,
  remoteVideo: YourRemoteVideoView(),
  localPreview: YourLocalPreviewView(),
);

<RingnityWidget
  config={config}
  mode="call"
  remoteVideo={<YourRemoteVideoView />}
  localPreview={<YourLocalPreviewView />}
/>

await call.mute();
await call.unmute();
await call.setVideoEnabled(false);
await call.end();

Recommended build order

  1. Keep Web Managed UI and Web Headless stable.
  2. Polish CRM panel mounting for Web Headless and Managed UI.
  3. Polish Flutter and React Native Managed UI through device QA.
  4. Run SwiftUI and Android native Managed UI preview through device QA.
  5. Add deeper native media renderer adapters after device QA.
  6. Formalize CRM Agent widget for web.
  7. Add deeper CallKit and Android Telecom support for background or killed-state calls.

Step-by-step setup

Copy-paste setup guide for each SDK.

Flutter SDK

Current Flutter foundation and examples.

React Native SDK

Current React Native foundation and examples.