---
title: iOS
slug: sdk/web-view-sdk-api-reference-ios
createdAt: 2026-11-04T11:39:41.227Z
---

The public API of the iOS, generated from release 1.0.1

# Classes

## KindlyWebViewClient

`class`

```swift
public final class KindlyWebViewClient
```

The Kindly web-view chat SDK. Use it through `KindlyWebViewSDK`; every member is static and may be called from any thread.

| Member                                                       | Declaration                                                                                                                                               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `delegate`                                                   | `public static var delegate: KindlyWebViewClientDelegate?`                                                                                                | The link delegate. Held weakly, and kept across `start()` and `kill()`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `events`                                                     | `static var events: AnyPublisher<KindlyEvent, Never>`                                                                                                     | Every event: `load`, `message`, `buttonClick`, `ui`, `globalIcon` and `state`. Emitted on the main thread. A hot stream with no replay; valid before `start()`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `state`                                                      | `static var state: AnyPublisher<KindlyEventState, Never>`                                                                                                 | The SDK state. Replays the current value to every new subscriber; emits on the main thread.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `currentState`                                               | `static var currentState: KindlyEventState`                                                                                                               | The current state, readable from any thread.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `isSupported`                                                | `static var isSupported: Bool`                                                                                                                            | `false` when the chat cannot run in this app: the app declares `WKAppBoundDomains` without `chat.kindlycdn.com`, or the current chat page reported, while it loaded, that the web view lacks features the widget needs (the next page checks again: after `endChat()`, `kill()` or a `start()` with another bot key or market; a `start()` with the same ones keeps the page). `displayChat()` then shows an "unsupported" screen instead of the chat; nothing crashes.                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `verboseLogging`                                             | `static var verboseLogging: Bool`                                                                                                                         | Debug-level logs under the OSLog subsystem `ai.kindly.webview`. Off by default. The logs never contain chat content, tokens or URLs beyond scheme and host.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `enableCrashReporting`                                       | `static var enableCrashReporting: Bool`                                                                                                                   | Whether the SDK reports its own errors to Kindly. Defaults to `true`. Applied at `start()`, and immediately when changed afterwards.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `start(botKey:languageCode:market:authTokenProvider:)`       | `static func start(botKey: String, languageCode: String = "en", market: String, authTokenProvider: KindlyWebViewAuthTokenProvider? = nil)`                | Starts the SDK for a bot. The chat page is created on the first `displayChat()`, but the usage metrics start here, and the error reports unless `enableCrashReporting` is off, so an app that asks for the user's consent calls `start` after it. Calling it again with the same bot key and market keeps the page and replaces the language (for the next page) and the auth provider. A different bot key or market closes the chat and discards the page; the old conversation stays stored for when you switch back. **Parameters** - `botKey`: The bot key. - `languageCode`: The chat language, for example `en` or `nb`. Defaults to `en`. - `market`: **Required** market slug. The widget loads `/settings/{botKey}/{market}.json`; there is no fallback to another market. - `authTokenProvider`: Called with the chat id when the chat authenticates. See `KindlyWebViewAuthTokenProvider`. |
| `start(botKey:languageCode:market:authCredentialsProvider:)` | `static func start(botKey: String, languageCode: String = "en", market: String, authCredentialsProvider: @escaping KindlyWebViewAuthCredentialsProvider)` | Starts the SDK with a provider of full credentials (id token, companion access token, issuer, expiry). Otherwise the same as the token overload.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `displayChat(languageCode:triggerDialogueId:)`               | `static func displayChat(languageCode: String? = nil, triggerDialogueId: String? = nil)`                                                                  | Presents the chat as a sheet over the top view controller. The first call loads the widget; later calls reopen it instantly with the conversation intact. Logs an error and does nothing before `start()`. **Parameters** - `languageCode`: A language for this display. A language other than the live page's reloads the page. - `triggerDialogueId`: A dialogue to start when the chat opens.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `closeChat()`                                                | `static func closeChat()`                                                                                                                                 | Dismisses the chat. The conversation and the page stay alive, so `sendMessage` and `triggerDialogue` keep working while it is hidden.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `endChat()`                                                  | `static func endChat() async`                                                                                                                             | Ends the conversation: tells the backend the user left (when a chat page is loaded), dismisses the chat, and clears the stored conversation, so the next `displayChat()` starts a new one with a fresh greeting. When no chat page is loaded (never displayed, or released) the backend is not told; that session expires on its own. Returns immediately before `start()`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `kill()`                                                     | `static func kill() async`                                                                                                                                | `endChat()`, then shuts the SDK down. Call `start()` again before anything else.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `sendMessage(_:newContext:)`                                 | `static func sendMessage(_ text: String, newContext: [String: String]? = nil) async throws`                                                               | Sends a message as the user. The text is trimmed; empty text throws `KindlyWebViewError.invalidArgument(_:)`. Throws `KindlyWebViewError.chatNotReady` when no chat page exists yet (call `displayChat()` first). While the page is loading the message waits (up to 30 seconds). It opens the chat only when the chat is displayed. `newContext` goes with this message only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `triggerDialogue(id:)`                                       | `static func triggerDialogue(id: String)`                                                                                                                 | Starts a dialogue. Needs a chat page (logs an error otherwise); while the chat is hidden the dialogue runs without opening it.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `setNewContext(_:)`                                          | `static func setNewContext(_ context: [String: String])`                                                                                                  | Context for the next message, button click or trigger. Applied to the loaded page right away, otherwise when the next page loads; once delivered it is not applied again. The widget merges context, so two calls before the next message send both maps.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `clearNewContext()`                                          | `static func clearNewContext()`                                                                                                                           | Withdraws context set with `setNewContext`, including context already delivered to the loaded page.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `authenticate()`                                             | `static func authenticate() async throws`                                                                                                                 | Authenticates the chat with the provider given to `start()`. Throws `KindlyWebViewError.noAuthProvider` without one. With a loaded page the widget re-authenticates now; a page that is still loading does once it has loaded (in call order with `deauthenticate()`, and the call throws `KindlyWebViewError.chatNotReady` if that page fails); without a page the next page does.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `deauthenticate()`                                           | `static func deauthenticate() async throws`                                                                                                               | Makes the chat anonymous. Until `authenticate()`, token requests are refused and new pages load without auth. A page that is still loading is told once it has loaded.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

