React Native quickstart
A thin JS bridge over the native iOS SDK — configure once, keep credentials fresh, and present whenever the user taps your launcher. Your app ships no assistant UI.
@voqal/react-native is not on the public npm registry yet, and the repository is private, so the install below will not resolve until your account has beta access. Email us to be added. The package is iOS-only today — Android is on the roadmap.Install the SDK
Once you have beta access, install the package and run pod install — the native framework is vendored inside the package, so there is no extra native setup. Add a microphone usage description for voice input.
# Requires beta access — the package is private (see the note above).npm install @voqal/react-nativecd ios && pod install<!-- ios/<YourApp>/Info.plist — iOS 16+ only --><key>NSMicrophoneUsageDescription</key><string>Voqal uses the microphone for voice conversations.</string>Set up the SDK
Call Voqal.setup once at app start. It throws on a non-iOS platform and when apiKey is missing, so fail fast in development.
import Voqal from '@voqal/react-native';// Configure once at app start. iOS only.Voqal.setup({ apiKey: 'pk_live_…', // your Voqal API key (required, public) requestId: 'prod-yourapp', // "prod-" / "stg-" selects the environment theme: { accent: '#2d5bff', appearance: 'auto' },});Configuration
Everything except credentials is passed to setup. Omit a field to take the native default.
| Option | Type | Description |
|---|---|---|
apiKey | string | Publishable key (pk_live_…), sent as X-Voqal-Key. Required. |
requestId | string | Environment routing; the "prod-" / "stg-" prefix picks the MCP. |
agentURL | string | Engine base-URL override. Rarely needed. |
theme | object | { accent, accent2, appearance, fontName, radius }. |
home | object | { userName, pinnedCTAs, showAgentGlance } — the opening glance. |
hapticsEnabled | boolean | Haptic feedback. Default true. |
conversationTimeout | number | Idle-reset window in seconds. Default 7200. |
observability | object | Sentry diagnostics: { dsn, enabled, scrubPII, tracesSampleRate }. |
forwardedHeaders | () => Record<string,string> | Headers forwarded to your backend each turn (new in 2.0.0). |
Set credentials
Hand the SDK your end user’s auth token with setCredentials, plus an optional metadata JSON string. The token is pushed, not pulled — call again on every rotation and the next request uses it. Metadata is sent as X-Client-Metadata (country, user id), which the engine reads to route and personalize.
// Set at start and whenever your auth layer rotates the token —// the SDK reads the latest value on every request.Voqal.setCredentials(userToken, JSON.stringify({ country_code: 'EGY' }));Forwarding headers
New in 2.0.0. Give setup a forwardedHeaders provider to send your own headers to your backend on every turn. Each entry reaches the engine namespaced as X-Voqal-Forward-<name>; the engine strips the prefix and forwards the header verbatim to your backend. The function is evaluated live on every prewarm / present, so a rotating value — a short-lived Authorization, for example — always sends its current value.
Voqal.setup({ apiKey: 'pk_live_…', requestId: 'prod-yourapp', // Read live at every open — a rotating token always sends its current value. forwardedHeaders: () => ({ Authorization: `Bearer ${getAccessToken()}`, 'X-Tenant-Id': currentTenantId(), }),});This is a different path from metadata. X-Client-Metadatais Voqal’s own context that the engine reads; forwarded headers are passed straight through to your backend and never interpreted by Voqal.
X-Token, X-Voqal-Key, X-Request-Id, X-Client-Metadata, Content-Type, Accept) are dropped if returned — they can never override the SDK’s own headers. Authorization is forwarded. At most 32 headers are sent. Forwarding reaches the wire with the bundled native framework at 2.0.0.Present the assistant
Optionally prewarm at launch to warm the engine connection, then present from any button. Voice, transcription, widgets, and confirmations are handled inside the native sheet.
// Warm the connection early (optional), then present from any button.Voqal.prewarm();Button( title='Talk to Voqal' onPress={() => Voqal.present()} />- Credentials are pushed from JS and served to the SDK’s synchronous delegate, so token refresh is just another
setCredentialscall. - Theming, presentation, and header branding share one model across platforms — see Configuration.
