> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clariodesk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Install with AI

> Paste one prompt into Claude Code, Cursor, or Codex and your agent integrates ClarioDesk end to end — it detects your stack, asks the right questions, and verifies with a real message.

The fastest way to integrate ClarioDesk is to not write the integration
yourself. Copy the prompt below into your AI coding agent (Claude Code, Cursor,
Codex, or any agent that can edit your project), replace the placeholder with
your app's publishable key, and let it work.

The prompt makes the agent:

* **detect your framework** — Flutter, bare React Native, or Expo (including
  the Expo Go evaluation lane),
* **ask you the decisions that are actually yours** — prebuilt chat UI vs.
  building screens in your own design system, where support opens from, push
  now or later, attachments,
* **consult these docs instead of guessing** — every step links the exact
  reference page, and the [rules for AI agents](/concepts/agent-rules) are
  embedded,
* **verify the result** — it finishes by round-tripping a real message to your
  dashboard inbox, not by declaring success.

<Note>
  Your `pk_live_` key is **publishable** — it's safe to paste into a prompt and
  ship in your app binary. It can only register devices; it can't read tickets.
  Get it at [dashboard.clariodesk.com](https://dashboard.clariodesk.com) → your app → API key.
  When you create a new app, the dashboard shows this same prompt with your key
  already filled in.
</Note>

## The prompt

````markdown theme={null}
# Add ClarioDesk In-App Support

Integrate the ClarioDesk SDK so users can contact support and report bugs from
inside this app, and replies from the support dashboard stream back live.

Your publishable API key for this integration: `pk_live_YOUR_KEY`

## Quick setup

Before running any commands or editing any files, present the user with this
checklist:

```
Here's what I'll do to add ClarioDesk in-app support.

1. Detect your framework (Flutter, bare React Native, Expo, or native iOS/Swift)
2. Ask a few questions about how you want support to work
3. Install the SDK and initialize it with your API key
4. Add a support entry point (prebuilt chat UI, or headless in your own UI)
5. Verify it works by sending a real test message

Shall I proceed?
```

## Step 1: Detect the stack

Inspect the project root:

- `pubspec.yaml` present → **Flutter**.
- `package.json` with an `expo` dependency (or `app.json`/`app.config.*` with an
  `expo` key) → **Expo**. Then determine the lane: if the project uses a dev
  client / EAS builds (`expo-dev-client` dependency, `eas.json`) it gets the
  full experience; if the user only runs Expo Go, everything works for
  evaluation but the device key is a software fallback and remote push is
  unavailable — say so, and recommend a dev build before shipping.
- `package.json` with `react-native` but no `expo` → **bare React Native**
  (old vs. New Architecture doesn't matter — the SDK supports both; don't
  branch on it).
- An `.xcodeproj`/`.xcworkspace` (or a `Package.swift` app target) with no
  Flutter/RN markers → **native iOS (Swift)**. Requires iOS 16+; if the
  deployment target is lower, say so before proceeding.
- Empty or non-mobile directory → ask which framework the user wants; offer to
  scaffold (`flutter create` / `npx create-expo-app`) and continue.

## Step 2: Ask the integration decisions

Ask the user these questions before writing code. Do not assume answers you
cannot infer from the codebase; if the user has no preference, use the marked
default.

1. **Prebuilt UI or your own?** The prebuilt chat UI is themeable and ships a
   complete inbox → thread → new-ticket → bug-report flow with one call
   *(default)*. Alternatively, integrate headless and render support screens in
   the app's own design system — more work, fully native look.
2. **Where does support open from?** A settings row, a "Help" button, a menu
   item — find where the app keeps such actions and propose a spot.
3. **Push notifications for agent replies — now or later?** Later is fine and
   is the default; it's additive. (Requires Firebase setup on the host app;
   Expo Go can't do remote push at all.)
4. **Attachments (screenshots/photos on messages) — enabled?** Default yes for
   the prebuilt UI if the app already has photo permissions, otherwise ask —
   iOS requires photo-library/camera usage strings in Info.plist.

## Step 3: Install and initialize

### Flutter

```bash
flutter pub add clariodesk
```

Initialize at app start, before `runApp`:

```dart
import 'package:clariodesk/clariodesk.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // First launch generates a hardware-backed device key and registers it.
  // Later launches reuse it — no network round-trip.
  await ClarioDesk.init(apiKey: 'pk_live_YOUR_KEY');
  runApp(const MyApp());
}
```

Platform floors: iOS 13+, Android API 23+.

### React Native (bare and Expo)

```bash
npm install @clariodesk/react-native react-native-get-random-values
```

(Substitute the project's package manager: pnpm/yarn/bun per the lockfile.)

Secure storage peer — pick one:

```bash
npx expo install expo-secure-store        # Expo
npm install react-native-keychain         # bare RN
```

**Expo**: add the config plugin to app.json, then make a dev build:

```jsonc
{ "expo": { "plugins": ["@clariodesk/react-native"] } }
```

```bash
npx expo prebuild && npx expo run:ios
```

(Skip prebuild for Expo Go evaluation — the SDK transparently uses a software
key there.)

**Bare RN**: run `npx install-expo-modules@latest` once (the device-key native
module is an Expo Module), then `cd ios && pod install`.

Initialize — and note the RNG import **must be the first import in the app
entry file** (index.js), before anything else:

```ts
// index.js — very first line:
import 'react-native-get-random-values';

import { ClarioDesk } from '@clariodesk/react-native';

await ClarioDesk.init({ apiKey: 'pk_live_YOUR_KEY' });
```

### Native iOS (Swift)

Add the package via Swift Package Manager — in Xcode, File → Add Package
Dependencies… with the URL, or in Package.swift:

```swift
.package(url: "https://github.com/clariodesk/clariodesk-swift", from: "0.1.1")
```

Link the products the app needs: `ClarioDesk` (headless core) and — for the
prebuilt UI lane — `ClarioDeskUI`. A headless host links only `ClarioDesk`;
Swift dead-strips the UI. Requires iOS 16+.

Initialize at app start (fire-and-forget, no await — AppDelegate or the
`App` initializer):

```swift
import ClarioDesk

ClarioDesk.initialize(.init(apiKey: "pk_live_YOUR_KEY"))
```

The device key is CryptoKit/Secure Enclave-backed (software fallback on the
simulator). Note: an **unsigned** host can't write the Keychain
(`errSecMissingEntitlement -34018`) — real signed apps are unaffected.

### Wire identity (all platforms)

First check whether Dashboard → Verified identity is enabled for this app.
Without it, `identify()` is label-only metadata and should be called in two
places; with it, use the configured token provider and the ordered lifecycle in
`references/identity-and-keys.md` instead.

1. **On every app launch**, hydrated from the app's persisted session. This is
   the step integrations most often miss: existing logged-in users never pass
   through the login screen again, so a login-only hook leaves them unlabeled.
2. **Right after a fresh login/signup.**

```dart
// Flutter
await ClarioDesk.identify(externalId: user.id, email: user.email, traits: {'plan': user.plan});
```

```ts
// React Native
await ClarioDesk.identify({ externalId: user.id, email: user.email });
```

```swift
// Swift
try await ClarioDesk.identify(externalId: user.id, email: user.email)
```

In label-only mode, acknowledged `reset()` → `init()` can isolate a shared
device. In Verified identity mode, logout/account switch must await
`clearIdentity()` before changing the host user; `reset()` is reserved for
removing this installation.

If the app has no auth, skip `identify()` entirely — anonymous tickets work;
the dashboard shows the device with an "Unverified device" badge.

## Step 4: Add the support UI

### Prebuilt UI lane (default)

**Flutter** — pass a theme at init so the modal matches the app, then open it
from the entry point chosen in Step 2:

```dart
await ClarioDesk.init(
  apiKey: 'pk_live_YOUR_KEY',
  theme: ClarioDeskTheme(
    primaryColor: /* app accent */,
    backgroundColor: /* app background */,
    surfaceColor: /* cards/bubbles */,
    textColor: /* primary text */,
    mutedTextColor: /* secondary text */,
    appBar: ClarioDeskAppBarTheme(title: 'Support'),
  ),
);

// From the entry point:
ClarioDesk.openInbox(context);
```

Pull the actual colors from the app's existing theme/design tokens — do not
invent a palette. The theme surface is deliberately small (colors + app bar
only); if the user wants more control than that, they want the headless lane.

**React Native** — wrap the app once, open from anywhere:

```tsx
import { ClarioDeskProvider, openInbox } from '@clariodesk/react-native/ui';

<ClarioDeskProvider theme={{ primary: brand.accent, cornerRadius: 18, mode: 'system' }}>
  <App />
</ClarioDeskProvider>;

// From the entry point:
openInbox();   // also: openTicket(id), openNewConversation(), openBugReport()
```

**Swift** — one call from SwiftUI or UIKit; the modal presents on the
top-most view controller:

```swift
import ClarioDeskUI

// From the entry point:
ClarioDeskWidgets.openInbox(theme: ClarioDeskTheme(primary: /* app accent */))
// also: openBugReport()
```

The theme is 13 optional tokens — unset ones derive light/dark from the
system; pull any you do set from the app's existing design tokens.

The prebuilt UI presents in a self-owned modal — it never touches the app's
navigation (GoRouter/Navigator 2.0/react-navigation/SwiftUI NavigationStack
all unaffected).

If attachments were enabled in Step 2 (React Native): install the picker peers
(`npx expo install expo-image-picker expo-document-picker expo-image-manipulator`
for Expo; `npm install react-native-image-picker @react-native-documents/picker`
for bare RN), pass a `picker` to `ClarioDeskProvider`, and add the iOS usage
strings (`NSPhotoLibraryUsageDescription`, plus camera/microphone if camera
capture is on) to Info.plist.

### Headless lane (custom UI in the app's design system)

Build the support screens with the app's own components on top of the SDK's
methods and live subscriptions. Follow the API exactly as documented — do not
guess method names:

- Flutter: https://docs.clariodesk.com/flutter/api-reference
  (`createTicket`, `sendMessage`, `ticketsStream()`, `messagesStream(id)`, …)
- React Native: https://docs.clariodesk.com/react-native/api-reference — use
  the hooks (`useTickets`, `useMessages`, `useConnection`, …) from
  `@clariodesk/react-native/hooks`.
- Swift: https://docs.clariodesk.com/swift/api-reference — replay-last
  `AsyncStream` reads (`for try await tickets in ClarioDesk.tickets`) from
  SwiftUI, or the closure variants (`subscribeTickets { … }`) from UIKit.

Match the app's existing screens: reuse its list items, buttons, spacing, and
color tokens so the support flow looks native to the app. Render optimistic
state: a message with `pending: true` shows "sending…", `failed: true` gets
tap-to-retry via `retryMessage`.

## Step 5: Push notifications (only if chosen in Step 2)

**React Native** — push is a deliberately separate package (Firebase's native
code must not autolink into apps that didn't opt in):

```bash
npm install @clariodesk/react-native-push @react-native-firebase/app @react-native-firebase/messaging
```

```ts
import { FirebaseTokenProvider } from '@clariodesk/react-native-push';
await ClarioDesk.init({ apiKey: 'pk_live_YOUR_KEY', pushTokenProvider: new FirebaseTokenProvider() });
```

Register the background handler in index.js at startup (the #1 push
setup-failure cause), and route notification taps with
`ClarioDesk.openTicketFromPush(data)`. Full guide:
https://docs.clariodesk.com/react-native/push

**Flutter** — the SDK takes an FCM token through a `PushTokenProvider` seam
(it never imports firebase_messaging itself). Follow
https://docs.clariodesk.com/concepts/push-notifications for the wiring.

**Swift** — APNs-direct, **no Firebase**. Forward the raw APNs token from the
AppDelegate — that's the whole wiring:

```swift
func application(_ app: UIApplication,
                 didRegisterForRemoteNotificationsWithDeviceToken token: Data) {
  ClarioDesk.setAPNSDeviceToken(token)
}
```

Full guide: https://docs.clariodesk.com/swift/push

Every platform also needs the app's push credentials uploaded once in the
ClarioDesk dashboard (app settings → push): FCM service account for
Flutter/React Native, an APNs `.p8` key for Swift.

## Step 6: Verify

Run the app (`flutter run` / `npx expo run:ios` / `npx react-native run-ios`
/ Xcode ⌘R). Then, as the user would:

1. Open the support entry point and send a message ("test from ClarioDesk
   setup").
2. Confirm the message appears in the dashboard inbox at
   https://dashboard.clariodesk.com — if the app-setup page is open, its
   "Watching for devices" check flips as soon as the app registered.
3. Reply from the dashboard and confirm the reply streams into the app live
   (no restart).

If registration or realtime fails, check the troubleshooting guides:
https://docs.clariodesk.com/integrate-flutter /
https://docs.clariodesk.com/integrate-react-native /
https://docs.clariodesk.com/integrate-swift

## When unsure, use the docs

Never guess an API. Every page below is also available as plain markdown for
you to fetch, and https://docs.clariodesk.com/llms.txt indexes everything.

| Topic | URL |
|---|---|
| Quickstart (all platforms) | https://docs.clariodesk.com/quickstart |
| Flutter integration walkthrough | https://docs.clariodesk.com/integrate-flutter |
| Flutter install / lifecycle / prebuilt UI / API | https://docs.clariodesk.com/flutter/installation · /flutter/lifecycle · /flutter/prebuilt-ui · /flutter/api-reference |
| React Native integration walkthrough | https://docs.clariodesk.com/integrate-react-native |
| RN install / lifecycle / prebuilt UI / push / API | https://docs.clariodesk.com/react-native/installation · /react-native/lifecycle · /react-native/prebuilt-ui · /react-native/push · /react-native/api-reference |
| Swift integration walkthrough | https://docs.clariodesk.com/integrate-swift |
| Swift install / lifecycle / prebuilt UI / push / API | https://docs.clariodesk.com/swift/installation · /swift/lifecycle · /swift/prebuilt-ui · /swift/push · /swift/api-reference |
| How auth works (device-is-identity) | https://docs.clariodesk.com/concepts/authentication |
| Identity lifecycle (launch/login/logout/switch) | https://docs.clariodesk.com/concepts/identity-lifecycle |
| Attachments / realtime / CSAT | https://docs.clariodesk.com/concepts/attachments · /concepts/realtime · /concepts/csat |
| Rules for AI agents | https://docs.clariodesk.com/concepts/agent-rules |

## Critical rules

- `pk_live_YOUR_KEY` is a **publishable** key — safe to ship in the app
  binary. It can only register new devices; it cannot read tickets or
  impersonate users. There is no secret key and no `appId` — the key encodes
  the app.
- The SDK's device key always authenticates requests. Do not invent additional
  auth in label-only mode. If Verified identity is enabled, use exactly its
  configured host-token/OIDC profile and never ship the signing secret.
- Label-only mode identifies on every launch. Verified mode uses a fresh proof
  on session restore/login and `clearIdentity()` before logout/switch;
  `reset()` deprovisions only this installation.
- Don't mix modes: either the prebuilt UI owns the support screens, or the
  app's custom screens do — not both for the same flow.
- React Native: `import 'react-native-get-random-values'` must be the **first
  import** in the entry file.
- React Native push lives in `@clariodesk/react-native-push` — never add
  Firebase packages to an app that didn't opt into push.
- Native iOS (Swift) push is APNs-direct — never add Firebase to a Swift
  host; the raw APNs token is all the SDK needs.
- Expo Go is for evaluation only (software device key, no remote push) — ship
  with a dev build.
- Do not read or print the contents of the user's `.env` or credential files;
  the only credential this integration needs is the publishable key above.

## After setup

Tell the user to send themselves a first support message from the app, then
reply to it from the dashboard inbox (https://dashboard.clariodesk.com) and
watch it arrive in-app live. Suggest exploring next: push notifications for agent
replies, attachments, and CSAT ratings — each is an additive follow-up
(https://docs.clariodesk.com).
````

## Connect the docs MCP server

These docs also run a hosted MCP server at `https://docs.clariodesk.com/mcp`
(tools: `search_clario_desk` for search, `query_docs_filesystem_clario_desk`
for reading pages). With it connected, your agent retrieves live ClarioDesk
docs mid-task instead of guessing.

<CodeGroup>
  ```bash Claude Code theme={null}
  claude mcp add --transport http clariodesk-docs https://docs.clariodesk.com/mcp
  ```

  ```json Cursor (.cursor/mcp.json) theme={null}
  {
    "mcpServers": {
      "clariodesk-docs": { "url": "https://docs.clariodesk.com/mcp" }
    }
  }
  ```

  ```json VS Code (.vscode/mcp.json) theme={null}
  {
    "servers": {
      "clariodesk-docs": { "type": "http", "url": "https://docs.clariodesk.com/mcp" }
    }
  }
  ```
</CodeGroup>

## Working docs-first instead?

If you'd rather have your agent research as it goes, point it at the
machine-readable docs:

* [`llms.txt`](https://docs.clariodesk.com/llms.txt) — index of every page;
  [`llms-full.txt`](https://docs.clariodesk.com/llms-full.txt) — the full docs
  in one file.
* The distilled [rules for AI agents](/concepts/agent-rules).
* Every page here can be pulled as markdown by appending `.md` to its URL, or
  through the docs MCP server above.
