React Native
React Native SDK
Real-time AI voice agent calls inside your iOS & Android app with
@telenow/react-native. The control plane, codecs, and jitter buffer run in
JS (shared with @telenow/client); a small native module
does only mic capture + PCM playback in the platform's voice-communication
mode, so hardware echo cancellation and noise suppression are on
automatically — speakerphone works without the agent hearing itself.
npm i @telenow/react-native @telenow/client
cd ios && pod install # autolinks the native TelenowAudio module
Before you start
- An agent (dashboard → Agents) and its agent ID.
- Authorization — recommended: your backend mints a session with an org
API key via
createWeb/init_web_calland hands{ sessionId, websocketUrl }to the app. Alternatives: the agent's publishedpublicSlugor an ephemeral clienttoken. - Microphone permission:
- iOS —
Info.plist:<key>NSMicrophoneUsageDescription</key> <string>Voice calls with our assistant</string> - Android —
<uses-permission android:name="android.permission.RECORD_AUDIO" />in the manifest and a runtime request (PermissionsAndroid.request) beforestart().
- iOS —
Quickstart
import { TelenowCall } from '@telenow/react-native';
const call = new TelenowCall({
session, // { sessionId, websocketUrl } from YOUR backend (recommended)
// publicSlug: 'my-agent', // or: published agent, no auth
baseUrl: 'https://api.telenow.ai',
});
call.onState = (s) => setCallState(s); // connecting | live | reconnecting | ended | error
call.onTranscript = (role, text) => append({ role, text });
await call.start(); // starts native audio + connects → live
call.setMuted(true);
call.stop();
Options reference
| Option | Type | Default | What it does |
|---|---|---|---|
session | { sessionId, websocketUrl } | — | Backend-minted session — skips on-device init (recommended). |
publicSlug | string | — | Published agent, no auth. |
token | string | — | Ephemeral client token. |
baseUrl | string | '' | API origin, e.g. https://api.telenow.ai. |
variables | Record<string,string> | — | Context variables — or bake them into the minted session (tamper-proof). |
uplinkEncoding | 'mulaw' | 'pcm16' | 'mulaw' | Wire format — keep the default. |
reconnect | { maxAttempts?, baseDelayMs?, maxDelayMs?, jitter? } | 6 / 500 / 10000 / 0.3 | Backoff after network drops. |
Callbacks: onState(state), onTranscript(role, text). Methods:
start(): Promise<void>, stop(), setMuted(boolean).
What the SDK handles
- Echo & noise — iOS
AVAudioSessionvoice-chat mode (VoiceProcessingIO), AndroidVOICE_COMMUNICATIONsource: hardware AEC/NS/AGC. Agent playback is routed through the voice-processing unit so the echo canceller removes the agent's own voice from the mic. - Barge-in — interrupting the agent flushes queued audio instantly.
- Reconnect — drops retry with backoff while audio keeps running.
- Latency pings — answered automatically for your analytics.
Troubleshooting
| Symptom | Fix |
|---|---|
TelenowAudio is null | Autolinking didn't run — pod install (iOS) / clean Gradle sync (Android), then rebuild the app (a JS reload isn't enough after installing). |
| Silent on Android | RECORD_AUDIO runtime permission not granted before start(). |
| Silent on iOS simulator | Test audio on a real device — simulator routing is unreliable. |
| 401/403 at start | Bad/expired credential, or API access is off on the agent's Publish tab. |
| 400 naming a variable | A required context variable wasn't passed. |
| Echo on speakerphone | Keep playback inside the SDK — it runs through the echo canceller. |
Other mobile stacks
Native Swift, Kotlin/Android, and Flutter SDKs are coming soon. Until then: embed the hosted widget or public page in a web view, or drive everything over the REST API (your agent's Publish tab has copy-paste cURL, Node, Python, and Rust samples).