# Structures

## KindlyAuthCredentials

`struct`

```swift
public struct KindlyAuthCredentials: Equatable, Sendable
```

The credentials the host app hands the SDK to authenticate a chat.

Copied from the native SDK. The web-view SDK passes them to the hosted widget: the bearer goes as `idToken` (the widget refuses credentials without one), the companion access token as `accessToken`, `issuer` as is, and `expiresAt` as Unix seconds.

The Kindly platform verifies an authenticated chat in one of three ways, and this single type covers all of them — which is why nothing here is named after any one of them:

- **Kindly JWT** — a JWT your own backend signs. Only `idToken` is read; `accessToken` is ignored by this strategy.
- **Identity provider (JWKS)** — a JWT minted by your identity provider. Set `accessToken` as well when the provider hands you a separate access token; the backend then verifies the pair together and forwards the access token to your webhooks rather than the id token.
- **Introspection** — an opaque bearer token. Put it in `idToken` and set `issuer` so the backend knows which provider to introspect it against.

Every field is optional, but **at least one of `idToken` / `accessToken` must be set** — whichever is present becomes the `Authorization: Bearer` (see `bearerToken`). A single-JWT integration can keep returning a plain `String` from a `KindlyWebViewAuthTokenProvider` and never touch this type at all.

| Member                                                   | Declaration                                                                                                            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `idToken`                                                | `public let idToken: String?`                                                                                          | The OIDC id token, when your provider issues one. Optional. This is the *preferred* bearer, not a mandatory field — plenty of providers hand back only an access token, and an opaque introspection bearer has no id token at all. What the SDK actually requires is that **at least one** of `idToken` / `accessToken` is set; see `bearerToken`.                                                                                                                                                                                                                                                       |
| `accessToken`                                            | `public let accessToken: String?`                                                                                      | The access token, when your provider issues one. Its role depends on what else is set. Alongside an `idToken` it is the dual-token *companion* and is sent as `X-Access-Token`. On its own it becomes the bearer — see `bearerToken`. The Kindly JWT strategy ignores the companion form.                                                                                                                                                                                                                                                                                                                |
| `issuer`                                                 | `public let issuer: String?`                                                                                           | The identity provider this credential came from. Sent as `X-Auth-Issuer`. Required when the bot has more than one provider configured, and when `idToken` is opaque — the backend cannot read an `iss` claim out of a token it cannot decode, so without this it has no way to pick a provider.                                                                                                                                                                                                                                                                                                          |
| `expiresAt`                                              | `public let expiresAt: Date?`                                                                                          | When these credentials stop being valid, if you know. Worth supplying when `idToken` is opaque: the SDK reads `exp` out of a JWT itself, but an opaque token tells it nothing, and credentials with no known expiry are treated as non-expiring and never proactively refreshed. This is a hint, not an override. The SDK refreshes on whichever comes first out of this, the `exp` claim it can read, and the expiry the backend reports. A date more than 1e12 seconds after 1970 is read as a millisecond value that was passed as seconds, and is divided by 1000.                                   |
| `init(idToken:accessToken:issuer:expiresAt:)`            | `public init( idToken: String? = nil, accessToken: String? = nil, issuer: String? = nil, expiresAt: Date? = nil )`     | Set at least one of `idToken` / `accessToken`. Credentials carrying neither cannot authenticate anything — the SDK reports them as an empty result from your callback and the chat stays anonymous. **Parameters** - `idToken`: The OIDC id token, if your provider issues one. - `accessToken`: The access token, if your provider issues one. - `issuer`: The provider's issuer. Required for opaque tokens and multi-provider bots. - `expiresAt`: When the credentials expire, if known.                                                                                                             |
| `init(idToken:accessToken:issuer:expiresAtUnixSeconds:)` | `public init( idToken: String? = nil, accessToken: String? = nil, issuer: String? = nil, expiresAtUnixSeconds: Int? )` | Convenience for providers that report expiry the way OAuth does — Unix seconds. **Parameters** - `expiresAtUnixSeconds`: Expiry as seconds since 1970, exactly as an `exp` claim or an introspection response carries it.                                                                                                                                                                                                                                                                                                                                                                                |
| `bearerToken`                                            | `var bearerToken: String?`                                                                                             | The token actually sent as `Authorization: Bearer`, or `nil` when neither field was set. `Authorization` is mandatory on the backend's auth route, so whichever token the host has goes there — `idToken` first, falling back to `accessToken`. A provider that returns only an access token is a normal, supported case: the backend verifies it by whichever strategy the bot is configured for, exactly as it did before dual-token support existed.                                                                                                                                                  |
| `hasToken`                                               | `var hasToken: Bool`                                                                                                   | `true` when these credentials carry something usable.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `companionAccessToken`                                   | `var companionAccessToken: String?`                                                                                    | The access token in its *companion* role — the value that will be sent as `X-Access-Token`, or `nil` when no companion header will be sent. Exposed so a host can see what the SDK will actually do rather than re-deriving the rule. It is `nil` in two cases that are easy to get wrong: when the access token is itself the bearer (no id token was supplied), and when it merely duplicates the id token. The backend verifies the companion against the id token's `at_hash` and rejects a mismatched pair outright, so sending a duplicate would fail an auth that would otherwise have succeeded. |

