Agent Run View and Web Embedding
Open an Agent in the Chat / Run pages, or embed it into third-party sites with the official embed.js SDK
Once an Agent is configured and published, Clouisle offers two delivery channels:
- In-app run pages: full conversational UIs for authenticated users. Agents use Chat (
/chat/{agent_id}); workflows use Run (/run/{workflow_id}?type=workflow). - Web embedding: embed a published Agent or workflow into an external website using a team API key (
clou_...), in bubble, fullscreen, or mobile form.
1. In-App Run Pages
The run pages drop the Studio's editor sidebar and drawers and focus on the task at hand:
┌────────────────────────────────────────────────────────────────────────┐
│ 🤖 Financial Analyst Agent [Team: Finance] │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ 🤖 Financial Analyst │
│ Upload quarterly earnings reports or ask financial modeling questions │
│ │
│ [Analyze Q3 Revenue] [Model Cashflow] [Compare Competitors] │
│ │
│ 👤 User: Analyze the uploaded Q3 report. │
│ │
│ 🤖 Financial Analyst: │
│ 💭 Thought for 2.4s (Reading file: Q3_Financials.pdf)... │
│ Here is the summary of Q3 financial performance... │
│ │
├────────────────────────────────────────────────────────────────────────┤
│ [📎] Ask a question or drop a spreadsheet... [Send] │
└────────────────────────────────────────────────────────────────────────┘Opening a run page
- Go to the Apps page (
/app/apps). - Hover an app card and open its ... menu:
- For an Agent, select Chat to open
/chat/{agent_id}in a new tab. - For a workflow, select Run to open
/run/{workflow_id}?type=workflowin a new tab.
- For an Agent, select Chat to open
- You can also navigate directly to
/run/{id}: this unified run route serves an Agent by default and switches to a workflow with?type=workflow.
Features
- Distraction-free canvas: optimized for deep interaction, document analysis, and iterative multi-turn conversations.
- Dynamic variable prompting: if the Agent defines required variables (e.g.
client_id,locale), the run page shows a structured input banner before the session starts. - Full capabilities: attachments, image lightbox, document previews,
ask_userforms, and multi-version message branching.
2. Web Embedding: Enable and Configure
Embedding renders the same app/workflow run page inside an iframe, so the target must be published first.
Enabling embedding
- Open your Agent in the Agent Studio (
/app/apps/{agent_id}). - Confirm the Agent is Published — when it is not, the drawer shows a yellow warning and saving stays disabled.
- Click the Embed button on the top toolbar to open the embed configuration drawer.
- Toggle Enable Embedding on.
- Paste a team API key (
clou_...) into the snippet field; it is inserted into the generated code below.
Drawer options
| Option | Description | Default |
|---|---|---|
| Enable embedding | Allow this app to be embedded in external sites via iframe | Off |
| Allowed domains | Restrict which origins may load the widget; empty allows every domain. Wildcard subdomains supported; separate multiple values with commas or newlines | Empty (allow all) |
| Show header | Show the app icon and name at the top of the embed | On |
| Show history | Show a history sidebar in the embed (stored in the browser) | On |
| Allow new | Allow visitors to start a new chat/run | On |
| Theme | Widget theme: auto / light / dark | auto |
| Primary color | Brand accent color, #RGB or #RRGGBB | Empty (bubble uses #6366f1) |
| Bubble position | Floating bubble placement: bottom-right / bottom-left | bottom-right |
| Bubble greeting | Message shown beside the bubble before it is first opened | Empty |
Allowed domains
Empty means every origin is allowed. Once populated, the backend validates the request's Origin header (falling back to Referer) and rejects other origins with 403 embed_domain_not_allowed. https://example.com, *.example.com (matches subdomains), and values with a port are accepted; malformed values fail validation on save. Requests without either header are allowed (handy for local testing).
The configuration is stored on the Agent/workflow as embed_config (fields: enabled, show_header, show_history, allow_new, allowed_domains, theme.mode, theme.primary_color, bubble.position, bubble.icon, bubble.greeting). bubble.icon has no editor control today, so setting it has no visible effect.
3. Integration Code
The three tabs at the bottom of the drawer (Bubble / Fullscreen / Mobile) decide which snippet is generated; all three target the same iframe page, /embed/agent/{agent_id} or /embed/workflow/{workflow_id}.
Option A: Bubble mode (recommended)
Bubble mode loads the official SDK /embed.js and calls Clouisle.init(...):
<script src="https://<your-domain>/embed.js"></script>
<script>
Clouisle.init({
type: 'agent',
id: '550e8400-e29b-41d4-a716-446655440000',
token: 'clou_a1b2c3d4e5f6...',
mode: 'bubble',
theme: 'auto',
primaryColor: '#2563eb',
position: 'bottom-right',
greeting: 'Hi! How can I help you?',
});
</script>Clouisle.init options (id and token are required — the SDK logs an error and renders nothing if either is missing):
| Option | Type | Default | Description |
|---|---|---|---|
type | 'agent' | 'workflow' | 'agent' | Target type; determines the iframe path |
id | string | — | Agent / workflow UUID, required |
token | string | — | Team API key (clou_...), required |
mode | 'bubble' | 'fullscreen' | 'mobile' | 'bubble' | Presentation mode |
theme | 'light' | 'dark' | 'auto' | 'auto' | Embed page theme; auto follows the system |
primaryColor | string | Empty | Bubble button color (bubble mode only); foreground is picked for contrast |
position | 'bottom-right' | 'bottom-left' | 'bottom-right' | Screen edge for the bubble and chat window |
greeting | string | Empty | Tooltip beside the bubble; clicking it opens the chat |
container | string (CSS selector) | body | Fullscreen mode only; a missing container logs an error and aborts |
The bubble instance exposes Clouisle.open(), Clouisle.close(), and Clouisle.destroy(). Calling init again first destroys the previous instance. The SDK also listens for the iframe's clouisle:close message to collapse the bubble.
Option B: Fullscreen / mobile mode (plain iframe)
Fullscreen and mobile do not need JS — the drawer emits an iframe pointing at /embed/...:
<!-- Fullscreen: fills a container on the page -->
<iframe
src="https://<your-domain>/embed/agent/550e8400-e29b-41d4-a716-446655440000?token=clou_a1b2c3d4e5f6...&mode=fullscreen"
style="width: 100%; height: 100%; border: none;"
allow="clipboard-write"
></iframe><!-- Mobile: covers the viewport -->
<iframe
src="https://<your-domain>/embed/agent/550e8400-e29b-41d4-a716-446655440000?token=clou_a1b2c3d4e5f6...&mode=mobile"
style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; border: none; z-index: 9999;"
allow="clipboard-write"
></iframe>Fullscreen can also be initialized through the SDK with a container: Clouisle.init({ type: 'agent', id: '...', token: '...', mode: 'fullscreen', container: '#chat' }).
iframe query parameters
The SDK and the drawer build URLs against /embed/{type}/{id} with these parameters:
| Parameter | Description |
|---|---|
token | Team API key; alternatively send an Authorization: Bearer <key> header |
mode | fullscreen (default when absent) or bubble; mobile and fullscreen both render edge-to-edge in the container |
theme | light / dark; absent or auto follows the system |
color | Primary color (the SDK includes it, but the embed page does not read it, so it does not affect the iframe's internal palette) |
Embed history is stored in the visitor's browser. With show_history off the embed hides the history sidebar; with allow_new off visitors cannot start a new conversation.
4. Security and Access Control
- API keys only:
/api/v1/embed/**accepts onlyclou_...API keys (via thetokenquery parameter orAuthorization: Bearer), never user JWTs. - Keys belong to a user: every API key is bound to the user who created it (
APIKey.user), and the embedded session runs as that user. scopesare not enforced: thescopesfield is stored and returned, but the authorization code never reads it, so it cannot narrow access.- Narrow access via bindings: an API key is bound to accessible objects through the
agents/workflowsmany-to-many relations. A key with bindings can reach only those objects; a key with no bindings can reach everything (backward compatibility) — so always bind an embed key to its target Agent/workflow. - Three server-side checks: the target must match the key's binding (otherwise
403 api_key_no_agent_access), must be published (otherwise404 agent_not_found), and must have embedding enabled (otherwise403 embed_not_enabled), on top of the domain check. - Rate limiting: the key's
rate_limit(default1000/minute;0means unlimited) is not currently enforced in the request path; embedded chats are bounded by provider rate limits and team model quotas. - Isolated scope: embedded sessions cannot reach team model management, site settings, or admin-only endpoints.
API Endpoints
The embed endpoints live under /api/v1/embed and accept API-key authentication only:
# Agent
GET /api/v1/embed/agents/{agent_id}/info
POST /api/v1/embed/agents/{agent_id}/chat/stream
POST /api/v1/embed/agents/{agent_id}/chat/runs
GET /api/v1/embed/agents/{agent_id}/chat/runs/{run_id}/stream
GET /api/v1/embed/agents/{agent_id}/conversations/{conversation_id}/messages
POST /api/v1/embed/agents/{agent_id}/upload/file
# Workflow
GET /api/v1/embed/workflows/{workflow_id}/info
POST /api/v1/embed/workflows/{workflow_id}/runHow is this guide?