Adding the Mobile SDK Channel (iOS & Android)

The Mobile SDK channel — shown in the Channels module under the Mobile apps group as Mobile - iOS and Mobile - Android — lets you embed a bot in a native mobile application. Your application links the SentiOne Automate SDK, and the SDK talks to the Automate backend directly over gRPC. There is no webhook to expose and no web page to host.

Unlike webhook-based channels, this channel does not authenticate against someone else's messaging platform. It authenticates your own application binary: on the first call the SDK proves which app it is, and Automate checks that against the identity you register here. Most of the configuration below exists for that reason.

📘

One channel per platform

A Mobile SDK channel is bound to a single platform. An iOS app and an Android app need two separate channels — each with its own App Key — even when they are the same product and serve the same project.

The platform cannot be changed after the channel is created. If you pick the wrong tile, create a new channel instead.

Prerequisites

  1. Permission to edit channels in the Channels module.
  2. A project (bot) to assign the channel to. The channel stays inactive until it is assigned.
  3. The identity of the mobile application, obtained from whoever builds it — see Step 1.
  4. Only if you want to require signed-in users: an identity provider that issues JWTs and publishes a JWKS endpoint on a public HTTPS URL — see External JWT authentication.
  5. Only if the app should speak or listen: TTS and/or ASR providers enabled for your organisation.

Step 1: Collect the application identity

During the initial handshake the SDK sends the identity of the running application, and Automate compares it with the values registered on the channel. If they do not match, the handshake is rejected with UNAUTHORIZED_PLATFORM and the app cannot open a conversation.

This binds the App Key to one specific, signed build, so a leaked key cannot be used from a different or re-signed application. Ask your mobile developer for the values below — they are all properties of the app build, not something you create in Automate.

iOS

ValueWhere it comes from
Bundle IDXcode → select the app target → GeneralBundle Identifier. Equivalently, CFBundleIdentifier in the target's Info.plist.
Apple Team IDApple DeveloperMembership detailsTeam ID. Also visible in Xcode → Signing & CapabilitiesTeam, where it is the 10-character code shown next to the team name.

Android

ValueWhere it comes from
Package NameThe applicationId in the app module's build.gradle.kts (or build.gradle). This is the application ID, which is not always the same as the Kotlin/Java package of the source code — take the applicationId.
SHA-256 certificate fingerprintThe fingerprint of the certificate that signs the build which will connect. Obtain it with ./gradlew signingReport (read the SHA-256 line for the relevant variant), or with keytool -list -v -keystore <keystore-file> -alias <alias>.
🚧

Android: register the certificate that actually signs the delivered app

When Google Play App Signing is enabled, Play re-signs your app with the app signing key, so the installed app carries a different certificate than your upload key. Register the app signing key fingerprint from Play Console → Test and releaseSetupApp signingSHA-256 certificate fingerprint.

Debug builds are signed with the local debug keystore and therefore have a different fingerprint than release builds. A channel registered for the release fingerprint will reject debug builds — create a separate channel for development if your team needs one.

If the app is signed by more than one signer, or its signing key has been rotated, the SDK reports only the first fingerprint the platform returns. That is the one to register here.

Step 2: Create the channel

  1. Go to the Channels module and click Create.
  2. In the Mobile apps group, select the Mobile - iOS or Mobile - Android tile.
  3. Fill in the form. Only Name and the two platform fields are required; every field is described in Step 3.
  4. Click Save.
  5. Automate generates the App Key at this point and opens a summary screen with two things on it: a project selector, and the App Key with a copy button. Assign the project here, or later from the channels list.
🚧

Copy the App Key when you need it, not necessarily now

The summary screen is not your only chance to read the key — reopening the channel for editing shows it again in the Authentication section. But it is not shown while creating a channel, because it does not exist yet.

Step 3: Field reference

The sections below follow the order of the form.

Authentication

Present only when you reopen an existing channel; on the summary screen straight after saving, the same value appears in its own panel.

