Quickstart
Flutter, from install to a grounded sandbox answer in ten minutes.
Rendel embeds a copilot into your app that answers with native UI components and executes registered actions behind risk-level guardrails. This page takes you from zero to a working copilot on a test key.
You need a Flutter app and a test key. You do not need a backend: an action can return a hardcoded map and the whole path still works.
1. Install the SDK
dependencies:
rendel:
git:
url: https://github.com/neon-apps/rendel.git
path: sdk/flutter/rendel
ref: v0.33.0The package is in private pilot and not on pub.dev yet. Install the SDK covers access, the Dart and Flutter floors, and what you need ready — including the part that surprises people, which is that you need nothing on your backend.
2. Add the platform permissions
The composer's microphone and its "+" — Photos, Camera and Files — are built in. Photos and Files need no permission on either platform; the microphone and the camera need these.
iOS — required. Open ios/Runner/Info.plist and add these three lines
inside the top-level <dict>, in your own words. Apple shows them to your
users in your app's name, which is why no package can add them for you:
<key>NSMicrophoneUsageDescription</key>
<string>Lets you speak to the assistant instead of typing.</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>Turns what you say into text for the assistant.</string>
<key>NSCameraUsageDescription</key>
<string>Lets you take a photo to show the assistant.</string>Skip them and the copilot still works, without a microphone or Camera: the
SDK leaves them out rather than letting iOS close your app, and logs
usage_description_missing.
Android — already done by the SDK. Its own manifest declares these, and
the build merges them into android/app/src/main/AndroidManifest.xml. They
are what your app will ask for; adding them inside <manifest>, above
<application>, changes nothing:
<!-- The SDK already declares both; adding them here changes nothing. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />3. Initialize with your test key
Your app's key tells Rendel which app is asking. Get it from the console: open your app's Settings → API keys and press Copy beside the Test key (rd_pk_test_...) — the same key is on the app's Overview, in the SDK step. Without it the copilot cannot start. Publishable keys are safe to embed; they identify your app and environment, nothing more.
await Rendel.init(
// Your app's key: Rendel console → Settings → API keys → Copy.
appKey: 'rd_pk_test_...',
theme: RendelTheme.paper(),
config: RendelConfig(languages: ['tr']),
);languages is what the copilot answers in. Name one and it answers only in
that one, whatever the user writes in — Turkish here. Name several, ['tr', 'en'], and it answers in whichever of them the user writes or the phone is
set to, and in the first for anything else. Leave it out and it answers in
whatever it is addressed in. The same list can be set without a build under
Experience → Persona in the console; the one in code wins.
The SDK talks to https://api.rendel.ai by default while the pilot runs. If your build needs to point elsewhere, pass RendelConfig(apiBaseUrl: ...) to init.
Swap paper() for your own tokens once it runs. See Theming.
4. Tell it who is signed in
The SDK cannot see your login. Until you tell it, a person is a device: one row per phone on the console's Users page, and nothing the copilot learns about them follows them to another phone. So, right after sign-in, hand it your own id for the person:
await Rendel.identify(
userId: user.id,
traits: {'plan': 'pro'},
);userId is the id your own system uses for this person — the primary key in
your database, or your auth provider's uid. Stable, and never an email or a
phone number. traits is optional and yours to overwrite; what you put there
the copilot knows about them, so their plan or the ids of their orders let it
answer "my order" without asking.
Once is enough: the SDK remembers who is signed in across launches, so a
restored session needs no second call. Every message carries that id, and two
people who share a phone keep two histories. On sign-out, call
Rendel.reset(): the next message is anonymous, never the last
person's.
With identity verification on, the call also carries a signature from your backend, which is what stops one user asking about another's orders. See Context.
Let it reach your API as them
The copilot can answer from your own API — "my order", "my routine" — as the person asking, with no API key to issue. Give the SDK their current token from your own sign-in, and in the console set those endpoints to the signed-in user's token:
await Rendel.init(
// Your app's key: Rendel console → Settings → API keys → Copy.
appKey: 'rd_pk_test_...',
config: RendelConfig(
languages: ['tr'],
userToken: () async => auth.accessToken,
),
);It is asked for before every question, so return the current one — your auth
library refreshes it when it runs out — and null when nobody is signed in. It
goes with the question and on to your endpoints as Authorization: Bearer, is
never stored, and each person reaches only what their own token opens.
5. Register your first action
Actions are the only things the copilot can do. Each one is typed, carries a risk level, and runs inside your app with the user's own session.
Rendel.registerAction(RendelAction(
name: 'get_order_status',
description: 'Fetch the delivery status of an order',
params: RendelSchema.object({'order_id': RendelSchema.string()}),
risk: RendelRisk.read,
handler: (params) async {
final order = await api.fetchOrder(params['order_id']);
return RendelResult.ok(order.toJson());
},
));6. Open the copilot
Rendel.open(context);Or drop const RendelLauncher() anywhere in your widget tree for a floating
entry point that opens it.
Ask something your action can answer: "Where is my order 1042?" The copilot calls get_order_status, your handler runs, and the answer renders as an order_tracker component.
7. Add knowledge
Paste your FAQ or policies into the console under Knowledge. Once embeddings are switched on for the deployment, questions like "What is your return policy?" answer from your own content rather than from the model's general knowledge. The console tells you whether they are.