## KindlyEvent

`struct`

```swift
public struct KindlyEvent
```

An event emitted by the Kindly web-view SDK.

Besides the typed `detail`, every event carries the raw `kindly:*` type string, the time it was emitted in epoch milliseconds, and the detail as JSON text, so wrappers and hosts can forward events without hand-written serialisers.

| Member               | Declaration                                                     | Description                                                                                                                                                                                                                                                                                                               |
| -------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`               | `public let type: KindlyEventType`                              | The type of event.                                                                                                                                                                                                                                                                                                        |
| `detail`             | `public let detail: KindlyEventDetail`                          | The event details.                                                                                                                                                                                                                                                                                                        |
| `timestamp`          | `public let timestamp: Int64`                                   | When the event was emitted, in milliseconds since 1970.                                                                                                                                                                                                                                                                   |
| `rawType`            | `public let rawType: String`                                    | The raw event type, `kindly:load`, `kindly:message`, `kindly:buttonclick`, `kindly:ui`, `kindly:globalicon` or `kindly:state`.                                                                                                                                                                                            |
| `detailJSON`         | `public let detailJSON: String`                                 | The event detail as JSON text. For widget events it is the SDK's own projection of what the page sent: the widget fields the SDK forwards, with the same limits as the typed `detail`, URLs without their query and never an attachment's download URL. For state and SDK-synthesised events it is the equivalent object. |
| `date`               | `public var date: Date`                                         | `timestamp` as a `Date`.                                                                                                                                                                                                                                                                                                  |
| `init(type:detail:)` | `public init(type: KindlyEventType, detail: KindlyEventDetail)` | Creates an event stamped with the current time, with `detailJSON` built from `detail`, for example to test your event handling.                                                                                                                                                                                           |

## KindlyEventAttachment

`struct`

```swift
public struct KindlyEventAttachment
```

Attachment data for events. The attachment's download URL carries a session token and is never forwarded; `storagePath` identifies the file.

| Member                                            | Declaration                                                                                                    | Description                                                     |
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `id`                                              | `public let id: String`                                                                                        | Attachment ID                                                   |
| `name`                                            | `public let name: String`                                                                                      | Attachment name                                                 |
| `format`                                          | `public let format: String`                                                                                    | Attachment format                                               |
| `status`                                          | `public let status: String`                                                                                    | Attachment status                                               |
| `sender`                                          | `public let sender: String`                                                                                    | Attachment sender                                               |
| `storagePath`                                     | `public let storagePath: String`                                                                               | Storage path                                                    |
| `init(id:name:format:status:sender:storagePath:)` | `public init( id: String, name: String, format: String, status: String, sender: String, storagePath: String )` | Creates an attachment, for example to test your event handling. |

## KindlyEventButton

`struct`

```swift
public struct KindlyEventButton
```

Button data for events.

| Member                                                     | Declaration                                                                                                                                                            | Description                                                |
| ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| `id`                                                       | `public let id: String?`                                                                                                                                               | Button ID                                                  |
| `type`                                                     | `public let type: String`                                                                                                                                              | Button type                                                |
| `label`                                                    | `public let label: String`                                                                                                                                             | Button label text                                          |
| `value`                                                    | `public let value: String?`                                                                                                                                            | Button value (an absolute URL loses its query)             |
| `index`                                                    | `public let index: Int?`                                                                                                                                               | Button index                                               |
| `hasBeenSelected`                                          | `public let hasBeenSelected: Bool`                                                                                                                                     | Whether the button has been selected                       |
| `context`                                                  | `public let context: [String: Any]?`                                                                                                                                   | Button context data (flat, at most 20 primitive values)    |
| `init(id:type:label:value:index:hasBeenSelected:context:)` | `public init( id: String? = nil, type: String, label: String, value: String? = nil, index: Int? = nil, hasBeenSelected: Bool = false, context: [String: Any]? = nil )` | Creates a button, for example to test your event handling. |

## KindlyEventGlobalIcon

`struct`

```swift
public struct KindlyEventGlobalIcon
```

Global icon action data for events.

| Member                     | Declaration                                                                       | Description                                                            |
| -------------------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| `type`                     | `public let type: String`                                                         | Action type                                                            |
| `source`                   | `public let source: String`                                                       | Action source                                                          |
| `value`                    | `public let value: [String: Any]?`                                                | Additional value data (the icon)                                       |
| `init(type:source:value:)` | `public init(type: String, source: String = "user", value: [String: Any]? = nil)` | Creates a global icon action, for example to test your event handling. |

## KindlyEventImage

`struct`

```swift
public struct KindlyEventImage
```

Image data for events.

| Member                  | Declaration                                                           | Description                                                |
| ----------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------- |
| `url`                   | `public let url: String`                                              | Image URL (query removed)                                  |
| `altText`               | `public let altText: String?`                                         | Alt text for accessibility                                 |
| `id`                    | `public let id: String?`                                              | Image ID                                                   |
| `init(url:altText:id:)` | `public init(url: String, altText: String? = nil, id: String? = nil)` | Creates an image, for example to test your event handling. |

## KindlyEventLanguage

`struct`

```swift
public struct KindlyEventLanguage
```

Language data for events.

| Member                       | Declaration                                                        | Description                                                  |
| ---------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------ |
| `code`                       | `public let code: String`                                          | Language code (e.g., "en", "es")                             |
| `name`                       | `public let name: String`                                          | Language name (e.g., "English", "Español")                   |
| `isDefault`                  | `public let isDefault: Bool`                                       | Whether this is the default language                         |
| `init(code:name:isDefault:)` | `public init(code: String, name: String, isDefault: Bool = false)` | Creates a language, for example to test your event handling. |

## KindlyEventMessage

`struct`

```swift
public struct KindlyEventMessage
```

Message data for events.

| Member                                                                                                           | Declaration                                                                                                                                                                                                                                                                                                                                                           | Description                                                                                       |
| ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `id`                                                                                                             | `public let id: String`                                                                                                                                                                                                                                                                                                                                               | Message ID. A message the user just typed carries a `tempId-...` id until the server confirms it. |
| `chatId`                                                                                                         | `public let chatId: String?`                                                                                                                                                                                                                                                                                                                                          | The chat/session ID this message belongs to.                                                      |
| `text`                                                                                                           | `public let text: String?`                                                                                                                                                                                                                                                                                                                                            | Message text content                                                                              |
| `sender`                                                                                                         | `public let sender: KindlyEventMessageSender`                                                                                                                                                                                                                                                                                                                         | Message sender type                                                                               |
| `created`                                                                                                        | `public let created: Date?`                                                                                                                                                                                                                                                                                                                                           | Message creation timestamp                                                                        |
| `isFromUser`                                                                                                     | `public let isFromUser: Bool`                                                                                                                                                                                                                                                                                                                                         | Whether the message is from the user                                                              |
| `exchangeID`                                                                                                     | `public let exchangeID: String?`                                                                                                                                                                                                                                                                                                                                      | Exchange ID if applicable                                                                         |
| `videoSource`                                                                                                    | `public let videoSource: String?`                                                                                                                                                                                                                                                                                                                                     | Video source URL if applicable (query removed)                                                    |
| `exchangeType`                                                                                                   | `public let exchangeType: KindlyEventExchangeType?`                                                                                                                                                                                                                                                                                                                   | Exchange type if applicable                                                                       |
| `buttons`                                                                                                        | `public let buttons: [KindlyEventButton]`                                                                                                                                                                                                                                                                                                                             | Message buttons if any                                                                            |
| `images`                                                                                                         | `public let images: [KindlyEventImage]`                                                                                                                                                                                                                                                                                                                               | Message images if any                                                                             |
| `attachments`                                                                                                    | `public let attachments: [KindlyEventAttachment]`                                                                                                                                                                                                                                                                                                                     | Message attachments if any                                                                        |
| `init(id:chatId:text:sender:created:isFromUser:exchangeID:videoSource:exchangeType:buttons:images:attachments:)` | `public init( id: String, chatId: String? = nil, text: String? = nil, sender: KindlyEventMessageSender, created: Date? = nil, isFromUser: Bool, exchangeID: String? = nil, videoSource: String? = nil, exchangeType: KindlyEventExchangeType? = nil, buttons: [KindlyEventButton] = [], images: [KindlyEventImage] = [], attachments: [KindlyEventAttachment] = [] )` | Creates a message, for example to test your event handling.                                       |

## KindlyEventSettings

`struct`

```swift
public struct KindlyEventSettings
```

Settings data for load events.

| Member                           | Declaration                                                                                        | Description                                                     |
| -------------------------------- | -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `name`                           | `public let name: String`                                                                          | Settings name                                                   |
| `id`                             | `public let id: String`                                                                            | Settings ID                                                     |
| `languages`                      | `public let languages: [KindlyEventLanguage]`                                                      | Available languages                                             |
| `style`                          | `public let style: KindlyEventStyle`                                                               | Style configuration                                             |
| `init(name:id:languages:style:)` | `public init(name: String, id: String, languages: [KindlyEventLanguage], style: KindlyEventStyle)` | Creates load settings, for example to test your event handling. |

## KindlyEventState

`struct`

```swift
public struct KindlyEventState: Equatable
```

State data for events.

The field names match the native SDK. In the web-view SDK `isSocketConnected` and `isConnected` both mean "the SDK page has loaded the widget" (also while the chat is hidden), and `connectionState` is one of `none`, `loading`, `connected`, `failed`, `unsupported` and `disconnected`.

| Member                                                                           | Declaration                                                                                                                  | Description                                                     |
| -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `isChatDisplayed`                                                                | `public let isChatDisplayed: Bool`                                                                                           | Whether the chat is currently displayed                         |
| `isStarted`                                                                      | `public let isStarted: Bool`                                                                                                 | Whether the SDK has been started                                |
| `isSocketConnected`                                                              | `public let isSocketConnected: Bool`                                                                                         | Whether the widget page is loaded                               |
| `isConnected`                                                                    | `public let isConnected: Bool`                                                                                               | Whether the widget page is loaded (same as `isSocketConnected`) |
| `connectionState`                                                                | `public let connectionState: String`                                                                                         | Current connection state as string                              |
| `init(isChatDisplayed:isStarted:isSocketConnected:isConnected:connectionState:)` | `public init( isChatDisplayed: Bool, isStarted: Bool, isSocketConnected: Bool, isConnected: Bool, connectionState: String )` | Creates a state, for example to test your event handling.       |

## KindlyEventStyle

`struct`

```swift
public struct KindlyEventStyle
```

Style data for events.

| Member                                                                                                                                                                                    | Declaration                                                                                                                                                                                                                                                                                                                                                                      | Description                                               |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `background`                                                                                                                                                                              | `public let background: String?`                                                                                                                                                                                                                                                                                                                                                 | Background color in hex format                            |
| `buttonBackground`                                                                                                                                                                        | `public let buttonBackground: String?`                                                                                                                                                                                                                                                                                                                                           | Button background color in hex format                     |
| `buttonText`                                                                                                                                                                              | `public let buttonText: String?`                                                                                                                                                                                                                                                                                                                                                 | Button text color in hex format                           |
| `headerBackground`                                                                                                                                                                        | `public let headerBackground: String?`                                                                                                                                                                                                                                                                                                                                           | Header background color in hex format                     |
| `headerText`                                                                                                                                                                              | `public let headerText: String?`                                                                                                                                                                                                                                                                                                                                                 | Header text color in hex format                           |
| `inputBackground`                                                                                                                                                                         | `public let inputBackground: String?`                                                                                                                                                                                                                                                                                                                                            | Input background color in hex format                      |
| `inputText`                                                                                                                                                                               | `public let inputText: String?`                                                                                                                                                                                                                                                                                                                                                  | Input text color in hex format                            |
| `userMessageBackground`                                                                                                                                                                   | `public let userMessageBackground: String?`                                                                                                                                                                                                                                                                                                                                      | User message background color in hex format               |
| `userMessageTextColor`                                                                                                                                                                    | `public let userMessageTextColor: String?`                                                                                                                                                                                                                                                                                                                                       | User message text color in hex format                     |
| `botMessageBackground`                                                                                                                                                                    | `public let botMessageBackground: String?`                                                                                                                                                                                                                                                                                                                                       | Bot message background color in hex format                |
| `botMessageTextColor`                                                                                                                                                                     | `public let botMessageTextColor: String?`                                                                                                                                                                                                                                                                                                                                        | Bot message text color in hex format                      |
| `init(background:buttonBackground:buttonText:headerBackground:headerText:inputBackground:inputText:userMessageBackground:userMessageTextColor:botMessageBackground:botMessageTextColor:)` | `public init( background: String? = nil, buttonBackground: String? = nil, buttonText: String? = nil, headerBackground: String? = nil, headerText: String? = nil, inputBackground: String? = nil, inputText: String? = nil, userMessageBackground: String? = nil, userMessageTextColor: String? = nil, botMessageBackground: String? = nil, botMessageTextColor: String? = nil )` | Creates a style, for example to test your event handling. |

## KindlyEventUIAction

`struct`

```swift
public struct KindlyEventUIAction
```

UI action data for events.

| Member                                                                                                                                    | Declaration                                                                                                                                                                                                                                                                                                                                    | Description                                                   |
| ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `type`                                                                                                                                    | `public let type: KindlyUIActionType`                                                                                                                                                                                                                                                                                                          | Action type                                                   |
| `source`                                                                                                                                  | `public let source: String`                                                                                                                                                                                                                                                                                                                    | Action source (`user` or `programmatic`)                      |
| `chatId`                                                                                                                                  | `public let chatId: String`                                                                                                                                                                                                                                                                                                                    | Chat ID (empty when the widget had none yet)                  |
| `value`                                                                                                                                   | `public let value: [String: Any]?`                                                                                                                                                                                                                                                                                                             | Additional value data                                         |
| `feedbackType`                                                                                                                            | `public let feedbackType: String?`                                                                                                                                                                                                                                                                                                             | Feedback type if applicable                                   |
| `feedbackValue`                                                                                                                           | `public let feedbackValue: [String: Any]?`                                                                                                                                                                                                                                                                                                     | Feedback value if applicable                                  |
| `languageCode`                                                                                                                            | `public let languageCode: String?`                                                                                                                                                                                                                                                                                                             | Language code for language change events                      |
| `languageName`                                                                                                                            | `public let languageName: String?`                                                                                                                                                                                                                                                                                                             | Language name for language change events                      |
| `previousLanguageCode`                                                                                                                    | `public let previousLanguageCode: String?`                                                                                                                                                                                                                                                                                                     | Previous language code for language change events             |
| `previousLanguageName`                                                                                                                    | `public let previousLanguageName: String?`                                                                                                                                                                                                                                                                                                     | Previous language name for language change events             |
| `nextPage`                                                                                                                                | `public let nextPage: String?`                                                                                                                                                                                                                                                                                                                 | Next page for navigation events (`chat` or `welcome-page`)    |
| `init(type:source:chatId:value:feedbackType:feedbackValue:languageCode:languageName:previousLanguageCode:previousLanguageName:nextPage:)` | `public init( type: KindlyUIActionType, source: String = "user", chatId: String, value: [String: Any]? = nil, feedbackType: String? = nil, feedbackValue: [String: Any]? = nil, languageCode: String? = nil, languageName: String? = nil, previousLanguageCode: String? = nil, previousLanguageName: String? = nil, nextPage: String? = nil )` | Creates a UI action, for example to test your event handling. |

# Enumerations

## KindlyEventDetail

`enum`

```swift
public enum KindlyEventDetail
```

Event details that can be associated with different event types.

| Member                                                | Declaration                                                                                                                       | Description                                 |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `load(settings:)`                                     | `case load(settings: KindlyEventSettings)`                                                                                        | Settings loaded event                       |
| `message(newMessage:chatLog:)`                        | `case message(newMessage: KindlyEventMessage, chatLog: [KindlyEventMessage])`                                                     | Message event with new message and chat log |
| `buttonClick(button:buttonType:chatLog:lastMessage:)` | `case buttonClick(button: KindlyEventButton, buttonType: String, chatLog: [KindlyEventMessage], lastMessage: KindlyEventMessage)` | Button click event                          |
| `ui(action:)`                                         | `case ui(action: KindlyEventUIAction)`                                                                                            | UI action event                             |
| `globalIcon(action:)`                                 | `case globalIcon(action: KindlyEventGlobalIcon)`                                                                                  | Global icon event                           |
| `state(state:)`                                       | `case state(state: KindlyEventState)`                                                                                             | State change event                          |

## KindlyEventExchangeType

`enum`

```swift
public enum KindlyEventExchangeType: String, CaseIterable
```

Exchange types for events.

| Member           | Declaration                               | Description                                                                                                         |
| ---------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `dialogue`       | `case dialogue`                           | `dialogue`: a reply from one of the bot's dialogues.                                                                |
| `fallback`       | `case fallback`                           | `fallback`: the bot's fallback reply, when no dialogue matched.                                                     |
| `greeting`       | `case greeting`                           | `greeting`: the bot's greeting.                                                                                     |
| `systemDialogue` | `case systemDialogue = "system_dialogue"` | `system_dialogue`: a system dialogue, including the widget's own system messages, which it marks `system-dialogue`. |
| `userSays`       | `case userSays = "user_says"`             | `user_says`.                                                                                                        |

## KindlyEventMessageSender

`enum`

```swift
public enum KindlyEventMessageSender: String, CaseIterable
```

Message sender types for events.

| Member    | Declaration                | Description                                                                                                  |
| --------- | -------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `agent`   | `case agent = "AGENT"`     | A human agent, after a handover.                                                                             |
| `bot`     | `case bot = "BOT"`         | The bot.                                                                                                     |
| `system`  | `case system = "SYSTEM"`   | A message from the chat itself rather than from a person or the bot.                                         |
| `user`    | `case user = "USER"`       | The user of your app.                                                                                        |
| `unknown` | `case unknown = "UNKNOWN"` | A sender this version does not map, such as the widget's `WEBHOOK` and `EXTERNAL`, or a message without one. |

## KindlyEventType

`enum`

```swift
public enum KindlyEventType: String, CaseIterable
```

Types of events that can be emitted by the Kindly web-view SDK.

| Member        | Declaration                               | Description                                                                   |
| ------------- | ----------------------------------------- | ----------------------------------------------------------------------------- |
| `load`        | `case load = "kindly:load"`               | The widget loaded its settings.                                               |
| `message`     | `case message = "kindly:message"`         | A message was added to the conversation.                                      |
| `buttonClick` | `case buttonClick = "kindly:buttonclick"` | The user clicked a message button.                                            |
| `ui`          | `case ui = "kindly:ui"`                   | A UI action happened (open, close, end chat, language change, feedback, ...). |
| `globalIcon`  | `case globalIcon = "kindly:globalicon"`   | A global icon was clicked.                                                    |
| `state`       | `case state = "kindly:state"`             | The SDK state changed.                                                        |

## KindlyUIActionType

`enum`

```swift
public enum KindlyUIActionType: String, CaseIterable
```

Types of UI actions that can be performed.

| Member                 | Declaration                                             | Description                                               |
| ---------------------- | ------------------------------------------------------- | --------------------------------------------------------- |
| `openChatBubble`       | `case openChatBubble = "open-chatbubble"`               | Open chat bubble                                          |
| `closeChatBubble`      | `case closeChatBubble = "close-chatbubble"`             | Close chat bubble                                         |
| `endChat`              | `case endChat = "end-chat"`                             | End chat                                                  |
| `restartChat`          | `case restartChat = "restart-chat"`                     | Restart chat                                              |
| `downloadChat`         | `case downloadChat = "download-chat"`                   | Download chat                                             |
| `deleteChat`           | `case deleteChat = "delete-chat"`                       | Delete chat                                               |
| `changeLanguage`       | `case changeLanguage = "change-language"`               | Change language                                           |
| `showFeedback`         | `case showFeedback = "show-feedback"`                   | Show feedback                                             |
| `submitFeedback`       | `case submitFeedback = "submit-feedback"`               | Submit feedback                                           |
| `dismissFeedback`      | `case dismissFeedback = "dismiss-feedback"`             | Dismiss feedback                                          |
| `welcomePageStartChat` | `case welcomePageStartChat = "welcome-page-start-chat"` | The user started the chat from the widget's welcome page. |

## KindlyWebViewError

`enum`

```swift
public enum KindlyWebViewError: Error, Equatable, Sendable
```

Errors the web-view SDK's `async throws` APIs report.

| Member                | Declaration                            | Description                                                                                                                                         |
| --------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `notStarted`          | `case notStarted`                      | `start()` has not been called, or `kill()` ran since.                                                                                               |
| `chatNotReady`        | `case chatNotReady`                    | No loaded chat page exists to run the call (for example `sendMessage` before the first `displayChat()`, or after the page failed to load).          |
| `invalidArgument(_:)` | `case invalidArgument(String)`         | An argument was refused before anything was sent. The associated value names the argument (`text`, `newContext`, `botKey`, ...), never its content. |
| `noAuthProvider`      | `case noAuthProvider`                  | `authenticate()` was called but `start()` received no auth provider.                                                                                |
| `timeout`             | `case timeout`                         | The page did not answer in time.                                                                                                                    |
| `widgetError(code:)`  | `case widgetError(code: String)`       | The hosted widget reported an error. `code` is a fixed code such as `widget_error`.                                                                 |
| `unsupported`         | `case unsupported`                     | The web view or the host app's configuration cannot run the chat.                                                                                   |
| `errorDescription`    | `public var errorDescription: String?` | A one-line English description for logs, without any argument's content.                                                                            |

# Protocols

## KindlyWebViewClientDelegate

`protocol`

```swift
public protocol KindlyWebViewClientDelegate: AnyObject
```

Lets the host app decide what happens to links the chat opens.

| Member                   | Declaration                                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------------------ | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `shouldHandleLink(url:)` | `func shouldHandleLink(url: URL) async -> Bool` | Return `true` to let the SDK open `url` outside the app (Safari, Mail, Phone, ...), or `false` to handle it yourself. Asked for every http, https, mailto, tel and sms link the chat tries to open while it is displayed; other schemes are blocked before this is asked. The SDK cancels the navigation first and then asks, off the navigation callback, so a slow answer never blocks WebKit. An answer that takes more than 5 seconds counts as `true`. A synchronous implementation satisfies this requirement too. **Default implementation** A default implementation is provided, so conforming types do not have to implement this. |

# Type Aliases

## KindlyWebViewAuthCredentialsProvider

`typealias`

```swift
public typealias KindlyWebViewAuthCredentialsProvider = @Sendable (_ chatId: String) async throws -> KindlyAuthCredentials
```

Supplies full credentials for an authenticated chat: an id token, a companion access token, an issuer and an expiry hint. Same timing and timeout as `KindlyWebViewAuthTokenProvider`.

## KindlyWebViewAuthTokenProvider

`typealias`

```swift
public typealias KindlyWebViewAuthTokenProvider = @Sendable (_ chatId: String) async throws -> String
```

Supplies a token for an authenticated chat.

Called with the widget's current `chatId` after it connects, when `KindlyWebViewClient`'s `authenticate()` runs, and when the previous credentials are about to expire. Return the JWT (or opaque bearer) for that chat, or throw to leave the chat anonymous.

The SDK waits at most 15 seconds. After that it cancels the task, answers the widget with `provider_timeout`, and the chat continues anonymously; a late result is discarded. An empty string counts as no token (`provider_returned_empty`).

## KindlyWebViewSDK

`typealias`

```swift
public typealias KindlyWebViewSDK = KindlyWebViewClient
```

The entry point of the Kindly web-view chat SDK.

It hosts Kindly's web chat widget in a `WKWebView` with a native bridge. Method names follow the native Kindly SDK: `start`, `displayChat`, `closeChat`, `endChat`, `kill`, `sendMessage`, `triggerDialogue`, `setNewContext`, `clearNewContext`, `authenticate`, `deauthenticate`, `events` and `state`.