FieldRequiredFormat and rulesWhat it is
App KeygeneratedRead-only, masked. mc- followed by 32 random letters and digits. Use the copy button to read it.The credential the mobile app presents on every call. Automate generates it when the channel is saved — you never type it in. Give it to your mobile developer, who puts it in the SDK configuration. It identifies this channel, so it is bound to one platform, one app identity and one environment: a key issued on one Automate environment is rejected by another.
📘

The App Key is not a secret in the way an API secret is

It ships inside the application binary, so anyone with a copy of the app can read it. That is expected — it is the platform identity check from Step 1, and optionally external JWT authentication, that stop a stolen key from being useful. Still, treat the key as configuration to hand over deliberately, not something to publish.

Basic Information

FieldRequiredFormat and rulesWhat it is
NameyesNon-empty, up to 256 characters; must be unique among your channels.Your own label for the channel, shown in the channels list. It is never displayed to end users, so name it for the app and platform it serves, for example Retail app — Android (production).

The remaining fields in this section depend on the platform tile you selected. Their values come from Step 1; what follows is what the form enforces.

Mobile - iOS

FieldRequiredFormat and rulesWhat it is
Bundle IDyesReverse-DNS: at least two dot-separated parts, each starting with a letter and continuing with letters, digits or underscores — for example com.example.app.The bundle identifier of the app permitted to use this channel.
Apple Team IDyesExactly 10 characters, uppercase letters and digits only — for example A1B2C3D4E5.The Apple Developer Team that signs the app. Together with the Bundle ID it identifies the build allowed to connect.
🚧

Hyphens in a Bundle ID

Apple permits hyphens in a bundle identifier, but the channel form currently rejects them. If your Bundle ID contains a hyphen, contact SentiOne support rather than altering the app's identifier.

Mobile - Android

FieldRequiredFormat and rulesWhat it is
Package NameyesReverse-DNS: at least two dot-separated parts, each starting with a letter and continuing with letters, digits or underscores — for example com.example.app.The applicationId of the app permitted to use this channel.
SHA-256 certificate fingerprintyes64 hexadecimal characters, either continuous (a1b2…) or as 32 colon-separated pairs (A1:B2:…). Letter case and colons are ignored, so paste whichever form your tool produced.The fingerprint of the signing certificate of the app permitted to use this channel.

TTS and ASR (default)

Both sections are optional, and only relevant if the app offers speech. Configure TTS to let the SDK play synthesized bot replies, and ASR (default) to let it stream the microphone in for transcription. Text conversations need neither.

FieldRequiredFormat and rulesWhat it is
ProvidernoSelected from the providers enabled for your organisation. Mobile channels support Techmo, Google, Microsoft and ElevenLabs; other providers your organisation may have are not offered here.Which speech engine serves this channel. Leave the section untouched to keep speech off.
Provider-specific fieldsyes, once a provider is chosenDepends on the provider: a language and voice for Google and Microsoft, a speech key and region for Microsoft, an API key and voice for ElevenLabs, and so on.The specific voice or recognition model to use. These are the same provider settings as on the Voice Gateway channel — see Adding Voice channel (Google provider) and Adding Voice channel (Microsoft provider) for what each provider expects.
Raw ModenoToggle in the section header, available once a provider is selected. Replaces the guided fields with a JSON editor (TTS Params / ASR Params); the JSON must be valid.An escape hatch for provider options the guided form does not expose. Switching Raw Mode back off asks for confirmation and discards JSON that the guided form cannot represent, so prefer the guided fields unless you specifically need it.
📘

The app can tell whether voice is available

Leave a section empty and speech simply stays off for this channel: at handshake the SDK is told that speech-to-text and/or text-to-speech is unavailable, and a voice call made anyway fails with SPEECH_TO_TEXT_NOT_AVAILABLE or TEXT_TO_SPEECH_NOT_AVAILABLE. Well-behaved apps hide their microphone and playback controls based on that signal, so configuring a provider here is what makes the feature appear in the app.

Handover to Agent

