Domain Assistant — chatbot widget embedding guide
Audience: Domain admins (setup) and website developers (embed code).
Goal: Add the Aventora chat widget (floating CTA button or embedded panel) to your website so visitors can start a conversation with Domain Assistant.
Use with: AD_CAMPAIGNS_TO_ENGAGEMENT.md when the widget is the conversion point for paid ad landing pages.
Related docs:
- AVENTORA_USER_MANUAL.md — configure bot knowledge, welcome message, and logs
- platform-api-keys.md — how domain API keys fit the platform (technical reference)
Table of contents
- Overview
- What you need from Aventora
- Step 1 — Generate a domain API key
- Step 2 — Create a server-side token endpoint
- Step 3 — Embed the widget on your site
- Widget options (floating CTA vs embedded panel)
- Landing-page CTA buttons
- How it works
- Testing checklist
- Production and security
- Troubleshooting
Overview
The chatbot loads in the visitor’s browser as a widget (corner bubble) or embedded panel. Authentication uses short-lived tokens generated on your server — the domain API key never goes in HTML or JavaScript visible to the browser.
| Piece | Who provides | Example |
|---|---|---|
| Domain slug | Aventora | acme |
| Chatbot app URL | Aventora | https://acme.aventora.app |
| Domain-chatbot API URL | Aventora | https://api.aventora.ai |
| Domain API key | You generate in Admin | Stored in server env only |
| Token endpoint | Your developer | https://yoursite.com/api/chatbot-token |
| Embed snippet | Your developer | Script tag on landing pages |
What you need from Aventora
Before embedding, confirm with your Aventora contact (or onboarding):
| Item | Description |
|---|---|
Domain slug (tenant) | Your Domain Assistant tenant name |
| Chatbot base URL | Usually https://{domain-slug}.aventora.app |
| Domain-chatbot API URL | Apex API for token generation (e.g. https://api.aventora.ai) |
| Widget script URLs | Where to load widget.js and aventora-chat.js (CDN or self-hosted copy) |
| Admin access | To generate domain API keys under Settings → Domain API Keys |
If you use Aventora CMS, the widget may already be toggled on campaign templates — ask your contact before custom embed work.
Step 1 — Generate a domain API key
- Sign in to Aventora Admin as a domain admin.
- Open Settings (domain settings for your tenant).
- Find Domain API Keys.
- Click Generate API Key.
- Name it (e.g.
Website embedding — production). - Copy the key immediately — it is shown only once.
- Store it in your server environment (see Step 2). Never commit it to git or paste it into front-end code.
This key authorizes your server to call:
POST {DOMAIN_CHATBOT_API_URL}/auth/api/v1/tokens/generate
Authorization: Bearer {DOMAIN_API_KEY}
Step 2 — Create a server-side token endpoint
Your website must expose an HTTPS endpoint the widget can call from the browser. That endpoint calls domain-chatbot with the API key and returns a token.
Required behavior
| Rule | Detail |
|---|---|
| Server-side only | API key stays in environment variables on your backend |
| HTTPS in production | Required for microphone/voice features |
| Response shape | { "token": "...", "expires_at": "..." } (ISO 8601 expiry optional) |
| Default path | Widget expects /api/chatbot-token unless you override data-token-api-url |
Example environment variables (your server)
DOMAIN_CHATBOT_API_URL=https://api.aventora.ai
DOMAIN_CHATBOT_API_KEY=your-domain-api-key-from-step-1
CHATBOT_BASE_URL=https://acme.aventora.app
Example token handler (Node.js / Express)
app.post('/api/chatbot-token', async (req, res) => {
try {
const language = req.body?.language || 'en';
const response = await fetch(
`${process.env.DOMAIN_CHATBOT_API_URL}/auth/api/v1/tokens/generate`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.DOMAIN_CHATBOT_API_KEY}`,
},
body: JSON.stringify({
username: 'anonymous',
language,
expires_in_hours: 24,
}),
},
);
if (!response.ok) {
return res.status(response.status).json({ error: 'Token generation failed' });
}
const tokenData = await response.json();
return res.json({
token: tokenData.token,
expires_at: tokenData.expires_at,
});
} catch (error) {
console.error('chatbot-token error', error);
return res.status(500).json({ error: 'Failed to generate token' });
}
});
Adapt the same pattern for PHP (Laravel), Python (FastAPI/Flask), WordPress (custom REST route), or your host’s serverless function.
Example token handler (PHP / Laravel route)
Route::post('/api/chatbot-token', function (Illuminate\Http\Request $request) {
$response = Http::baseUrl(rtrim(config('services.domain_chatbot.url'), '/'))
->withToken(config('services.domain_chatbot.api_key'))
->post('auth/api/v1/tokens/generate', [
'username' => 'anonymous',
'language' => $request->input('language', 'en'),
'expires_in_hours' => 24,
])
->throw();
return response()->json([
'token' => $response->json('token'),
'expires_at' => $response->json('expires_at'),
]);
});
Step 3 — Embed the widget on your site
Option A — Script tag + floating widget (recommended)
Add before </body> on every page that should show the chat CTA (including ad landing pages):
<script
src="https://cdn.aventora.ai/widget.js"
data-tenant="acme"
data-language="en"
data-theme="auto"
data-position="bottom-right"
data-token-api-url="/api/chatbot-token"
data-chatbot-url="https://acme.aventora.app"
defer>
</script>
| Attribute | Required | Description |
|---|---|---|
data-tenant | Yes | Your domain slug (same as acme above) |
data-token-api-url | No | Path to your token endpoint (default /api/chatbot-token) |
data-chatbot-url | Yes* | Chatbot app base URL (https://{slug}.aventora.app) |
data-language | No | en, fr, es, etc. (default en) |
data-theme | No | auto, light, or dark |
data-position | No | bottom-right, bottom-left, top-right, top-left |
*If omitted, the widget tries to auto-detect from configuration — set explicitly for production.
Your Aventora contact confirms the correct widget script URL if you self-host instead of CDN.
Option B — Embedded panel (chat fills a section)
Use when the landing page has a dedicated “Chat with us” area instead of only a corner bubble.
<div id="chat-panel" style="width:100%;max-width:480px;height:600px;"></div>
<script
src="https://cdn.aventora.ai/widget.js"
data-tenant="acme"
data-language="en"
data-position="embedded"
data-token-api-url="/api/chatbot-token"
data-chatbot-url="https://acme.aventora.app"
defer>
</script>
Place the script after the container, or mount <aventora-chat> manually once aventora-chat.js has loaded (advanced).
Option C — Manual iframe (minimal)
If you cannot use the widget loader, your token endpoint + iframe is enough:
<div id="chatbot-container" style="width:100%;height:600px;"></div>
<script>
async function loadChatbot() {
const res = await fetch('/api/chatbot-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ language: 'en' }),
});
const { token } = await res.json();
const iframe = document.createElement('iframe');
iframe.src = `https://acme.aventora.app/autoconnect?token=${encodeURIComponent(token)}&lang=en`;
iframe.style.cssText = 'width:100%;height:100%;border:none';
iframe.allow = 'microphone; camera';
document.getElementById('chatbot-container').appendChild(iframe);
}
loadChatbot();
</script>
Widget options (floating CTA vs embedded panel)
| Mode | Best for | Visitor experience |
|---|---|---|
Floating (data-position="bottom-right") | Site-wide CTA; ad landing pages | Corner chat bubble; opens panel on click |
| Embedded | “Chat now” section on one page | Chat always visible in a page block |
| Fixed | Full-width support pages | Larger persistent panel |
For paid ads, floating bottom-right is the usual pattern: the Meta/Google ad brings them to the page; the chat bubble is the conversion CTA.
After the widget loads, you can control it from JavaScript:
// Open chat when visitor clicks a landing-page button
document.getElementById('chat-cta').addEventListener('click', function () {
if (window.AventoraChatbot && window.AventoraChatbot.open) {
window.AventoraChatbot.open();
}
});
Wait for the ready event if the button appears before the widget finishes loading:
window.addEventListener('aventora:ready', function () {
window.AventoraChatbot.open();
});
Landing-page CTA buttons
Typical ad landing page pattern:
- Hero headline matches the ad.
- Primary button: “Chat with us” → calls
AventoraChatbot.open(). - Floating widget in the corner for visitors who scroll past the button.
- Optional: auto-open chat 3–5 seconds after page load on campaign pages only (test UX before enabling).
Align bot content with the ad — see AD_CAMPAIGNS — Configure Domain Assistant.
How it works
sequenceDiagram
participant Browser
participant YourServer as Your website server
participant API as Domain-chatbot API
participant Chat as Chatbot app
Browser->>YourServer: POST /api/chatbot-token
YourServer->>API: POST /auth/api/v1/tokens/generate (Bearer domain key)
API-->>YourServer: token, expires_at
YourServer-->>Browser: token
Browser->>Chat: Load autoconnect?token=...&lang=en
Chat-->>Browser: Anonymous session + chat UI
- Visitor opens your page (e.g. from a Meta ad).
- Widget requests a token from your server.
- Your server mints a short-lived token with the domain API key.
- Widget loads the chatbot iframe at
{chatbot-url}/autoconnect?token=.... - Visitor chats; high-intent actions (callback form, intakes) can start Engagement Hub flows when configured.
Testing checklist
- Token endpoint —
curl -X POST https://yoursite.com/api/chatbot-token -H "Content-Type: application/json" -d "{\"language\":\"en\"}"→200withtoken. - Wrong key — temporarily break API key → expect
401/403from domain-chatbot (not silent success). - Widget visible — open landing page; corner bubble or embedded panel appears.
- Network tab —
/api/chatbot-tokenreturns 200; iframe URL includestoken=. - Conversation — send a test message; check Domain Assistant → Logs in Admin.
- Callback test — ask to speak with someone; confirm Hub engagement if phone assistant is enabled.
- Mobile — test on phone; bubble does not cover primary CTA.
Production and security
| Requirement | Detail |
|---|---|
| HTTPS | Entire site + token endpoint |
| Secret storage | API key in server env / secrets manager only |
| No key in browser | Never put DOMAIN_CHATBOT_API_KEY in HTML, JS bundles, or mobile apps |
| Rate limiting | Optional: limit token endpoint per IP to reduce abuse |
| Key rotation | Revoke old keys in Admin → Domain API Keys; update server env |
| CORS | Token endpoint only needs to accept requests from your site origin |
Production env checklist
-
DOMAIN_CHATBOT_API_KEYset on production server -
DOMAIN_CHATBOT_API_URLpoints to production API -
data-chatbot-urlpoints to production chatbot host - Token route deployed and reachable at
data-token-api-url - Welcome message and knowledge base updated for live campaigns
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| No widget on page | Script missing or data-tenant empty | Add script tag; set data-tenant |
data-tenant attribute is required in console | Missing tenant | Set domain slug |
| Token request 404 | Token route not deployed | Add /api/chatbot-token on your server |
| Token request 500 “not configured” | API key missing on server | Set DOMAIN_CHATBOT_API_KEY in env |
| Token request 401/403 | Wrong or revoked API key | Regenerate key in Admin; update env |
| Iframe blank / “Token required” | Token not passed or expired | Check token in iframe URL; retry token call |
| Chat loads but wrong domain | Wrong data-chatbot-url | Match URL to your tenant slug |
| Microphone not working | Page not HTTPS | Enable SSL on site |
| High-intent “call me back” fails | Phone assistant not enabled | Contact Aventora; see ad campaign doc |
Quick reference
Three steps:
- Admin → Settings → Domain API Keys → generate key
- Server →
POST /api/chatbot-token→ calls/auth/api/v1/tokens/generate - HTML → add
widget.jsscript withdata-tenantanddata-chatbot-url
Minimal embed:
<script
src="https://cdn.aventora.ai/widget.js"
data-tenant="YOUR_DOMAIN_SLUG"
data-chatbot-url="https://YOUR_DOMAIN_SLUG.aventora.app"
data-token-api-url="/api/chatbot-token"
defer>
</script>
For campaign strategy, Meta messaging ads, Email Pull, and CRM follow-up, continue with AD_CAMPAIGNS_TO_ENGAGEMENT.md.