Install the SDK and get the first answer
From an empty project to the agent answering in your app or on your website: the package, the permissions, configure at launch, the bar, and how to know the agent's settings loaded — on iOS, Android, Flutter, React Native, Kotlin Multiplatform and the web.
The smallest integration that works end to end: the SDK installed, configured once with the agent's publishable key, and the assistant bar on screen. When it works, the launcher appears in your design, and the agent greets you when you open it. About 30 minutes.
What it needs in the dashboard
| Where | Setting | Value |
|---|---|---|
| Agent → Embed & Widgets | Set up embedding | Done once per agent; it creates the publishable key |
| Agent → Embed & Widgets → Install | Publishable key | Copy the pk_live_… key into your app. It is public by design: it selects the agent and cannot read your data |
| Agent → Embed & Widgets → Install | Allowed domains | app:// for apps; each website host, staging included, for the web |
| Agent → Embed & Widgets → Appearance | What visitors get | Call, chat, or both with a switch |
The agent itself — its prompt, voice and greeting — is whatever you built in the dashboard; test it there first.
What to do, in order
- Install the package, and declare the microphone (the voice bar asks for it when a call starts).
- Configure once, at launch, with
baseUrlhttps://www.graine.aiand the publishable key. The SDK loads the agent's settings — its design, what visitors get, its actions, its calling and booking rules — and keeps them on the device, so the next launch starts at once. - Put the bar on screen. It draws the launcher, the voice call, the chat and the components in your design.
- Check the settings loaded — a listener, a hook or a promise, per platform.
- Open the bar and talk, or type. The agent greets you.
- Clean up only what you added yourself: a listener you registered.
The code, platform by platform
1. Install. Xcode → File → Add Package Dependencies… →
https://github.com/GraineAI/inapp-ios, from 0.9.0; add the GraineInApp
library to your app target. Add NSMicrophoneUsageDescription to Info.plist.
2. Configure at launch — once, before any screen uses the agent:
→ GraineInApp.shared is the agent from now on; the settings load in the
background.
3. Put the bar on screen:
→ The launcher appears in your design once the settings arrive.
4. Check the settings loaded:
→ onSessionReady fires once per launch with a GraineSessionConfig;
GraineInApp.shared.session holds it afterwards.
5. The first answer. Tap the launcher and speak, or switch to the chat and type. → The agent greets you; captions show under the bar.
6. Clean up: GraineInApp.shared.removeListener(status) when the screen that
added it goes away.
Troubleshooting
| What you see | Why | Fix |
|---|---|---|
Nothing appears; the log or console says 403 or origin_refused | app:// (apps) or the site's exact host is missing from Allowed domains | Add it under Embed & Widgets → Install |
Nothing appears; invalid_key | The key is not one, or the agent was deleted | Copy the key again from Embed & Widgets → Install |
| The bar shows Needs microphone | The microphone was not declared, or the customer refused it | Permissions |
| The design is the default one | The settings have not loaded yet, or the design was not saved | Wait for the settings; Save design in the Garage, then restart the app |
| The agent never speaks | The agent has no greeting, or the call never connected | Try the agent in the dashboard first; Voice → Troubleshooting |
Next: identify the user, then every other use case — Use cases by SDK.