Optional. Determines what happens when the flow hands the conversation to a human. The default is Listen & React, SentiOne's own agent application, which needs no extra configuration. Other destinations, such as Genesys, require their own credentials, and which ones appear here depends on what is enabled on your installation — ask your system administrator if an option you expect is missing.

Once the conversation is owned by an agent, the agent's replies reach the app asynchronously and the bot stops answering until the thread is handed back. For what each option involves, see Conversation handover.

External JWT authentication

This section is optional. Leave Enforce external JWT off and the channel is anonymous: any installation of the registered app can start a conversation, and the SDK sends no user credential. Anonymous is the right choice for a public assistant that does not need to know who is asking.

Turn it on when the bot should serve signed-in users only, or when the flow needs to know who the user is. The app then has to attach a JWT issued by your own identity provider to every call, and Automate verifies it against the JWKS below before allowing the session. The three fields appear only once the switch is on.

FieldRequiredFormat and rulesWhat it is and where to get it
Enforce external JWTnoToggle. Off by default.Off — anonymous channel, no user credential. On — the SDK must present a JWT signed by your identity provider, validated against the JWKS URL below.
Audience (aud)yes, when enforcedNon-empty, up to 256 characters.The value Automate expects to find in the token's aud claim. A token is accepted only when its audience list contains this value; anything else is rejected as an audience mismatch. Take it from your identity provider's configuration — it is whatever identifier you registered for the Automate integration (an API identifier, a client ID, or a name you chose).
JWKS URLyes, when enforcedAbsolute HTTPS URL, up to 512 characters. The host must resolve to a public address — localhost, private and internal addresses are rejected.The JSON Web Key Set endpoint Automate fetches to verify token signatures. Every mainstream identity provider publishes one; it is often listed as jwks_uri in the provider's OpenID configuration document (…/.well-known/openid-configuration). Automate must be able to reach it, which is why private hosts are refused.
User identifier claimyes, when enforcedNon-empty, up to 128 characters.The name of the claim whose value identifies the user — not the value itself. Commonly sub, but any claim your provider issues will do: a user ID, a username, a customer number, or an ID of the user's own session. Automate reads that claim to tie the conversation to a user, and a session started under one user's token cannot be continued with another's.
Pass external JWT to bot flownoToggle. Off by default.When on, every message reaching the bot carries the raw token and its decoded claims, available in the flow as external.externalToken.raw and external.externalToken.payload. Turn it on when the flow needs data from the token — an account number, an entitlement, a tier — and leave it off otherwise, so claims are not written into conversation data unnecessarily.
📘

What the token has to look like

Automate accepts tokens signed with RS256, RS384, RS512, ES256, ES384 or ES512, verified against a key from your JWKS endpoint. The token must carry an exp (expiry) claim, must not be expired, must include the configured audience, and must contain the configured user identifier claim with a non-empty value. Tokens are validated on every call, so a session lives no longer than the token backing it — your app is responsible for refreshing the credential, and the SDK picks the new value up.

🚧

On-premise installations and internal JWKS hosts

Rejecting private and internal JWKS hosts is a deliberate safeguard on SentiOne cloud. On an on-premise installation where the identity provider is only reachable inside your network, this check can be relaxed by an administrator through the allow-private-jwks-hosts setting. Contact your system administrator.

Step 4: Assign the channel to a project

A Mobile SDK channel does nothing until it is assigned to a project — that assignment is what decides which bot answers. Until then the channel is marked Channel inactive, and the SDK cannot start a conversation.

Assign it on the summary screen right after saving, or later from the channels list. You can also change the assignment afterwards to point the same app at a different bot, which is a convenient way to move an app between a test bot and a production bot without rebuilding it.

Step 5: Hand the configuration to your mobile developer

The channel is only half of the integration; the other half lives in the app. Give your mobile developer the following:

