Quickstart
The fastest way to see ChimeKit working end-to-end is: identify an audience member, send them a message, and render the Inbox widget to view it.
You’ll need two things from the Dashboard: a server secret key (for the Server SDK) and a public key (for member-facing widgets). Keep your secret key on the server — never ship it to the browser.
1) Install the UI SDK
Pick the UI package that matches your app.
Install UI SDK
npm install @chimekit/react
2) Add UI styles
Import the global styles once (usually in your app entry point).
Add styles
import "@chimekit/react/styles.css";
// Tailwind (optional): if you want utilities to override ChimeKit styles,
// use your global CSS instead:
// @import "@chimekit/react/styles.css" layer(components);
Tailwind users can keep the JS import. Only use the layered @import when you
want Tailwind utilities to override ChimeKit styles.
3) Render the Inbox (React or Vue)
Wrap the UI with the provider/root component. Use getToken to fetch a member token from your backend (we build that endpoint in step 5).
Inbox setup
import { ChimeKitProvider, Inbox } from "@chimekit/react";
import "@chimekit/react/styles.css";
// Tailwind (optional): if you want utilities to override ChimeKit styles,
// use your global CSS instead:
// @import "@chimekit/react/styles.css" layer(components);
const getToken = async () => {
const response = await fetch("/api/chimekit/token");
if (!response.ok) {
throw new Error("Failed to fetch ChimeKit token");
}
const data = await response.json();
return data.token;
};
export function App({ userId }: { userId: string }) {
return (
<ChimeKitProvider
publicKey={process.env.NEXT_PUBLIC_CHIMEKIT_PUBLIC_KEY!}
audienceMember={{ id: userId }}
getToken={getToken}
>
<Inbox />
</ChimeKitProvider>
);
}
The audienceMember.id should match the externalUserId
you identify on the server.
4) Install the Server SDK
Pick the server SDK for your backend.
Install Server SDK
npm install @chimekit/node
5) Identify a user and create a member token
Use the Server SDK to identify the user (once) and return a member token to the UI. The example below can live in a route like /api/chimekit/token.
Identify + token
import { ChimeKit } from "@chimekit/node";
const ck = new ChimeKit({ secretKey: process.env.CHIMEKIT_SECRET_KEY! });
export async function createMemberToken(userId: string) {
await ck.identify(userId, {
displayName: "Ava Example",
identities: [{ type: "email", value: "ava@example.com", verified: true }],
attributes: { plan: "pro" },
});
return ck.audience.createToken({ userId });
}
If the member is already identified in your system, you can skip the identify call and just find the member instead. However, it doesn't hurt to identify more than once either.
6) Send a message (Dashboard or SDK)
For the fastest validation loop, send a message from the Dashboard to user_123. You can also send one from code:
Send a message
import { ChimeKit } from "@chimekit/node";
const ck = new ChimeKit({ secretKey: process.env.CHIMEKIT_SECRET_KEY! });
await ck.messages.sendMessage("user_123", {
content: {
in_app: {
title: "Welcome to ChimeKit",
body: "If you can read this in the inbox, you're fully wired up.",
},
},
});
Next steps
Keep it simple until you’ve validated the full loop. Then iterate:
- Add email as a second channel: Messaging Channels.
- Move from manual content to reusable templates: Templates.
- Create 2–4 categories so users can manage preferences: Messages.
- Trigger sequences from product events: Workflows.
- See the raw endpoints behind the Server SDK: SDK API Reference.