Skip to main content

Get started with the web channel

Overview​

The Moveo web channel enables you to add AI-powered conversations directly to your website. This channel provides a customizable chat interface that you can style to match your brand and configure to meet your specific requirements.

note

By default, a conversation in the web channel stays active for one hour if the user does not close the window. The web channel does not load if the user agent (browser) is a bot.

The user does not have to wait for the AI agent to finish an answer. If the user sends a text message while the AI agent is still answering, the AI agent stops that answer. Then it answers all of the new messages together in one reply.

Quick start​

To add the web channel to your website:

  1. Go to Deploy → Connections in your Moveo account
  2. Select your environment
  3. Select Connect on the Webchat integration
  4. Copy the generated snippet and add it before the </body> tag:
<script src="https://web.moveo.ai/web-client.min.js"></script>
<script>
MoveoAI.init({
integrationId: "YOUR-INTEGRATION-ID",
version: "v2",
})
.then((instance) => console.log("connected"))
.catch((error) => console.error(error));
</script>
  1. Add your domain to the trusted domains list
  2. Set the web channel state to Active

The web channel is now ready to receive messages.

Connect the web channel through the API or the MCP server​

Follow the quick start steps above. The console shows the snippet with your integrationId. For accounts in the United States and Brazil, the snippet also sets host.

Region hosts​

The snippet loads the same script in every region. The host option tells the web channel which region to connect to. Without host, it connects to Europe.

Regionhost value
Europehttps://channels-ws.moveo.ai (default)
United Stateshttps://channels-ws.us-central.moveo.ai
Brazilhttps://channels-ws.sa-east.moveo.ai
MoveoAI.init({
integrationId: "YOUR-INTEGRATION-ID",
host: "https://channels-ws.us-central.moveo.ai",
});

Installation options​

Standard installation​

The standard installation loads the web channel on every page:

<script src="https://web.moveo.ai/web-client.min.js"></script>
<script>
MoveoAI.init({
integrationId: "YOUR-INTEGRATION-ID",
version: "v2",
})
.then((instance) => console.log("connected"))
.catch((error) => console.error(error));
</script>

Embed mode​

Render the chat within your page content instead of as a floating widget:

<div id="chat-container"></div>
<script src="https://web.moveo.ai/web-client.min.js"></script>
<script>
MoveoAI.init({
integrationId: "YOUR-INTEGRATION-ID",
element: document.getElementById("chat-container"),
version: "v2",
})
.then((instance) => console.log("embedded chat connected"))
.catch((error) => console.error(error));
</script>

Delayed initialization​

Wait for page load or user interaction before initializing:

<script src="https://web.moveo.ai/web-client.min.js"></script>
<script>
window.addEventListener("DOMContentLoaded", function () {
MoveoAI.init({
integrationId: "YOUR-INTEGRATION-ID",
version: "v2",
})
.then((instance) => console.log("connected"))
.catch((error) => console.error(error));
});
</script>

User authentication​

Secure your web channel and authenticate users to ensure messages come from verified customers only.

Why authenticate?​

Authentication provides:

  • Security: Verify that messages come from your actual customers
  • Personalization: Pass user data securely to provide tailored responses
  • Privacy: Encrypt sensitive information end-to-end

Basic authentication setup​

  1. Generate RSA keys:
# Private key (keep secure on your server)
openssl genrsa -out private.pem 2048
# Public key (add to Moveo)
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
  1. Add public key to Moveo:

    • Go to Deploy → Connections → Webchat → Advanced settings
    • Enable Activate end-to-end encryption
    • Paste your public key
  2. Generate JWT on your server:

const jwt = require('jsonwebtoken');

function generateToken(userId) {
const payload = {
sub: userId, // Required: unique user ID
iss: 'yourdomain.com', // Required: issuer
};

return jwt.sign(payload, process.env.PRIVATE_RSA_KEY, {
algorithm: 'RS256',
expiresIn: '5m', // Must expire within 24 hours
});
}
  1. Initialize with authentication:
<script>
MoveoAI.init({
integrationId: "YOUR-INTEGRATION-ID",
identityToken: "JWT_FROM_YOUR_SERVER",
version: "v2",
})
.then((instance) => console.log("authenticated"))
.catch((error) => console.error(error));
</script>

Passing encrypted user data​

To securely pass sensitive user information (for example, account details, VIP status):

  1. Get Moveo's public key from your web integration settings
  2. Encrypt context with AES-256
  3. Encrypt AES key with RSA
  4. Include in JWT:
Match the encryption scheme exactly