What to hand overWhy they need it
App KeyGoes into the SDK configuration as appKey. Identifies this channel.
Which Automate environment to connect toApp Keys are environment-bound. For an on-premise installation they will need the host name and port of your Automate deployment, which the SDK accepts as a custom environment.
Whether the channel is anonymous or enforces external JWTDecides whether the app must supply a client access token at all. Sending a token to an anonymous channel is rejected, and so is omitting one where a token is required.
The audience, user identifier claim, and issuing provider — when external JWT is enforcedTheir tokens must carry the audience and claim this channel expects; otherwise every call is rejected.
The exact identity you registered — Bundle ID and Team ID, or Package Name and fingerprintSo they can confirm the build they ship matches the registration, and know that a differently signed build needs its own channel.

Minimal iOS configuration:

import SentiOneAutomate

let configuration = try SentiOneSDKConfiguration(
    appKey: "mc-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    teamId: "A1B2C3D4E5"
)
let sdk = SentiOneSDK(configuration: configuration, delegate: self)

Minimal Android configuration:

val sdk = SentiOneAutomate.create(
    context = context,
    config = Configuration(appKey = "mc-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),
    tokenProvider = null, // required only when the channel enforces external JWT
)

Everything beyond this — installing the SDK, opening a session, streaming replies, handling voice and errors — is covered by the integration guide shipped with each SDK. Ask the SentiOne team for the current version.

Troubleshooting

The form will not save

MessageWhat to do
Channel name cannot be emptyEnter a name.
Bundle ID / Package Name must be reverse-DNS, for example com.example.appUse at least two dot-separated parts, each starting with a letter.
Apple Team ID must be 10 uppercase alphanumeric charactersPaste the Team ID only, without the surrounding parentheses that Xcode shows next to the team name.
SHA-256 fingerprint must be 64 hex characters, optionally separated into pairs by colonsYou probably pasted a SHA-1 fingerprint (40 characters) — take the SHA-256 line instead.
Cannot change the platform of an existing MobileChat channelCreate a new channel for the other platform.
Audience (aud) cannot be empty / must be at most 256 charactersFill in the audience your identity provider issues, or turn off enforcement.
JWKS URL must be a valid absolute https URLUse a full https://… URL. Plain HTTP and relative paths are refused.
JWKS URL host must resolve to a public addressThe endpoint is not reachable from Automate. See the note on on-premise installations above.
User identifier claim cannot be empty / must be at most 128 charactersEnter the claim name, for example sub.
Selected TTS / ASR provider is not supported for mobile channelsChoose Techmo, Google, Microsoft or ElevenLabs.

The app cannot connect

The SDK surfaces the reasons below; each maps to something in this configuration.

Reported reasonCause
INVALID_APP_KEYThe key does not exist — often a key from another Automate environment, or a typo.
APP_KEY_REVOKEDThe channel has been disabled.
UNAUTHORIZED_PLATFORMThe app's identity does not match the registration: wrong Bundle ID or Team ID, wrong Package Name, or — most commonly on Android — a build signed with a different certificate than the fingerprint you registered.
CLIENT_ACCESS_TOKEN_MISSINGThe channel enforces external JWT but the app sent no token.
CLIENT_ACCESS_TOKEN_NOT_SUPPORTEDThe opposite: the app sent a token to an anonymous channel.
CLIENT_ACCESS_TOKEN_EXPIREDThe token's exp has passed. The app must refresh it; long-lived streams end when the token backing them expires.
CLIENT_ACCESS_TOKEN_SIGNATURE_INVALIDThe signature did not verify against any key from the JWKS endpoint, or the signing algorithm is not one of the supported RSA/ECDSA algorithms.
CLIENT_ACCESS_TOKEN_AUDIENCE_MISMATCHThe token's aud does not contain the Audience (aud) configured here.
PRINCIPAL_CLAIM_MISSINGThe token has no claim by the configured User identifier claim name, or its value is empty.
PRINCIPAL_MISMATCHAn attempt to resume a session with a token belonging to a different user.
AUTH_PROVIDER_UNAVAILABLEAutomate could not reach your JWKS endpoint. Check that it is up and publicly reachable, then retry.
SDK_VERSION_UNSUPPORTEDThe app embeds an SDK version below the supported minimum and must be updated. Nothing on the channel needs changing.

Did this page help you?