Skip to main content
The iOS SDK is a native Swift library that embeds PolyAI’s messaging agent directly inside your iOS app. It’s headless by design: you own the UI, PolyAI provides the AI layer underneath. Your app connects to the same agent logic used across voice, webchat, and other channels. The SDK supports chat (PolyMessaging) and live two-way voice calls (PolyVoice).
The iOS SDK wraps the Messaging API. All WebSocket events, streaming, and handoff behavior documented in the API reference apply.

Source on GitHub

polyai/ios-sdk: Swift package, CocoaPods, and example apps.

How it works

The SDK handles authentication, session management, WebSocket connections, and reconnection logic. Your app sends and receives messages through the SDK and renders them however you choose. The SDK ships as two products:
  • PolyMessaging is chat-only and source-only, with no third-party dependencies.
  • PolyVoice is a separate product that adds voice calling and the WebRTC dependency. Chat-only apps never link the WebRTC binary. It reuses the messaging Configuration and the same CallState / PolyError types. See Voice calling (iOS) for the full guide.
1

Install the SDK

Add the SDK to your project via Swift Package Manager or CocoaPods.
2

Configure authentication

Add your connector token (from Agent Studio) and register your app’s bundle identifier in Agent Studio. The backend rejects connections from unregistered bundle identifiers.
3

Initialize and start a session

Call PolyMessaging.initialize(...) once at launch, then PolyMessaging.chat() to get a ChatSession. The SDK handles access token exchange and WebSocket connection automatically.
4

Build your UI

Observe the ChatSession and send user messages through it. Render the conversation in your own UI components.

Requirements

PolyMessaging (chat) also supports macOS; PolyVoice is iOS-only.

Installation

The SDK is pre-1.0, so a minor version bump is allowed to include breaking changes. Always pin to the next minor version. Don’t use Xcode’s default “Up to Next Major” rule.
In Xcode, go to File > Add Package Dependencies and enter the repository URL:
Set the Dependency Rule to Up to Next Minor Version from 0.11.0, then tick the PolyMessaging library for your app target. If you’re using voice calling, also tick PolyVoice. It’s a separate product and isn’t added automatically.
With CocoaPods, a chat-only pod 'PolyMessaging' install pulls nothing extra. With SPM, adding the repo resolves the WebRTC package for the whole dependency graph, so a chat-only target downloads the xcframework but does not link it.

Authentication setup

The iOS SDK authenticates using a connector token and your app’s bundle identifier.
1

Generate a connector token

In Agent Studio, go to Connector Settings and generate a connector token for your agent.
2

Register your bundle identifier

When generating the token, set the host identifier to your app’s bundle identifier (e.g. com.yourcompany.app). This must match the CFBundleIdentifier in your app’s Info.plist. The SDK sends it automatically as the X-Host header, and the backend rejects connections from apps with a mismatched bundle identifier.
For voice calling you need one further credential from the same page, the web calling token. It is a separate value that authenticates the voice media connection. See Voice calling credentials.

Initialize once

Call PolyMessaging.initialize(...) once at app launch: in SwiftUI’s @main App init, or UIKit’s AppDelegate.application(_:didFinishLaunchingWithOptions:).
apiKey is the only required field. Every other field has a working default: The full configuration reference on GitHub covers environments, error handling and connection states.

Chat session lifecycle

PolyMessaging.chat() returns a @MainActor ChatSession, an ObservableObject. It assembles streaming, tracks delivery, manages typing and surfaces handoff; your UI reads its state and calls its methods.
  • Keep one ChatSession per chat screen. Each new session is a fresh REST handshake.
  • In SwiftUI, hold it with @StateObject.
  • In UIKit, hold it in a stored property and observe its @Published properties with Combine.
  • Call await session.client.shutdown() when you permanently tear down the chat surface. It is idempotent and cancels heartbeat, reconnect, and retry tasks.

Key features

Session persistence

