Embed an AI agent conversation directly into your web app. Choose the level of control that fits your needs — drop-in component, headless state manager, or a single API call.
Drop-in component
One HTML tag, everything handled — input, streaming, scrolling.
<gleap-agent-conversation agentId="YOUR_AGENT_ID"></gleap-agent-conversation>With context and a custom placeholder:
<gleap-agent-conversation
agentId="YOUR_AGENT_ID"
context='{"page": "/billing", "plan": "pro"}'
placeholder="Ask about your billing..."
></gleap-agent-conversation>Attributes
Attribute | Type | Default | Description |
|---|---|---|---|
| string | required | The agent ID |
| string | — | Resume an existing conversation |
| string (JSON) | — | Additional context passed to the agent |
| string |
| Input placeholder |
| string |
| Empty-state text |
| string | primary color | Override accent color |
| boolean | false | Dark mode |
Events
The component dispatches DOM events you can listen to:
const el = document.querySelector("gleap-agent-conversation");
el.addEventListener("gleap-agent-conversation-created", (e) => { /* e.detail */ });
el.addEventListener("gleap-agent-message-sent", (e) => { /* e.detail */ });
el.addEventListener("gleap-agent-reply-received", (e) => { /* e.detail */ });
el.addEventListener("gleap-agent-error", (e) => { /* e.detail */ });The same events also fire on Gleap.on(...) without the gleap- prefix:
Gleap.on("agent-reply-received", (data) => { /* ... */ });
Gleap.on("agent-error", (data) => { /* ... */ });
Gleap.on("agent-conversation-created", (data) => { /* ... */ });Headless with Gleap.createAgentChat()
Manage state and streaming yourself, render any UI you want.
const chat = Gleap.createAgentChat({
agentId: "YOUR_AGENT_ID",
context: { page: "/billing" },
onChange: ({ messages, isExecuting, error, conversationId }) => {
renderMessages(messages);
toggleSpinner(isExecuting);
},
});
chat.sendMessage("What is my current plan?");Options
agentId– the agent to talk to (defaults to"kai").context– arbitrary object passed to the agent.conversationId– resume an existing conversation.onChange({ messages, isExecuting, error, conversationId })– called whenever state changes.onToken,onReplyReceived,onError,onConversationCreated– optional lifecycle callbacks.
Returned instance
sendMessage(content)– send a user message (streams the reply).setContext(context)– update the context for future messages.clearMessages()– clear messages and start a new conversation.cancelStream()– abort the in-flight stream.getState()–{ messages, isExecuting, error, conversationId }.destroy()– tear down listeners. Always call when unmounting.
Each message is { id, role, content, createdAt, isStreaming? }. isStreaming is true while tokens are still arriving.
To clear cached conversation state across the page (e.g. on logout):
Gleap.clearAgentConversation();Raw API
One call, you handle everything else.
const result = await Gleap.sendAgentMessage("YOUR_AGENT_ID", "Hello!", {
conversationId: previousConversationId,
additionalContext: { page: "/billing" },
onToken: (data) => { /* progressive streaming */ },
});
console.log(result.response); // full reply
console.log(result.conversationId); // for follow-up callsReturns a Promise that resolves to { runId, status, response, conversationId }.
TypeScript
The gleap package ships JSX type definitions for the <gleap-agent-*> elements, so they work in TSX without a manual declaration. This requires @types/react 18.2.6 or newer (17.0.51+ / 16.14.41+ on older React lines). If your project shows errors like Type '"span"' is not assignable to type 'ElementType' after installing, run npm i -D @types/react@latest.
Custom styling
The drop-in component renders inside an iframe and accepts agentColor / dark for basic theming. For full control over the UI, use the headless createAgentChat() API and render your own components.