Moveo decrypts encryption_key and init_vector with RSA-OAEP (SHA-256), and the context with AES-256-CBC. Libraries that default to a different padding or hash produce tokens Moveo cannot decrypt. In particular, node-rsa defaults to OAEP with SHA-1, so always set the OAEP hash to SHA-256, as the example shows.

const crypto = require("crypto");
const jwt = require("jsonwebtoken");

function generateSecureToken(userId, userContext) {
// Generate AES key and IV
const aesKey = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);

// Encrypt context with AES-256-CBC
const cipher = crypto.createCipheriv("aes-256-cbc", aesKey, iv);
let encrypted = cipher.update(JSON.stringify(userContext), "utf8", "base64");
encrypted += cipher.final("base64");

// Encrypt the AES key and IV with Moveo's RSA public key.
// Moveo decrypts with RSA-OAEP / SHA-256, so the padding and hash must
// match exactly or decryption fails server-side.
const oaep = {
key: process.env.MOVEO_PUBLIC_KEY,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256",
};
const encryptedKey = crypto.publicEncrypt(oaep, aesKey).toString("base64");
const encryptedIV = crypto.publicEncrypt(oaep, iv).toString("base64");

// Create JWT with encrypted data
const payload = {
sub: userId,
iss: "yourdomain.com",
context: encrypted, // AES encrypted context
encryption_key: encryptedKey, // RSA encrypted AES key
init_vector: encryptedIV, // RSA encrypted IV
};

return jwt.sign(payload, process.env.PRIVATE_RSA_KEY, {
algorithm: "RS256",
expiresIn: "5m",
});
}

// Usage
const userContext = {
user: {
email: "user@example.com",
is_vip: true,
account_tier: "premium",
},
contract_id: "12345",
credit_limit: 10000,
};

const token = generateSecureToken("user-123", userContext);

The AI agent can use the encrypted context for personalization. Moveo never sends it back to the client, so sensitive data stays secure.

Authentication flow​

Content Security Policy​

If your site sends a Content-Security-Policy header, allow these hosts. Replace the channels-ws host with the host of your region.

DirectiveValueWhy
script-srchttps://web.moveo.aiThe script web-client.min.js.
frame-srchttps://web.moveo.aiThe web channel window loads in an iframe from this host.
connect-srchttps://channels-ws.moveo.ai and wss://channels-ws.moveo.aiThe configuration request and the WebSocket connection.
img-srchttps://res.cloudinary.comThe default avatar of the AI agent.

The snippet also has an inline <script> that calls MoveoAI.init. A policy that allows only hosts blocks this script, so the web channel does not start. To allow it, add a nonce: a random value that your server creates for each page response. Put the same value in script-src and in the nonce attribute of the inline script.

For example, for an account in Europe:

Content-Security-Policy: script-src 'self' https://web.moveo.ai 'nonce-RANDOM-VALUE';
frame-src https://web.moveo.ai;
connect-src 'self' https://channels-ws.moveo.ai wss://channels-ws.moveo.ai;
img-src 'self' https://res.cloudinary.com
<script src="https://web.moveo.ai/web-client.min.js"></script>
<script nonce="RANDOM-VALUE">
MoveoAI.init({
integrationId: "YOUR-INTEGRATION-ID",
version: "v2",
});
</script>

If you cannot add a nonce, move the MoveoAI.init call to a script file on your own domain. 'self' in script-src allows that file.

If you set your own avatar or show files that users upload, also allow the hosts of these files in img-src and connect-src.

Security best practices​

  1. Keep private keys secure - Never expose them in client-side code
  2. Use short expiration times - Moveo rejects JWT tokens that expire more than 24 hours ahead
  3. Validate on server - Always generate tokens server-side
  4. Encrypt sensitive data - Use AES encryption for context data
  5. Trusted domains - Only allow your domains in settings
  6. HTTPS only - Always use secure connections

Mobile app integration​

To use the web channel in a mobile application:

  1. Host the web channel on a webpage accessible by URL
  2. Embed the webpage using a WebView or iframe:
<!-- Host this page on your server -->
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<script src="https://web.moveo.ai/web-client.min.js"></script>
<script>
MoveoAI.init({
integrationId: "YOUR-INTEGRATION-ID",
// Pass authentication from mobile app if needed
identityToken: window.AUTH_TOKEN,
version: "v2",
})
.then((instance) => {
// Expose instance to mobile app if needed
window.moveoInstance = instance;
})
.catch((error) => console.error(error));
</script>
</body>
</html>

Then embed this page in your mobile app's WebView component.

Next steps​