Conversations survive an app relaunch.
  • PolyMessaging.chat() resumes a valid stored session, or starts a fresh one. Sessions normally remain resumable for approximately ten minutes (the backend’s WebSocket idle timeout); after that, chat() starts a new conversation.
  • PolyMessaging.start() always starts a new session. Use it for an explicit “New chat” entry point.
  • PolyMessaging.hasResumableSession() tells the app whether a resumable session exists, so you can offer the choice before showing the chat.
Network changes (Wi-Fi to cellular, brief drops) are handled with automatic reconnection and retry.

Streaming responses

Streaming is enabled by default. ChatSession assembles the chunks automatically and updates messages, so the existing agent message grows token by token and then settles into the final message. You never handle chunks directly. For complete-message bubbles, set Configuration.streamingEnabled to false:

Handoff to live agents

The full handoff flow is supported. When the PolyAI agent triggers a handoff, the SDK delivers the same handoff events (HANDOFF_ACCEPTED, HANDOFF_QUEUE_STATUS, LIVE_AGENT_JOINED, etc.) so your app can show queue status and live agent messages.

Response suggestions

Agent messages can include quick-reply suggestions in AgentMessage.suggestions ([ResponseSuggestion]). Render these as tappable buttons under the latest agent message. When the user taps one, call session.clearSuggestions(for: message.id), then send suggestion.messageText.

Rich content

An AgentMessage can carry:
  • Image attachments: attachments with contentType == .image
  • URL / link-card attachments: attachments with contentType == .url
  • callActions: telephone buttons (ChatCallAction with title and contactNumber)
Drop attachments with contentType == .unknown; it exists for forward compatibility.

Voice calling

PolyVoice places live, two-way WebRTC voice calls to the same agent that powers your chat. Calls are user-initiated: the user taps to call your agent. Set both credentials once in PolyMessaging.initialize(...), then create calls with no arguments:
Configuration.webrtcToken is the normal place to configure the web calling token. iOS also supports VoiceOptions.webrtcToken as an optional per-call override; if both are supplied, the VoiceOptions value wins. Calls run over PolyAI’s webrtc-bridge. The old webrtc-gateway path has been removed and no longer works. Your app needs the microphone permission (NSMicrophoneUsageDescription; a call without it crashes) and the audio background mode so calls survive backgrounding. The SDK handles accessory-aware audio routing, automatic reconnection on transient network drops, and interruptions like incoming phone calls. Optional CallKit support runs the call as a system call; it requires specific delegate wiring, covered on the voice page.

Voice calling (iOS)

The full voice guide: installation, credentials, quick start, CallKit, audio routing, resilience, and troubleshooting.

Platform values

The platform identifier is sent automatically when the session is created, alongside a device_type (mobile / tablet). It identifies the device, not the channel. For the channel a conversation arrives on, see Multichannel below.

Limitations

Example apps

The ios-sdk repository ships runnable example apps in both SwiftUI and UIKit: a chat ladder under Examples/*/Chat and voice demos under Examples/*/Voice.

Multichannel

The iOS SDK connects to the same agent project as your voice and webchat channels. Agent behavior, knowledge, and flows are shared; only channel-specific settings (greetings, formatting) differ. See multichannel agents for how to tailor behavior per channel. Two values tell your agent where a conversation came from:
  • conv.channel_type identifies the channel. Its possible values are webchat.polyai, chat.polyai, sms.twilio, sms.polyai, rcs.polyai, whatsapp.polyai, and sip.polyai. It is never "ios" or "android".
  • platform identifies the device: the SDK sends platform: "ios" (alongside device_type) when the session is created. Use this to tailor behavior for native app users.
To branch on the channel in your agent’s start function:

Voice calling (iOS)

WebRTC voice calls with PolyVoice: setup, CallKit, audio routing, and troubleshooting

Messaging API reference

Full WebSocket protocol, events, streaming, and handoff

Sessions and authentication

Access tokens, session creation, and platform values

Multichannel agents

Build agents that work across voice, webchat, and mobile
Last modified on September 17, 2026