# Moveo.AI Documentation > Revolutionize your customer experience using an AI agent This file contains all documentation content in a single document following the llmstxt.org standard. ## Dialog webhooks A dialog webhook is a webhook that runs as part of a workflow. You add a **webhook action** to a dialog node, point it at a configured webhook, and the AI Agent calls your endpoint when the conversation reaches that node. The endpoint can return new context variables (to carry data forward) or its own [responses](./responses/overview) (to take control of the agent's reply). Use a dialog webhook to: - Validate information collected from the user. - Fetch data from another system, like a customer record or inventory status. - Trigger an action with side effects, such as sending an OTP or creating a ticket. :::note This page covers how to wire a dialog webhook into a workflow. To configure the webhook itself (URL, verification token, headers), see [Webhooks](./webhooks). For the request and response payload schemas, see [Build a webhook](./build-a-webhook). ::: ## Add a webhook action to a workflow 1. Open the AI Agent and pick the dialog where you want the webhook to run. 2. Drag a **Webhook** action onto the node, in the position where the call should happen. 3. Configure the action: | Field | Description | | --- | --- | | Webhook | Pick the webhook from the list of webhooks configured on the AI Agent. Only webhooks of type `dialog` appear here. | | Fallback | A text response sent to the user if the webhook call fails or times out. Used as a graceful degradation when `fail on error` is off. | Once the action runs, any context variables your endpoint returns are immediately available to the rest of the workflow — condition nodes downstream can branch on them, and other actions can interpolate them into their text. ## What gets sent and received When the action fires, Moveo sends the conversation's full context, the user's input, and the recognized intents and entities. Your endpoint replies with any combination of: - **Context updates** — new or changed variables to carry forward in the session. - **Responses** — a list of reply objects (text, media, carousel, webview, etc.) that the agent will deliver to the user instead of generating its own reply. Full schemas for the request body, the supported response types, and the rules around updating context are in [Build a webhook → Type reference](./build-a-webhook#type-reference). --- ## Advanced setup The **Advanced** page allows you to configure key parameters of your AI Agent, including selecting a language model, setting prediction confidence, and defining inactivity timeouts. ## Match user's language By default, responses are generated in the language the AI Agent has been set up to. However, you can configure the AI Agent to match the user's language regardlessly of the language the AI Agent has been set up to, or if the knowledge base is in a different language. To do this you have to: 1. Navigate to your AI Agent 2. Go to **Overview** tab 3. Click on the **Advanced** section in the sidebar 4. Enable the **Match user's language** switch 5. Save your changes ## Model strategy The **Models** section lets you choose the language models that power your AI Agent. You set a **default** list of models that run in order — if one fails, the next takes over — and you can optionally **customize the models per channel** (Chat, Email, and Voice). For full details, see the [Model strategy](./model-strategy.md) guide. ## Prediction threshold This setting controls the confidence level required for an **[intent](./intents.md)** prediction to be considered correct. The threshold ranges from 0 to 1. - **Lower threshold (more flexible, but increases false positives)**\ In customer support scenarios, a lower threshold allows the AI Agent to be more responsive. Even if it’s uncertain about a user’s intent, it will still attempt a relevant response. This helps keep conversations flowing but may sometimes result in incorrect predictions. - **Higher threshold (more conservative, requiring clearer user input)**\ In fields like legal or financial assistance, a higher threshold ensures only the most confident predictions are accepted. This reduces errors but may require users to phrase their questions more precisely for accurate responses. ## Inactivity timeout This setting determines how long the AI Agent retains context before resetting due to user inactivity. :::note This timeout will take over the whole session time out when this AI Agent is assigned to it. ::: For a comprehensive understanding of timeout mechanisms in Moveo, including inactivity timeout, session timeout, and keep alive, refer to the [Timeout mechanisms](../guides/timeouts) documentation. Adjusting this setting optimizes the AI Agent's performance based on your workflow requirements. - **Shorter timeouts (e.g., 5–30 min)** → Ideal for fast-paced interactions where outdated context should be discarded quickly. This prevents the AI Agent from using stale information that might mislead the conversation. - **Longer timeouts (e.g., 2, 8, 24 hours, or more days)** → Useful for cases where conversations span extended periods. For example, in complex troubleshooting or long-running customer support sessions, a longer timeout allows the AI Agent to maintain context even if the user returns hours later. ## Factuality sensitivity This setting controls how strictly AI Agent responses are evaluated for correctness before being delivered to the user. When a response doesn't meet the selected guard level, it is redirected to the [Unknown](./triggers/unknown.md) flow instead of being delivered. - **Off** → No factuality enforcement. Responses are delivered without validation. - **Light Guard** → Flags major inaccuracies and attempts correction, but delivers the response anyway. - **Strong Guard** (default) → Catches major inaccuracies, attempts correction, and redirects to the Unknown flow if correction fails. - **Maximum Guard** → Catches both major and minor inaccuracies, attempts correction, and redirects to the Unknown flow if correction fails. **Minor inaccuracies** are small assumptions that are not explicitly supported by the provided knowledge but remain plausible, low-risk, and non-contradictory. **Major inaccuracies** are claims or instructions that are unsupported, invented, or contradictory to the provided knowledge and risk misleading the user. :::tip Use **Strong Guard** or **Maximum Guard** in regulated industries (e.g., finance, healthcare, legal) where accuracy is critical. Use **Light Guard** for more conversational use cases where strict factuality is less important. ::: ## Reminder A reminder is a feature that triggers a [dialog node](./dialogs.md#triggers) when a certain period of time passes after the last user message. In order to set up a reminder: 1. Go to your AI Agent 2. Go to **Settings** tab 3. Scroll to **Reminder** section 4. Select the waiting to trigger the reminder 5. Select the node that should handle the reminder 6. Save your changes --- ## Build a webhook This guide walks through implementing a webhook endpoint that Moveo can call during a conversation. It covers the request format, signature verification, response contracts per webhook type, operational practices, and a few worked use cases. A complete TypeScript type reference is at the end. The examples use Next.js with TypeScript, but the patterns translate to any HTTP framework. :::note For configuring a webhook in the Moveo UI (URL, verification token, custom headers, types) and for the payload differences across types, see [Webhooks](./webhooks). ::: ## What you'll build By the end of this guide you will have: 1. An HTTPS endpoint that accepts `POST` requests from Moveo. 2. HMAC SHA256 verification of the `X-Moveo-Signature` header. 3. Body validation with Zod. 4. A response shaped for the webhook type you configured (dialog, first message, pre message, or post message). ## Prerequisites - Node.js 18 or newer - A TypeScript project (Next.js, Express, Fastify, or any HTTP framework) - A public-facing HTTPS URL — non-HTTPS URLs are rejected by Moveo in production - A verification token configured on the webhook in the Moveo UI ## The request from Moveo Every webhook call is a `POST` with a JSON body. The body shape depends on the [webhook type](./webhooks#payload-differences-per-type); the headers are the same across types: | Header | Description | | --- | --- | | `X-Moveo-Signature` | HMAC SHA256 of the request body, hex-encoded | | `X-Moveo-Request-Id` | Unique identifier for this call — log it for correlation | | `X-Moveo-Session-Id` | The conversation session | | `X-Moveo-Account-Id` | The Moveo account | | `X-Moveo-Account-Slug` | The account slug | Custom headers configured on the webhook are sent on every call. The full payload reference per webhook type is in the [Webhooks](./webhooks#payload-differences-per-type) page; ready-to-use type definitions for TypeScript, Python, and Go are in the [Type reference](#type-reference) at the end of this guide. ## Verify the signature The signature confirms the request came from Moveo and was not tampered with. Always compute it before doing anything else with the body — including parsing it as JSON, in case the body was modified in transit. Use the **raw request body** (not a parsed JSON object) and the verification token configured on the webhook. ```ts title="verify-signature.ts" export const verifySignature = (rawBody: string, signature: string, token: string): boolean => { const expected = crypto.createHmac('sha256', token).update(rawBody).digest('hex'); const a = Buffer.from(expected, 'hex'); const b = Buffer.from(signature, 'hex'); return a.length === b.length && crypto.timingSafeEqual(a, b); }; ``` ```py title="verify_signature.py" def verify_signature(raw_body: bytes, signature: str, token: str) -> bool: expected = hmac.new(token.encode("utf-8"), raw_body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, signature) ``` Use a constant-time comparison (`timingSafeEqual` / `compare_digest`) — a regular string `===` is vulnerable to timing attacks. ## A complete handler The handler below runs four steps in order: verify the signature, validate the body, do the work, respond. The example is for a dialog webhook; the same skeleton applies to event webhooks — only the body schema and the response shape change. ```ts title="api/orders.ts" const WEBHOOK_TOKEN = process.env.MOVEO_WEBHOOK_TOKEN!; const bodySchema = z.object({ context: z.object({ customer_id: z.string(), }), }); export const config = { api: { bodyParser: false }, }; const readRawBody = async (req: NextApiRequest): Promise => { const chunks: Buffer[] = []; for await (const chunk of req) { chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk); } return Buffer.concat(chunks).toString('utf-8'); }; const handler = async (req: NextApiRequest, res: NextApiResponse) => { // 1. Verify the signature against the raw body const rawBody = await readRawBody(req); const signature = req.headers['x-moveo-signature']; if (typeof signature !== 'string' || !verifySignature(rawBody, signature, WEBHOOK_TOKEN)) { return res.status(401).json({ error: 'invalid signature' }); } // 2. Parse and validate the body const body = bodySchema.parse(JSON.parse(rawBody)); // 3. Do the work const order = await fetchOrder(body.context.customer_id); // 4. Respond — context updates feed back into the conversation return res.json({ context: { order_status: order.status, order_total: order.total, }, }); }; export default handler; ``` A few notes on the structure: - **Disable the body parser**, or capture the raw body before it is parsed, so the signature is computed against the exact bytes Moveo signed. - **Validate at the boundary.** Use Zod (or your validator of choice) once at the top of the handler. Downstream functions should receive already-typed inputs. - **Keep the handler thin.** External API calls belong in their own module. Idempotency, retries, and caching are concerns of the underlying API client, not the webhook handler. ## Respond by webhook type Each webhook type has its own response contract. Returning fields the contract does not honor is silently ignored. ### Dialog webhooks A dialog webhook can return a `context` object, a `responses` array, or both. The `responses` array supports text, media, event, carousel, webview, and reset entries — see the [response action types](#response-actions) below. ```json { "context": { "order_status": "pending", "order_total": 49.5 }, "responses": [ { "type": "text", "texts": ["Your order is on the way!"] } ] } ``` Responses are validated. Invalid responses are logged as warnings and skipped; a request that fails validation entirely returns an error to the agent. ### First message and pre message webhooks Return a `context` object and, optionally, a modified `input`. These webhooks fire before the agent processes the user's input and cannot reply on the agent's behalf. The `input` object accepts two fields: - **`input.text`** — replaces the user message before the agent sees it. Useful for normalization or moderation. 1–4096 characters. - **`input.trigger_node_id`** — UUID of an existing dialog node. Routes directly to that node and bypasses intent classification. The UUID must reference a node on the AI Agent. ```json { "context": { "live_instructions": "The user is George, a VIP customer.", "user_crm_level": "platinum" } } ``` Rewrite the user input: ```json { "input": { "text": "I want to cancel my order" } } ``` Route to a specific dialog node: ```json { "input": { "trigger_node_id": "9c8e4f1a-2d6b-4e3a-9f1b-1c2d3e4f5a6b" } } ``` ### Post message webhook Return a `context` object and, optionally, a `responses` array. If `responses` is present, it replaces the agent's planned reply for this turn. Items in this array are sent to the user as-is — no templating or context-variable substitution is applied. ```json { "context": { "last_intent": "order_inquiry" }, "responses": [ { "type": "text", "texts": ["Override: please contact us at support@example.com."] } ] } ``` ### Context update rules The same rules apply to every webhook type that returns a `context`: - At most 100 variables, 32 KB total. - Names: 1–128 characters, alphanumeric plus `_`, `-`, `.`. - Reserved names that cannot be set or overwritten: `user`, `global`, `channels`, `campaign`, `tags`, anything beginning with `sys-` or `channels.`. - Individual `user.*` fields can be updated using dotted-path notation (e.g. `"user.email": "alice@example.com"`); the `user` object as a whole cannot be replaced. ## Operating in production A few constraints to design around: - **Timeouts** — Moveo waits 1.5 seconds for the connection and 15 seconds for a response. Defer non-critical work (analytics, log shipping, cache warming) until after the response is sent. - **No automatic retries** — a failed call surfaces as an error to the agent and is not retried. If your endpoint must be exactly-once, implement idempotency on your side using `X-Moveo-Request-Id` as the dedupe key. - **HTTPS only** — non-HTTPS URLs and loopback or private addresses are rejected at configuration time in production. - **History is opt in** — to receive `history` in the body, add `X-Moveo-Include-History: true` as a custom header on the webhook configuration. Without it, history is omitted to keep payloads small. - **Choose `fail_on_error` deliberately** — leave it off for non-critical webhooks (analytics, enrichment) so the agent can keep talking when your endpoint hiccups. Turn it on for webhooks the conversation cannot proceed without (authentication, payment). - **Don't log payload bodies as is** — Moveo payloads typically contain user information. Log identifiers (`X-Moveo-Request-Id`, `session_id`) instead. ## Test locally You can test your endpoint with `curl` once you compute a valid signature. The signature is HMAC SHA256 of the exact body bytes, keyed with the verification token from the Moveo UI: ```sh BODY='{"channel":"web","session_id":"abc","brain_id":"xyz","lang":"en","context":{"customer_id":"123"}}' SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$MOVEO_WEBHOOK_TOKEN" | awk '{print $2}') curl -X POST https://your-app.example.com/api/orders \ -H "Content-Type: application/json" \ -H "X-Moveo-Signature: $SIG" \ -d "$BODY" ``` For an end-to-end test against Moveo itself, expose your local server with ngrok or Cloudflared, paste the public URL into the webhook configuration, and use the **Send test request** button in the [UI tester](./webhooks#test-your-webhook). ## Use cases The patterns below are the worked counterparts of the brief use cases on the [Webhooks](./webhooks#use-case-examples) page. ### Use case: live instructions **Webhook type:** first message or pre message. Fetch user data from your system the moment a session starts and inject it into the conversation as `live_instructions`. The agent reads `live_instructions` from context on every turn and uses it to personalize replies. This is the cleanest way to keep the agent's prompt short while still acting on real-time customer data. ```ts title="api/live-instructions.ts" const handler = async (req: NextApiRequest, res: NextApiResponse) => { const userId = req.body.context.user_id; const userInfo = await API.getUserInfo(userId); const { name, transactions, atm } = userInfo; const latestTransaction = transactions[0]; const liveInstructions = [ `1. User name: ${name}`, `2. Recent activity: ${name} made a ${latestTransaction.type} of ${latestTransaction.amount} ${latestTransaction.currency}, pending and expected to settle in 2–4 days.`, `3. The nearest ATM is at ${atm.address}.`, ].join('\n'); return res.json({ context: { live_instructions: liveInstructions, }, }); }; export default handler; ``` :::tip Format `live_instructions` with newlines (`\n`) and consistent numbering. The agent reads it as plain text — well-structured input produces more reliable behavior. ::: ### Use case: validate input **Webhook type:** dialog. Drop a [webhook action](./action-webhooks) into a dialog node to check something the user said against your backend before the conversation continues. Update context with the result, and use a regular condition node downstream to branch on it. ```ts title="api/check-account.ts" const handler = async (req: NextApiRequest, res: NextApiResponse) => { // 1, 2 — verify signature + validate body (omitted for brevity) const accountNumber = req.body.context.account_number; const account = await API.lookupAccount(accountNumber); if (!account) { return res.json({ context: { account_valid: false }, }); } return res.json({ context: { account_valid: true, account_balance: account.balance, account_holder: account.holder, }, }); }; ``` ### Use case: post message audit **Webhook type:** post message. Inspect the agent's planned reply, log it, and optionally replace it. Useful for compliance review, trailing analytics, or A/B testing different response styles without changing the dialog. ```ts title="api/post-message.ts" const handler = async (req: NextApiRequest, res: NextApiResponse) => { // 1, 2 — verify signature + validate body (omitted for brevity) const { session_id, output, intents } = req.body; await API.logTurn({ sessionId: session_id, intent: intents[0]?.intent, responseTypes: output.map((response) => response.type), }); // Pass through unchanged — return only context. return res.json({ context: { last_intent: intents[0]?.intent ?? null, }, }); }; ``` To override the reply instead of passing through, return a `responses` array — the rules are the same as for dialog webhooks. ## Type reference Drop-in type definitions are available in TypeScript, Python, and Go. Each file covers the request bodies for all four webhook types, the context object, the response shape per type, and the response action types you can return. | Language | File | | --- | --- | | TypeScript | [`moveo-webhooks.ts`](/types/moveo-webhooks.ts) | | Python (Pydantic v2) | [`moveo_webhooks.py`](/types/moveo_webhooks.py) | | Go | [`moveo_webhooks.go`](/types/moveo_webhooks.go) | ### Using the types Import the request and response types you need, and parameterize them with an interface describing the custom variables your AI Agent collects: ```ts DialogWebhookRequest, DialogWebhookResponse, } from './moveo-webhooks'; interface OrderVars { customer_id: string; order_status?: 'pending' | 'shipped' | 'delivered'; } const handler = async ( req: DialogWebhookRequest ): Promise> => { // req.context.customer_id is typed as string // req.context.user.display_name is available return { context: { order_status: 'shipped' }, }; }; ``` Pydantic models validate the body at the boundary. Subclass `MoveoContext` to type your custom variables: ```py from moveo_webhooks import ( DialogWebhookRequest, DialogWebhookResponse, MoveoContext, ) class OrderContext(MoveoContext): customer_id: str order_status: str | None = None # Inside your handler: body = DialogWebhookRequest.model_validate(payload) order_context = OrderContext.model_validate(body.context.model_dump(by_alias=True)) return DialogWebhookResponse( context={"order_status": "shipped"}, ).model_dump(exclude_none=True) ``` Decode into the request struct, embed `Context` if you need typed custom variables, and encode a response struct: ```go // Copy moveo_webhooks.go into your module under, for example, // internal/moveowebhooks, and import it from there. type OrderContext struct { mw.Context CustomerID string `json:"customer_id"` OrderStatus string `json:"order_status,omitempty"` } type orderRequest struct { mw.RequestBase Input mw.MessageInput `json:"input"` Intents []mw.Intent `json:"intents"` Entities []mw.Entity `json:"entities"` UserMessageCounter int `json:"user_message_counter"` Debug mw.Debug `json:"debug"` Context OrderContext `json:"context"` } var req orderRequest if err := json.Unmarshal(rawBody, &req); err != nil { // handle error } resp := mw.DialogWebhookResponse{ Context: map[string]any{"order_status": "shipped"}, } return json.Marshal(resp) ``` ### Context The session context, with the special `user` object and reserved system variables: ```ts title="moveo-webhooks.ts" export interface MoveoContextUser { readonly user_id: string; readonly external_id?: string; display_name?: string; avatar?: string; email?: string; phone?: string; address?: string; language?: string; timezone?: string; location?: { city?: string; country?: string; region?: string; latitude?: number; longitude?: number }; browser?: string; platform?: string; device?: string; ip?: string; verified?: boolean; verified_method?: 'jwt' | 'otp' | 'email' | 'qr'; verified_at?: string; } export type MoveoContext = Record> = TVars & { user?: MoveoContextUser; tags?: string[]; channels?: Record>; global?: Record; campaign?: { campaign_id?: string; subscriber_id?: string; sender_id?: string }; live_instructions?: string | Record | null; // Read only — managed by Moveo and rejected when overwritten in a response. 'sys-channel'?: string; 'sys-session'?: string; 'sys-business'?: 'open' | 'closed'; 'sys-user_message_counter'?: number; 'sys-unknown_counter'?: number; }; ``` ### Request bodies All four request types share a common envelope and add type-specific fields. `TVars` is your interface describing the custom variables the AI Agent collects. ```ts title="moveo-webhooks.ts" export interface MoveoWebhookRequestBase = Record> { channel: string; channel_type: string; session_id: string; desk_id: string; integration_id: string; brain_id: string; lang: string; context: MoveoContext; timestamp: number; history?: MoveoHistoryMessage[]; // present only with X-Moveo-Include-History: true } export interface DialogWebhookRequest extends MoveoWebhookRequestBase { input: MoveoMessageInput; intents: MoveoIntent[]; entities: MoveoEntity[]; user_message_counter: number; debug: { dialog_stack: { node_id: string; name: string }[] }; } export interface FirstMessageWebhookRequest extends MoveoWebhookRequestBase { input: MoveoMessageInput; business_closed: boolean; } export interface PreMessageWebhookRequest extends MoveoWebhookRequestBase { input: MoveoMessageInput; business_closed: boolean; } export interface PostMessageWebhookRequest extends MoveoWebhookRequestBase { input: MoveoMessageInput; intents: MoveoIntent[]; entities: MoveoEntity[]; user_message_counter: number; output: MoveoAgentAction[]; // broader than MoveoResponseAction — see below debug: { dialog_stack: { node_id: string; name: string }[] }; } ``` ### Response actions What your endpoint can put inside a `responses` array. Dialog and post message webhooks accept these; first message and pre message webhooks ignore them. ```ts title="moveo-webhooks.ts" export type MoveoResponseAction = | { type: 'text'; texts: string[]; options?: { label: string; text: string }[] } | { type: 'image' | 'video' | 'audio' | 'file'; url: string; name?: string; size?: number } | { type: 'event'; trigger_node_id: string } | { type: 'webview'; name: string; label: string; url: string; height?: 'tall' | 'compact' | 'full'; trigger_node_id?: string } | { type: 'carousel'; cards: MoveoCarouselCard[]; action_id: string } | { type: 'reset' }; ``` ### Agent actions The post message webhook's `output` field is broader than `MoveoResponseAction` — the agent can plan additional action types (handover, url, tag, reminder, internal webhook calls) that you cannot return from your own endpoint: ```ts title="moveo-webhooks.ts" export type MoveoAgentAction = ( | MoveoResponseAction | { type: 'handover'; external: boolean } | { type: 'url'; url: string } | { type: 'tag'; tags: string[] } | { type: 'reminder'; reminder_seconds: number; trigger_node_id: string } | { type: 'webhook'; webhook_id: string; fallback: MoveoAgentAction[] } ) & { action_id?: string; metadata?: Record; }; ``` ### Response bodies The shape your endpoint returns, per webhook type: ```ts title="moveo-webhooks.ts" export interface DialogWebhookResponse { context?: Partial>; responses?: MoveoResponseAction[]; } export interface PreMessageWebhookResponse { context?: Partial>; input?: MoveoMessageInput; // rewrite the user input before the agent sees it } export type FirstMessageWebhookResponse = PreMessageWebhookResponse; export interface PostMessageWebhookResponse { context?: Partial>; responses?: MoveoResponseAction[]; // if present, replaces the agent's planned reply } ``` ## Next steps - [Webhooks](./webhooks) — concept overview, types, UI configuration - [Dialog webhooks](./action-webhooks) — how to wire a dialog webhook into a workflow --- ## Build an MCP server This guide walks through building a custom MCP server that Moveo can connect to as a tool provider for an AI agent. It covers the implementation, the tool-design choices that determine whether the agent calls your tools correctly, and the operational practices that keep the server reliable in production. The examples use Next.js App Router with TypeScript, but the patterns translate to any HTTP framework. :::note For configuring an MCP server in the Moveo UI (adding a server, managing tools, resyncing) and for runtime behavior numbers, see [MCP servers](./mcp-servers). ::: ## What you'll build By the end of this guide you will have: 1. A route that exposes an MCP endpoint over Streamable HTTP. 2. One tool with a Zod-validated input schema and a description that the agent uses correctly. 3. An authentication strategy you can pick from: no auth, header-based, URL-based, or OAuth. 4. A working URL you can paste into Moveo to connect the agent. ## Prerequisites - Node.js 18 or newer - A TypeScript project (Next.js, Express, Fastify, or any HTTP framework) - A public-facing HTTPS URL (production: Vercel, Cloud Run, Fly.io; local development: ngrok or similar) ## Install dependencies ```bash npm install mcp-handler @modelcontextprotocol/sdk zod ``` `mcp-handler` is a thin wrapper that hosts an MCP server over Streamable HTTP and provides an `withMcpAuth` helper for OAuth. `@modelcontextprotocol/sdk` is the official MCP SDK. `zod` validates tool inputs. ## Create the route Create `app/api/your-server/mcp/route.ts`: ```typescript export async function POST(request: Request): Promise { const handler = createMcpHandler( (server) => { server.registerTool( searchOrders.name, { title: searchOrders.name, description: searchOrders.description, inputSchema: searchOrders.inputSchema.shape, }, searchOrders.handler ); }, { serverInfo: { name: 'your-server', version: '1.0.0' }, }, { basePath: '/api/your-server', disableSse: true, } ); return handler(request); } ``` A few details that matter: - **`disableSse: true`** — Moveo only connects over Streamable HTTP. The legacy SSE transport is [rejected at the URL-validation step](./mcp-servers#enter-the-server-url). - **`basePath`** — must match the route path so the MCP handler resolves the correct endpoint. - The setup callback is where you register every tool the server exposes. ## Define a tool Create `app/api/your-server/mcp/tools/search-orders.ts`: ```typescript export const searchOrders = { name: 'search_orders', description: 'Search the order database by order number or customer email.', inputSchema: z.object({ query: z.string().describe('Order number or customer email to search for'), limit: z.number().int().min(1).max(20).default(5), }), handler: async (args: { query: string; limit: number }) => { const orders = await fetchOrders(args.query, args.limit); if (orders.length === 0) { return { content: [ { type: 'text' as const, text: `No orders found for "${args.query}".` }, ], }; } const text = orders .map((o) => `Order #${o.id} — ${o.status}, ${o.total} ${o.currency}`) .join('\n'); return { content: [{ type: 'text' as const, text }] }; }, }; ``` That's a working tool — but the description is too thin to make the agent call it reliably. The next section covers the tool-design choices that actually move the needle. --- ## Tool design A tool's name, description, and input schema are part of the system prompt the agent sees. Whether the agent calls the right tool at the right time depends much more on these strings than on the model behind the agent. Treat them as prompt copy. ### The four surfaces the agent sees Every tool exposes four prompt surfaces. Each is read by the model on every turn. 1. **Tool name** — short identifier the agent uses to invoke the tool. 2. **Tool description** — free text. The agent's primary signal for *when* to use the tool. 3. **Input schema** — JSON Schema with field-level descriptions. The agent reads each field's description to fill in arguments. 4. **Tool result** — what the tool returns. The agent uses this to compose a reply or chain into the next tool. Edit all four like you'd edit a guideline. ### Tool names ```typescript // Good 'search_orders' 'cancel_appointment' 'send_invoice' 'get_customer' // Bad 'do_thing' // no information for the agent 'OrderSearch' // wrong case 'query' // generic, collides across tools 'fetch_data' // no domain 'order' // not a verb — is this get? search? create? ``` 1. Use lowercase `snake_case`. Most MCP SDKs require it; the model also handles it more reliably. 2. Lead with a verb. The verb signals action. 3. Use singular for "get one" and plural for "list/search". `get_order` returns one; `search_orders` returns many. 4. Avoid generic names like `query`, `fetch`, `lookup`, `data`. They collide across tools and force the model to read every description. 5. Match the user's vocabulary. If your support team says "ticket" and your database says "issue", name the tool around the user-facing word. 6. Keep names stable. Renaming a tool flips the server [status](./mcp-servers#status-indicators) to **Outdated** and forces a [resync](./mcp-servers#resync-tools). Old guidelines that referenced the old name break. ### Tool descriptions The description is where the agent learns when to call the tool. The model is forced to choose between similarly-named tools by reading these few sentences. Make them count. The same string also appears as a tooltip in the Moveo UI when an operator hovers a tool in the [Edit panel](./mcp-servers#edit-a-server) — write it for both audiences. A reliable structure is **WHAT, WHEN, HOW, RETURNS, NOT**: ```typescript description: `Search the order database by order number or customer email. WHAT: Returns matching orders with their status, total, and last-updated date. WHEN: - Customer asks about a specific order they placed - Customer mentions an order number, email, or "my order" - Customer asks about delivery status of an existing order HOW: - query: order number (numeric, 6+ digits) or customer email address - limit: defaults to 5; raise only if the customer explicitly asks for more RETURNS: Up to N orders, leading with the most recent. Empty list if no match. NOT: For shipping policy or returns, use the knowledge base. For creating new orders, use \`create_order\`. For order line items, use \`get_order_details\`.` ``` The **NOT** section is the highest-leverage. Whenever two tools collide in the agent's mind, fix it by writing a *better NOT* in one description, not by adding rules to a guideline. Other tips: 1. Start the description with the verb. The model often reads only the first line under time pressure. 2. Include domain vocabulary the user will use. If users say "service appointment", put that phrase in the description even if your code calls it `service_booking`. 3. State side effects. If the tool sends an email or charges a card, say so explicitly. Otherwise the agent might call it for exploration and surprise the user. 4. Keep it under ~200 words. Long descriptions waste context, and the model often skims. ### Input schemas The agent reads the schema to know what arguments to send. It honors types, enums, and `describe` strings. Make the schema do as much work as possible. ```typescript // Good inputSchema: z.object({ query: z.string().min(1) .describe('Order number or customer email to search for'), status: z.enum(['active', 'cancelled', 'pending', 'completed']) .optional() .describe('Filter results to a single status'), limit: z.number().int().min(1).max(20).default(5) .describe('Maximum number of results'), }) // Bad inputSchema: z.object({ q: z.string(), // no description, ambiguous name filters: z.record(z.any()), // free-form, no constraints options: z.object({ // deep nesting pagination: z.object({ offset: z.number(), page_size: z.number(), }), }), }) ``` 1. **Describe every field.** A field with no description is a coin flip. 2. **Use enums for known sets.** Free-form strings invite typos. 3. **Set sensible defaults.** The agent will call the tool with fewer arguments and fewer mistakes. 4. **Mark required fields explicitly.** The model treats a missing required field as a hard error — which is what you want when the user hasn't provided the information yet. 5. **Keep it flat.** Deeply nested objects confuse the model. 6. **Validate at the edges.** Add `min`/`max`, `pattern`, `format` constraints the model can read. Even though Moveo [validates arguments](./mcp-servers#tool-invocation) before forwarding, the agent uses these hints when constructing the call. 7. **Don't expose internal IDs.** If your tool needs an `account_id` the user has never typed, the agent can't fill it. Read it from the [Moveo session context](#what-moveo-sends-to-your-server) instead. 8. **Use units in field names.** Prefer `delay_seconds` over `delay`, `price_cents` over `price`. The model picks up on units in field names and rarely converts incorrectly. ### Tool results The string the tool returns is appended to the conversation as if the tool just spoke. Write it for the agent to summarize — not for an end user to read directly. ```typescript // Good — leads with the answer, formatted for paraphrasing return { content: [{ type: 'text' as const, text: `Found 3 orders for jane@example.com: **Order #4521** — shipped, $89.00 USD, updated Mar 2 **Order #4498** — delivered, $145.50 USD, updated Feb 28 **Order #4399** — refunded, $32.00 USD, updated Feb 14 Ask which one the customer is asking about.`, }], }; // Bad — JSON dump return { content: [{ type: 'text' as const, text: JSON.stringify(orders), }], }; ``` 1. **Lead with the answer.** Don't bury it under metadata. 2. **Use markdown sparingly.** Bold for emphasis, lists for enumerations. Tables sometimes confuse smaller models. 3. **Cap volume.** Return at most 5–10 results. The agent can ask the user to narrow down. 4. **Include enough for paraphrasing.** If the agent will ask "is this the right one?", the result needs to contain the disambiguating fields. 5. **Tell the agent what to do next when ambiguous.** "Multiple matches — ask the customer for the order number" inside the result text is more effective than relying on guidelines. 6. **Use the result, not the description, for things that change.** Inventory counts, prices, and status belong in the result. The description is static. ### Error messages When something goes wrong, return a tool result with `isError: true` and a clear message. ```typescript // Good — actionable, plain language return { content: [{ type: 'text' as const, text: 'Order #4521 not found. The order number may be wrong, or it could belong to a different account. Ask the customer to confirm the number.', }], isError: true, }; // Bad — leaks implementation, not actionable return { content: [{ type: 'text' as const, text: '404 NOT_FOUND: SELECT * FROM orders WHERE id=4521 returned 0 rows', }], isError: true, }; ``` 1. **Tell the agent what happened in plain language.** Not error codes. 2. **Tell the agent what to do next.** This becomes the agent's natural reply. 3. **Distinguish recoverable from terminal errors.** "Service is temporarily unavailable, retry in 30 seconds" is recoverable. "This account is closed" is not. 4. **Don't leak implementation.** Stack traces, internal hostnames, SQL errors are noise to the model and risk to your operation. 5. **Match the user's language.** If the conversation is in Spanish, errors should be in Spanish. ### Disambiguating between tools Two tools that look similar from the agent's perspective will be confused. Diagnose with these questions: 1. **Are the names verb-distinct?** `get_order` vs. `search_orders` is good. `get_order` vs. `find_order` is a coin flip. 2. **Do the WHEN sections actually differ?** 3. **Does each description name the other?** "Use this for one order by ID; use `search_orders` when the user gives a name or email instead" cross-references reliably. 4. **Could it be one tool with a mode parameter?** ```typescript // Two close-cousin tools — the agent has to pick the right one { name: 'find_order_by_id', description: 'Look up an order by its numeric ID.', inputSchema: z.object({ id: z.string() }), } { name: 'find_order_by_email', description: 'Find orders for a customer by email address.', inputSchema: z.object({ email: z.string().email() }), } // One tool with a mode — the agent picks from a known enum { name: 'find_order', description: 'Find orders by ID or by customer email.', inputSchema: z.object({ query: z.string().describe('Order ID or customer email'), by: z.enum(['id', 'email']).describe('How to interpret the query'), }), } ``` ### Iteration loop Tool prompts are like guideline copy: ship a draft, watch the model use it, refine. 1. **Run the agent in the test panel** with realistic user messages that should trigger the tool. 2. **Watch the trace** for two failure modes: - The agent does not call the tool when it should. The description's WHEN section is too narrow or the name is wrong. - The agent calls the tool when it shouldn't. Add a NOT clause that rules out the case it just got wrong. 3. **Watch for fishing.** Repeated calls with slight argument variations mean the model doesn't trust the result format. Make the result more decisive. 4. **Watch for hallucination.** If the agent describes calling the tool ("Let me search the orders…") without actually calling it, the description is unclear about whether the tool needs to be invoked vs. mentioned. Tighten WHAT to "Returns…" rather than "Helps with…". 5. **Refine the tool, not the prompt.** When in doubt, the fix lives in the tool definition. Guidelines that say "remember to call `search_orders`" are a smell — the description should make the call self-evident. ### Anti-patterns These keep recurring. Audit your tools for them. - **Tool name as an action.** `do_thing`, `process_request`, `handle_input`. - **Description as documentation.** Long parameter docs, "see also" links, deprecation notices. - **Free-form strings where enums belong.** A `status` field that takes any string. The agent will invent values. - **Identical names with different shapes.** `get_user` on two different MCP servers, with different schemas. Moveo does not let the agent disambiguate by server. Rename one. - **Returning JSON to the agent.** The agent reads the result as text. Return prose or markdown that summarizes the JSON, not the JSON itself. - **One mega-tool with `mode` covering 12 use cases.** Fan out into 2–4 specific tools instead. - **Side effects with no warning.** A tool named `lookup_customer` that secretly creates a CRM contact. Either rename or split. --- ## Referencing tools from guidelines Once your tool is connected in Moveo, the people writing the agent's guidelines can mention it inline. In any guideline editor (Overview, Features, Custom Instructions, Objections), typing `@` opens a picker that lists every enabled tool. Selecting one inserts an inline badge. A realistic guideline reads like business prose with tool references woven in: > When the customer asks about a specific order or mentions an order number, use `@search_orders` to find it. If multiple orders match, ask the customer to confirm which one before continuing. > > If the customer wants to cancel, only use `@cancel_order` after confirming the order number out loud — never cancel based on a partial match. Two practical implications for tool design: 1. **Names appear verbatim in guidelines.** A clean name like `search_orders` reads naturally; `do_search_v2_final` does not. Renames break every guideline that referenced the old name. 2. **Tools can be enabled per-guideline.** Disabling a tool in a guideline removes its references automatically. Build small, focused tools that can be selectively enabled — large catch-all tools become unwieldy. The operator selects which tools are enabled per server in the [Edit panel](./mcp-servers#edit-a-server). The agent reads both the guideline copy and the tool description. The guideline tells it the *workflow*; the description tells it *what the tool does*. Keep them aligned: if the guideline says "search orders by email or order number", the description's WHEN section should match. --- ## Authentication Pick the simplest authentication that meets your security requirements. Moveo's MCP servers UI supports four modes; this section shows how to implement the server side of each. ### No authentication If your tools are read-only and your endpoint URL is hard to enumerate, public access is acceptable. The route shown above accepts any caller. In Moveo, when you add the server, the **Authentication mode** is detected as **None** and the connection is verified automatically. See [No authentication](./mcp-servers#no-authentication) in the UI walkthrough. ### Header authentication Validate a static credential that Moveo passes on every request: ```typescript export async function POST(request: Request): Promise { const apiKey = request.headers.get('x-api-key'); if (apiKey !== process.env.MCP_API_KEY) { return new Response('Unauthorized', { status: 401 }); } const handler = createMcpHandler(/* ... */); return handler(request); } ``` In Moveo: 1. Add the server with the URL of your route. 2. Discovery returns 401 because no header is set yet. 3. Choose **Header authentication** and add a header row: key `x-api-key`, value ``. 4. Select **Connect**. For the full UI flow, see [Header authentication](./mcp-servers#header-authentication) in the MCP servers walkthrough. Header auth fits server-to-server integrations where you can rotate a static secret on a regular schedule. Common conventions: | Convention | Header | |------------|--------| | Bearer token | `Authorization: Bearer ` | | Custom API key | `X-Api-Key: ` | | Vendor-specific | `X--Token: ` | ### URL-based authentication Embed a token directly in the URL path: ```typescript // app/api/your-server/mcp/[token]/route.ts export async function POST( request: Request, { params }: { params: { token: string } } ): Promise { if (params.token !== process.env.MCP_URL_TOKEN) { return new Response('Not Found', { status: 404 }); } const handler = createMcpHandler( (server) => { /* register tools */ }, { serverInfo: { name: 'your-server', version: '1.0.0' } }, { basePath: `/api/your-server/mcp/${params.token}`, disableSse: true, } ); return handler(request); } ``` In Moveo, paste the URL with the embedded token. Discovery succeeds because the URL itself is the credential, so the **Authentication mode** is detected as [**None**](./mcp-servers#no-authentication). URL-based auth is convenient for per-tenant URLs — give each customer their own token-embedded URL and the server can route to the right tenant from the path. It is **not recommended** for long-lived production secrets because the token typically appears in HTTP access logs, CDN caches, and observability tools. ### OAuth For full OAuth 2.0 with PKCE, wrap the handler with `withMcpAuth`: ```typescript export async function POST(request: Request): Promise { const handler = withMcpAuth( createMcpHandler(/* ... */), verifyToken, { required: false, resourceMetadataPath: '/.well-known/oauth-protected-resource/', } ); return handler(request); } ``` `verifyToken` is your function that takes the incoming `Request` and a Bearer token, and returns either an `AuthInfo` object on success or `undefined` to reject. A typical implementation verifies against the authorization server's JWKS: ```typescript const JWKS = createRemoteJWKSet(new URL('https://issuer.example.com/oauth2/jwks')); export async function verifyToken(req: Request, bearerToken?: string) { if (!bearerToken) return undefined; try { const { payload } = await jwtVerify(bearerToken, JWKS, { issuer: 'https://issuer.example.com', }); return { token: bearerToken, clientId: payload.sub || '', scopes: payload.permissions || [], }; } catch { return undefined; } } ``` Provide an OAuth Resource Metadata endpoint at the path you specify in `resourceMetadataPath`, returning the authorization server's discovery URL. Moveo follows that metadata to negotiate the rest of the flow, including dynamic client registration if your provider supports RFC 7591. For the user-facing flow — popup, dynamic registration, manual client credentials fallback — see [OAuth authentication](./mcp-servers#oauth-authentication). If your server uses OAuth, support refresh tokens and document any scopes you require. Moveo stores access and refresh tokens for the connection but cannot recover from a revoked refresh token without a fresh authorization flow. ## What Moveo sends to your server On every tool call, Moveo includes correlation headers so you can log, route, and rate-limit per tenant: | Header | Description | |--------|-------------| | `x-moveo-account-id` | Account that owns the conversation | | `x-moveo-account-slug` | Account slug | | `x-moveo-brain-id` | Identifier of the AI agent making the call | | `x-moveo-desk-id` | Desk identifier | | `x-moveo-session-id` | Conversation session | | `x-moveo-external-id` | External user identifier | | `x-moveo-request-id` | Request correlation ID | | `x-moveo-user-agent` | Moveo user-agent string | In addition, conversation context is passed in the MCP request `_meta` field. From inside a tool handler, access it via the `extra` parameter: ```typescript handler: async (args, { extra }) => { const moveoContext = extra._meta?.['moveo/context']?.context; const language = extra._meta?.['moveo/context']?.lang; const channel = extra._meta?.['moveo/context']?.channel; // ... } ``` The `context` object holds the agent's session variables. Set them from the agent side using a [live-instructions webhook](./build-a-webhook#use-case-live-instructions) before the tool call. ## Update Moveo session context from a tool Tools can write back to the agent's session variables by including a `_meta` field in the response: ```typescript return { content: [{ type: 'text' as const, text: 'Found 3 orders.' }], _meta: { 'moveo/context': { context: { last_search_query: args.query, last_search_count: orders.length, }, }, }, }; ``` The new variables are merged into the session and become available to subsequent tool calls and guidelines (where they can be referenced as `$last_search_query`). ## Deploy and connect from Moveo 1. Deploy your server to a public HTTPS URL. 2. In Moveo, navigate to your AI agent → **Workflows** → **MCP servers** → **Add MCP server**. 3. Paste the full URL of your route (for example, `https://your-server.example.com/api/your-server/mcp`). 4. Pick the matching authentication mode and complete the auth step. 5. Select the tools to expose and save. For the full configuration walk-through in the Moveo UI, see [MCP servers](./mcp-servers). ## Test locally Use a tunnel like [ngrok](https://ngrok.com/) to expose `localhost` over HTTPS, then connect from Moveo with that URL. For automated testing without Moveo, send a JSON-RPC `tools/list` request directly: ```bash curl -X POST https://your-server.example.com/api/your-server/mcp \ -H 'Content-Type: application/json' \ -H 'Accept: application/json, text/event-stream' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' ``` A successful response lists the registered tools with their input schemas. ## Operating your MCP server in production Tool calls happen inside live conversations. The runtime numbers (timeouts, retries, validation, cache TTL) are documented under [Runtime behavior](./mcp-servers#runtime-behavior). The practices below are how you build for them. ### Respect the connection budget Moveo's [connection and discovery](./mcp-servers#connection-and-discovery) handshake is bounded by a 30-second timeout. If your server depends on cold-start work — warming a database connection, fetching auth metadata, loading a model — do that lazily rather than blocking the handshake. The first request can pay the warmup; the handshake should not. ### Keep tool calls fast Tools are called inside a live conversation. Long-running work should either complete in a few seconds or run asynchronously and return a status the agent can poll. Avoid synchronous tool calls that take longer than the user is willing to wait. ### Implement timeouts on the server side Wrap any outbound call your tool makes (HTTP requests, database queries, third-party APIs) with its own timeout that is **shorter** than the [Moveo tool-call budget](./mcp-servers#tool-invocation) (65 seconds). Never let an unbounded operation hang the call. ### Make tool calls idempotent Moveo [retries](./mcp-servers#tool-invocation) connection-level failures and HTTP 5xx/429 once with exponential backoff. Tool-level errors that you return with `isError: true` are passed back to the agent without retrying — that's a deliberate signal. Idempotent tools (same input → same effect) let Moveo retry transport failures safely, and let the agent re-issue a call without duplicating side effects. ### Add retries inside the tool for transient failures If your tool depends on flaky downstream services, retry inside the server with bounded attempts and exponential backoff. Surface a single, clear error to Moveo only when retries are exhausted. ### Version tool definitions deliberately Changes to a tool's description or input schema flip the server [status](./mcp-servers#status-indicators) to **Outdated**. Plan changes so users can [resync](./mcp-servers#resync-tools) at a predictable time, and avoid removing a tool without a deprecation window — guidelines that referenced the removed tool will lose their references. ## Next steps - [MCP servers](./mcp-servers) — connect your built server to Moveo and manage it - [Local tools](./local-tools) — built-in tools that don't require an external server - [Live instructions](./build-a-webhook#use-case-live-instructions) — set session context that MCP tools can read --- ## Compliance profiles Compliance profiles help align your AI Agent with regulatory requirements for outbound campaigns. When a compliance profile is active, the platform applies protections designed to respect legal restrictions, such as blocking contact when regulations require it and respecting time-of-day and frequency limits. Each campaign is assigned a compliance profile that determines which protections are applied. :::warning Important Compliance protections take precedence over custom instructions and [guidelines](./knowledge.md#guidelines). ::: :::caution Compliance profiles are designed to assist with regulatory compliance, but they are not a substitute for legal counsel. You are responsible for ensuring your campaigns comply with all applicable laws and regulations. ::: :::note These profiles are actively evolving. Protections may be added and parameters may change. ::: ## How it works When a compliance profile is assigned, contact attempts are checked against the profile's protections before they are sent. If a protection is triggered: - **Contact is stopped** when the regulation requires it — for example, if the subscriber has filed for bankruptcy or has requested to cease communications. - **Contact is delayed** when timing or frequency restrictions apply — for example, quiet hours or frequency caps. Blocked contacts and their reasons are visible on the campaign's [Performance tab](../campaigns/performance.md), under **Barriers to progress**. ## Setting a compliance profile You select a compliance profile during [campaign creation](../campaigns/campaigns.md): 1. Go to **Campaigns** and click **+ Create** (or edit an existing campaign) 2. In the campaign setup step, select a **Compliance profile** from the dropdown 3. Continue with the rest of the campaign configuration ## Available profiles Across the debt collection profiles, a phone number or email address identified as not belonging to the consumer is not contacted again. This reflects FDCPA §804 (third party) and TCPA called-party consent (first party). ### Default Applies no regulatory protections. Suitable for testing or non-regulated campaign use cases. :::danger This profile does not enforce debt collection regulations. Do not use for real subscriber contact in regulated industries. ::: --- ### US debt collection (first party) For US first-party debt collection — when the original creditor collects on their own debts. This profile includes protections for: - **Bankruptcy Code** — Automatic stay protections - **SCRA** — Active-duty military servicemember protections - **Rosenthal Act** (California) — Contact frequency limits for California residents - **940 CMR 7.04** (Massachusetts) — Contact frequency limits for Massachusetts residents State-specific frequency caps are applied based on the subscriber's state of residence. --- ### US debt collection (third party) For US third-party debt collection — collection agencies and debt buyers. This profile covers federal FDCPA and Reg F requirements, bankruptcy and military protections, and state-level restrictions for California and Massachusetts. **Federal regulations:** - **FDCPA:** - Cease and desist (§805(c)) and refusal to pay — permanently stops contact on all channels when a subscriber requests it in writing. - Attorney representation (§805(a)(2)) — restricts direct contact when a subscriber is represented by an attorney. - Disputes (§809) — stops collection on disputed debts pending verification. - Coerced debt (§809) and identity theft (§809, FCRA §1681c-2) — permanently stops contact. - Inconvenient contact (§805(a)(1)) — delays contact proposed outside the subscriber's stated preferred times or days. - **Reg F** — Enforces the 7-call-per-7-day frequency cap (§1006.14(b)): no more than 7 voice call attempts per 7 days per debt, and no calls within 7 days of a connected conversation. Enforces quiet hours (§1006.6(b)): contact is delayed if proposed outside 8:00 AM – 9:00 PM in the subscriber's local time. Covers deceased subscribers (§1006.6(a)(4)): contact is permanently stopped when a subscriber is confirmed deceased. - **Bankruptcy Code** — Respects the automatic stay (11 U.S.C. §362). When a subscriber has filed for bankruptcy, all contact is permanently stopped. - **SCRA** — Protects active-duty military servicemembers (50 U.S.C. §3901). When active-duty status has been confirmed, contact is permanently stopped pending review of applicable SCRA protections. **State-specific regulations:** - **California** — Enforces the Rosenthal Act's prohibition on unreasonable contact frequency. No more than 7 voice call attempts per 7 days for California residents. - **Massachusetts** — Enforces 940 CMR 7.04(1)(f). No more than 2 communications (voice calls and SMS combined) per 7 days to a personal number for Massachusetts residents. Email is excluded. Unanswered calls count toward the limit. State-specific frequency caps apply **in addition** to the federal frequency cap and are automatically enforced based on the subscriber's state of residence. --- ### Brazil debt collection (third party) For third-party debt collection in Brazil. This profile covers requirements under the Consumer Defense Code (Código de Defesa do Consumidor) and stricter state-level rules. **National rules:** - **Cease communications:** contact is permanently stopped when a consumer asks to stop being contacted. - **Contact hours:** contact is delayed if proposed outside Monday to Friday, 9:00 AM to 7:00 PM, or Saturday, 10:00 AM to 1:00 PM. Sundays are not contacted. - **Public holidays:** contact is delayed on national public holidays. - **Frequency cap** (CDC Art. 71): no more than 3 contact attempts per day, and no contact within 1 day of a connected conversation. **State-specific rules:** Several states enforce stricter contact hours, applied automatically based on the consumer's state of residence: - **Rio de Janeiro** (Lei 7.868/18) and **Espírito Santo** (Lei 10.626/17): Saturday contact is not allowed. - **Paraná** (Lei 22.130/24) and **Amazonas** (Lei 4.644/2018): weekday contact ends at 6:00 PM. --- ### Greece debt collection (third party) For third-party debt collection in Greece. This profile covers requirements under Greek Law 3758/2009 on debtor-information companies (as amended). This profile includes protections for: - **Grace period:** contact does not begin until 10 days after a debt becomes overdue. - **Contact hours:** contact is delayed if proposed outside 9:00 AM to 8:00 PM on working days. - **Public holidays:** contact is delayed on national public holidays. - **Frequency limits:** up to 7 voice call attempts per day, and no more than one verified contact with the debtor every 2 days. Reaching the wrong party does not count toward the verified-contact limit. --- ## Conversation-level protections Beyond the outbound checks above, the AI agent applies compliance guardrails during live conversations: - **Stopping collection** when the consumer asks to cease communications, disputes the debt, reports identity theft or fraud, indicates the debt was coerced, states they have filed for bankruptcy, says they are represented by an attorney, reports the account holder is deceased, or identifies as an active-duty servicemember. - **Responding to safety signals**: if the consumer expresses self-harm or suicidal thoughts, the agent stops immediately and responds with concern. - **Avoiding prohibited topics**, such as credit reporting, litigation, wage garnishment, or asset seizure. - **Protecting third parties**: the agent does not disclose debt details to anyone who is not the consumer. In Brazil, the agent also informs consumers who report financial hardship of their right to request consolidated renegotiation under the over-indebtedness law (Lei 14.181/2021). :::tip Additional compliance profiles are being developed. If your use case requires a profile that is not listed, contact your account manager or reach out to [support](mailto:support@moveo.ai). ::: --- ## Context and variables ## Overview In Moveo, store temporary information during a conversation using **context variables**. These variables apply only to a specific conversation and are automatically deleted once the conversation ends. Context is a collection of key-value pairs that help AI Agents make decisions, store state, and enhance dialog interactions. Context variables can be set at different levels: - **Environment level** (see [Context Bundles](../environments/context-bundles.md)) - **Agent level** (within AI Agents and dialogs) Additionally, context can store user-related information, such as their name, email, or other relevant data. ## Types of context variables ### Dialog variables Create and store variables within a dialog using [questions](./operations/questions.md). These variables are flexible and can be named as needed. ### User variables User-related information is stored in specific system-defined variables, including: - **`$user.display_name`** – User's name - **`$user.email`** – User's email address - **`$user.user_id`** or **`$user.external_id`** – Unique user ID (depends on the communication channel) Some user variables, such as user IDs, are automatically assigned by the system, while others require manual input via **questions** or **forms** at the start of a conversation. :::warning User variables **cannot be set directly**. To assign a value using a [**Set Variable** action](./operations/set-variables.md), select the appropriate key (e.g., `$user.display_name`). For webhook responses, refer to the [Webhook reference](./action-webhooks#sending-replies). ::: ### System variables Moveo provides system-generated variables that contain essential metadata about the conversation: | Variable | Description | | --------------------------- | ----------------------------------------------------------------- | | `$sys-channel` | Communication channel of the conversation | | `$sys-unknown_counter` | Number of times a [fallback](./triggers/unknown.md) was triggered | | `$sys-business` | Indicates if the conversation occurs within business hours | | `$sys-desk` | Identifies the conversation environment | | `$sys-session` | Unique conversation ID | | `$sys-user_message_counter` | Number of messages sent by the user | :::note The **`$sys-unknown_counter`** variable is **zero-indexed**, meaning the first unknown response occurrence is stored as `0`. ::: ### Bundle variables Import variables from **[Context Bundles](../environments/context-bundles.md)** associated with different environments. These variables follow the format: `{{$global.bundle.variable}}`. ### Tags [Tags](./operations/tag.md) assigned by the AI Agent during a conversation are stored in **`$tags`** as a list. For example, if the assistant assigns `location` and `hours` tags, `$tags` will contain `['location', 'hours']`. This variable is useful for: - Filtering conversations in **[Analytics](../analytics/overview.md)** - Triggering specific actions using **[Rules](../environments/rules.md)** - Enhancing human-agent interactions (agents can manually assign tags) To add a new tag, use the **`Add Tag`** dialog action. ### Live instructions The `live_instructions` variable allows real-time updates to the AI Agent, guiding its behavior dynamically based on external input. ## Using context in dialogs Context variables enable various dialog functionalities, such as: - **Setting new variables** - **Updating existing ones** - **Deleting variables** - **Making decisions using conditions** ([Learn more](./operations/conditions.md)) For example, you can check whether a user has provided their email and prompt them accordingly if it's missing. ### Ways to set context variables - **[Questions](./operations/questions.md)** – Collect information during a dialog. - **[Webhooks](./webhooks.md)** – Update variables in real time based on external data. - **[Set Variable action](./operations/set-variables.md)** – Directly assign values in dialogs. ## Using context variables Reference variables in the dialog by using `{{$variable}}`. For example: ```plaintext Hello {{$user.display_name}}, how can I assist you today? ``` Refer to the documentation for more guides on handling context variables effectively. --- ## Dialogs Dialogs are a feature of [AI Agents](../ai-agents/overview.md). Their purpose is to define fixed workflows that the AI agent can follow in a conversation. A dialog is composed of several different blocks, which are connected to each other. Each of these block have different functionalities and have different roles. Each dialog consists of [**trigger**](#triggers) and [**action**](#actions) nodes. ## Triggers Every [dialog](./dialogs.md) starts with a single trigger. Moveo.AI supports the following triggers: | Type | Description | | :-------------------------------- | :------------------------------------------------------------------------------------ | | [Intent](./triggers/text.md) | Triggered on text messages, when the AI agent recognizes an intent | | [Event](./triggers/event.md) | Triggered internally from a different dialog node | | [Fallback](./triggers/unknown.md) | Triggered when Moveo cannot match any of the dialog nodes given the recognized intent | ### Add a trigger Add a new trigger by using Moveo's drag-and-drop functionality. ### Uses of triggers Moveo has two different functionalities for triggers: - They can be used as the parent trigger ($r\_0$, `nodes[0]`) in a dialog. - They can be used as child triggers to provide a different response. See what happens for an [intent trigger](./triggers/text.md#how-to-use-an-intent-trigger) and a [fallback trigger](./triggers/unknown.md). #### Enhance with AI Toggle "Enhance with AI" in the trigger node’s sidebar to enrich responses with relevant contextual information. ## Actions Each time the user sends a message, the AI agent activates one or more [triggers](#triggers). It can then respond in a variety of forms. Actions include plain text, links, menus, and options. Add one or more actions below a [trigger](#triggers) by dragging and dropping them. ### Types of actions Moveo.AI supports the following responses, operations, and extensions: #### Responses | Response | Description | | :---------------------------------- | :-------------------- | | [Text](./responses/text.md) | Reply with a text | | [Image](./responses/image.md) | Send an image | | [Carousel](./responses/carousel.md) | Reply with a carousel | | [Webview](./responses/webview.md) | Display a webview | | [Video](./responses/video.md) | Send a video | | [File](./responses/file.md) | Send a file | | [Survey](./responses/survey.md) | Display a survey | | [URL](./responses/url.md) | Send a URL | #### Operations | Operation | Description | | :--------------------------------------------- | :-------------------------------------- | | [Question](./operations/questions.md) | Ask a question to the user | | [Jump to](./operations/event.md) | Trigger a specific node | | [Condition](./operations/conditions.md) | Create a logic tree | | [Handover](./operations/handover.md) | Transfer the conversation to an agent | | [Tag](./operations/tag.md) | Label the conversation with a tag | | [Pause](./operations/pause.md) | Pause the conversation | | [Set variables](./operations/set-variables.md) | Set a variable equal to a value | | [Reset variables](./operations/reset.md) | Reset specific or all context variables | | [Resolve](./operations/resolve.md) | Close the conversation | #### Extensions | Extension | Description | | :----------------------------------------- | :--------------------------- | | [Webhook](./responses/webhook.md) | Call a predefined webhook | | [Google Sheet](./responses/googlesheet.md) | Store data in a Google Sheet | | [Email](./responses/email.md) | Send an email | ### Add an action Add one or more actions below a [trigger](#triggers) by using Moveo's drag-and-drop functionality. ## Folders A **folder** is a group of dialogs. Its purpose is to create a clean and organized AI Agent, so that you can coordinate better and be more efficient. It's like organizing clothes in a closet's shelves, instead of putting them all in one cupboard. To (re)name a folder, you can double-click its name and enter the new one. ### Moving around dialogs Drag and drop a dialog from any folder to another. Drag a dialog to the area at the bottom of the list to create a new folder, or click on any dialog and then on the **Create dialog** button to create a dialog under the folder you are at. ## Export and import a dialog 1. Select the dialog you want to export. 2. Click on the contextual menu in the top right corner. 3. Select **Export dialog** or **Import dialog**. :::note The exported dialog will be a JSON file. ::: ## Limits Each new dialog turn in Moveo is designed to efficiently handle up to 80 trigger nodes and completes within a maximum timeframe of 17 seconds. This setup ensures optimal performance and user experience during interactions. In practice, these limits are rarely reached unless an unintended infinite loop is introduced through the dialog's event structure. ### Loop Detection To safeguard against such scenarios, Moveo employs real-time loop detection mechanisms. These mechanisms monitor the creation of dialog event loops, typically occurring due to incorrectly configured `jumpTo` actions that inadvertently create cyclic dependencies between dialogs. For instance, a dialog named "Dialog Affirmative" jumps to "Dialog UserInfo", which in turn jumps back to "Dialog Affirmative", forming a loop. While some loops might be intentionally designed to achieve specific conversational flows, most are accidental and can disrupt the user experience. If Moveo detects potential looping behavior, it issues a warning message pointing out the actions in the dialogs that created the loop. This notification serves as a prompt to review and, if necessary, revise the dialog configuration to eliminate the unintended loop. However, if the loop is part of your design and functions as intended, you may disregard this warning. ### Troubleshooting When naming an intent trigger, keep in mind that you are not allowed to use more than 45 characters. Whenever you use a condition, you must add at least one rule and attach a response (action) or you will not be able to save your changes. The field inside an intent trigger cannot be empty. If it is empty, you will not be able to save the changes. Consider converting the intent trigger to an event trigger if you encounter this issue. To attach a new file in a dialog, ensure that the file is accessed through a URL. If you want to use a photo or video, make sure the file is accessed through a URL. For carousels, the title's maximum length is 32 characters and the subtitle's is 80 characters. Each card supports a maximum of 3 buttons, with up to 6 cards total. The Carousel's title, Button's Label, and Postback are mandatory fields. Always remember that when you save your changes, they are not visible to the end user. To make them visible, you must **Publish** them. --- ## Entities Entities are terms or objects that provide context for an [intent](../ai-agents/intents.md) (question category). An entity is the tool that lets you drill down to the options (values) you want your end user to choose from. ## Values Values are the options that derive from an entity. These choices dig further into specific information your AI Agent needs to resolve any issue. Values can also provide more context, allowing you to delve deeper into specific information. ## Synonyms and Patterns In the **Entity | Value | Synonym/Pattern** triad, synonyms and patterns represent the last layer. ### Synonyms Use synonyms to declare different ways the user can refer to each value. The following table shows a possible implementation of an entity that uses synonyms. #### Entity **`@payment_methods`** | Values | Type | Synonyms/Patterns | | :------: | :-----: | :----------------------------------: | | **card** | Synonym | `visa` `mastercard` `credit` `debit` | | **bank** | Synonym | `bank transfer` | | **web** | Synonym | `PayPal` | ### Patterns Patterns control the way information is captured. Patterns are written in the form of [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) with very specific structures like dates, telephone numbers, email addresses, credit card numbers, ZIP codes, and more. The following table shows a possible implementation of an entity that uses patterns: #### Entity **`@contact_info`** | Values | Type | Synonyms/Patterns | | :--------: | :-----: | :---------------: | | **e-mail** | Pattern | `\S+@\S+` | | **phone** | Pattern | `\d{10}` | ## Add a New Entity 1. While in your AI Agent, click on the **Entities** tab. 2. Click on the **+** icon and change the name and description of your entity. 3. Add the entity values along with their synonyms or patterns. :::note Each value can contain either synonyms or patterns, not both. ::: ## Import an Entity To import an entity, click on the import icon on the top right to select a local CSV file. The CSV file **must** have the following format: - Four columns with headers `Entity`, `Type`, `Value`, `Synonyms/Patterns`. - Optional: Under `Entity`, include the name of your imported entity. - Under `Type`, write either `synonym` or `pattern`. - Under `Value`, include the value of the entity. - Under `Synonyms/Patterns`, include the comma-separated synonyms or patterns. Once you upload the file, the values with their synonyms and/or patterns are visible. Save to add the entity to your AI Agent. Download an example CSV file containing an entity. ### Troubleshooting An entity can only take one value in an end user's sentence. This means that if a single sentence contains two or more values of an entity, only **one** of the values will be matched. In the example below, the entity `@payment_methods` contains two values (`card`, `cash`). If the user's sentence contains both of those values, then only one value will be matched to the entity. More specifically, only the last value in the sentence will be matched to the entity. In this example, the entity `@payment_methods` only takes the value `cash`, since it is the last one referenced in the sentence. In general, it is **not** good practice to anticipate that an entity will have multiple values in a user's sentence. If this is anticipated, you would need to create separate entities. While you edit and try giving new names in Entities, you are allowed to use only alphanumeric or underscore characters. --- ## Intents **Intents** are specific purposes or goals that a user has in mind when interacting with a conversational AI system. Intents represent the underlying intention behind a user's input. They can include inquiries about store hours, product availability, sales, as well as frequently asked questions, guidelines, procedures, and actions. ## Overview To plan the scope of your AI agent, it's important to think about the types of questions you want it to be able to answer. For instance, if you want your assistant to handle questions from users wanting to track their order, you can create an intent called `#order_tracking`. The `#` prefix helps distinguish the name as an intent. Once you have identified the questions you want your assistant to address, it's time to start creating the corresponding intents. Aim to have around 6-10 natural language examples for each intent, some of which can also be [generated automatically](#auto-generation) if needed. ### Use case Check out the following example: > I'd like to **book a reservation** at the **Italian restaurant** on **Friday night**. In this example, the user's intention is to book a reservation, so a possible intent is `#book_a_reservation`. The place and the time are information that may differentiate the AI agent's response, so you can handle cases like this by creating two [entities](./entities.md), `@place` and `@time`. ## Create an intent To create an intent, follow these steps: 1. Open your AI agent and select **Conversation**. 2. Click on **Intents**. 3. Press the **Create intent** button. 4. Rename your intent with a descriptive name by double-clicking on the intent name. 5. Add some natural language examples ([training phrases](#training-phrases)) that are related to the intent you want to create. ## Training phrases The number of training phrases needed for an intent to achieve the best results can vary depending on the complexity of the intent and the natural language patterns of your users. However, a general rule of thumb is to include around 6-10 training phrases for each intent you want your assistant to recognize. Having a sufficient number of diverse training phrases can help Moveo learn to accurately classify the intent, even if the user inputs different phrasing or wording. However, it is also important to ensure that the training phrases cover a broad range of variations to avoid overfitting the model to specific examples. It is also important to note that the quality of the training phrases is more important than the quantity. Training phrases that accurately represent the natural language patterns of your users will help the model achieve better results. Additionally, it is recommended to continuously monitor the performance of the intent and adjust the training data as necessary to ensure optimal results. ### Auto-generation Once you input your initial set of examples, Moveo will use them to suggest additional examples that are relevant to your intent. You can then accept or reject these suggestions based on their suitability. The following example illustrates this process: After entering the first two training phrases, Moveo generates new phrases, and you can choose which ones to incorporate into your intent by accepting them. ## Intent performance When building intents for your AI agent, it is important to consider the intent performance. While around 6-10 natural language examples per intent are considered optimal, you should maintain a balance between the number of phrases and the overall performance. The performance bar on the right sidebar can give you a good idea of how well your intent will perform, because it takes into consideration the number of training phrases you have provided for the intent, as well as how they compare to the other intents in the AI agent. ## Confidence Threshold Adjust the confidence threshold of an AI Agent depending on your needs at any time. This threshold accepts a value between 0 and 1, representing the minimum confidence level your AI Agent should have to answer a question it is not exactly trained on. For example, for a typo like "Helor there," your AI Agent should have a high level of confidence to respond with the `#greetings` intent, assuming you have added an expression like "Hello there" to this intent. Conversely, for a phrase like "ffdfdgd," the assistant should have a low level of confidence in replying. :::note An AI Agent set at a 0.70 confidence threshold would respond to the "Helor there" message and trigger the [unknown](./triggers/unknown.md) intent for the "ffdfdgd" message. ::: The confidence threshold is located in the **Advanced** section of your AI Agent. ## Connect a flow After you create your intent, you can immediately connect it to a new [dialog](./dialogs.md) by clicking on **Connect**. Pick a name for your new dialog, as well as the folder you want to classify it. Then, write the reply of the assistant, click **Create** and modify the dialog to your needs. ## Good and bad practices | Do's :heavy_check_mark: | Don'ts :x: | | :------------------------------------------------------------------------: | :--------------------------------------------------------------------------: | | Do make sure the intent is specific enough. | Don't make the intent and its expressions too general or too vague. | | Do ensure the intent has a clear purpose. | Don't create intents that overlap or are redundant. | | Do use clear and concise language. | Don't use ambiguous language and **unclear** jargon. | | Do try to maintain a balance in the number of training phrases per intent. | Don't add training phrases, in which the only variation is upper/lower case. | | Do try to merge subsets of the same flow into one. | Don't use similar training phrases to different intents. | ### Create a specific and precise intent To create a successful intent, it's important to make sure that it is specific enough to capture the user's intention without being too general or vague. For example, if you want your AI agent to help users check the status of their order, a good intent name might be `#check_order_status`. This name is specific enough to accurately represent the user's intention, while also being clear and easy to understand. On the other hand, an intent name like `#ask_about_orders` is too general and may not accurately capture the user's intention. Similarly, when adding training phrases to your intent, make sure they are specific and relevant to the intent's purpose, rather than being too broad or ambiguous. ### Create clear and purposeful intents When creating intents for your AI agent, it's important to ensure that each intent has a clear and specific purpose. This will make it easier for the assistant to understand and respond to user requests accurately. However, you should also avoid creating intents that overlap or are redundant, as this can cause confusion for both the user and the assistant. For example, if you have an intent called `#check_order_status`, you should not create a separate intent called `#view_order_details` as these two intents are likely to have overlapping expressions. ### Use clear and concise language Use simple and clear language for the training phrases of your intents. Avoid **ambiguous** jargon and aim to familiarize the AI agent with your users' language. - :heavy_check_mark: **Good examples**: - When will my order arrive? - How much does this product cost? - :x: **Bad examples**: - ETA of package - What's the MSRP of this product? ### Use effective training phrases You should aim to keep a consistent number of training phrases per intent, ideally 6-10. Having too few or too many training phrases can lead to confusion or ambiguity for the AI agent. Avoid duplicating training phrases that only vary in capitalization. For instance, instead of using **Where is my order?** and **WHERE IS MY ORDER?** as separate training phrases, you can use a different phrase conveying the same meaning, like **What is the status of my delivery?**. This provides a more diverse range of inputs for the AI agent to recognize, resulting in a more accurate and robust system. ### Merge different subflows into one Consider combining similar thought processes into a single intent for better clarity. For example, instead of treating **Pay with card**, **Pay with cash** and **Pay with a coupon** as separate flows, it's strongly suggested to consolidate these cases into one flow, **Payment methods**. Given that these cases share similarities and have overlapping training phrases, combining them can help streamline the process and improve the confidence with which the assistant can answer a question on this topic. Additionally, you can include the supported **payment methods** as an [entity](./entities.md). In this case, you should remove the intents handling the card, cash, and coupon cases, and move them all into one intent called `#payment_methods`. This intent may include expressions such as: - How can I pay? - What are the available payment methods? - In which ways may I pay off my account? - Is it possible to pay with cash? - Can I pay my account with my card? - I want to use a coupon for the payment. ## Export and import intents Export and import intents using CSV files. The process is the same for both operations: ### To import an intent: 1. Click on the import icon on the top right to select a local CSV file 2. The CSV file **must** have the following format: - Two columns with headers `Intent` and `Expression` - Optional: Under `Intent`, write the name of your imported intent - Under `Expression`, write the expressions referring to the imported intent 3. Once you upload the file, save to add the intent to your AI agent ### To export an intent: 1. Click on the export icon on the top right to download the intent as a CSV file 2. The exported file will follow the same format as described above 3. You can then use this file to import the intent into another AI agent Download an [example intent](https://media.moveo.ai/media/accounts/65251a75-c3c5-4e51-86b9-21bc1905ae69/daaf9c9a-6c2b-46d0-ae41-ddcd22ff5623.csv) to see the correct format. ## Off-topic messages Your AI agent, once trained, has knowledge about the topics you teach it. However, it also knows when it doesn't know something. Moveo classifies all user messages into two groups: those that fit within an existing intent that it knows, and those that fall under the `#offtopics` category, which is a default category that cannot be deleted. You can also add specific phrases to this _system_ intent that you want your agent to recognize as off-topic messages. :::tip Do not connect an [intent trigger](./triggers/text.md) to the `#offtopics` intent, but rather handle the cases where it is triggered with a [fallback](./triggers/unknown.md). ::: --- ## Knowledge & Guidelines Knowledge and Guidelines work together to create intelligent, contextual AI agents. **Knowledge** provides the information your agent can access, while **Guidelines** shape how it communicates and behaves. ## [Knowledge base](../knowledge-base/overview.md) A knowledge base is your agent's collection of information that it relies on to answer questions and provide support. When a user asks a question, the agent searches connected knowledge bases, retrieves the most relevant fragments, and uses this information along with guidelines to generate a response. This RAG (Retrieval Augmented Generation) approach ensures accurate, grounded responses based on your actual content. For setup instructions, see [Knowledge agent quick start](./quickstart.md). ## Guidelines Guidelines are instructions that define your AI agent's personality, behavior, and response patterns. ### Personalization The **Personalization** field links your agent's **first message webhook** — the webhook that runs once at the start of each conversation to fetch data about the user and inject it into the conversation context. Those context variables are what [dynamic personalization](#dynamic-personalization) reads (name, account type, tenure, and so on). - Personalization always maps to the **first message** webhook, and an agent has at most one. - If none exists yet, click **Create** to add one — it's linked here automatically. - Other webhook types (pre message, post message, dialog, authentication) run at different points and aren't personalization webhooks. Manage them on the [Webhooks](./webhooks.md) page; they don't appear in this field. ### Writing effective guidelines The quality of your guidelines directly impacts agent performance. Here's how to write guidelines that work: #### 1. Be specific and clear ```md When users ask about pricing, always mention: 1. Starting price is $29/month 2. 14-day free trial available 3. Annual billing saves 20% 4. Enterprise plans available for 50+ users Format prices with currency symbol first (e.g., $29 not 29$). ``` ```md Tell users about our pricing when they ask. ``` #### 2. Handle objections strategically ```md Price Objection Response Framework: 1. Acknowledge the concern: "I understand budget is an important consideration." 2. Highlight value: "Our customers typically save 10+ hours per week." 3. Reduce risk: "That's why we offer a 14-day free trial." 4. Provide options: "We also have a starter plan at $19/month." Never dismiss price concerns or say "it's worth it" without explanation. ``` #### 3. Set clear boundaries ```md Topics to avoid: - Political opinions or commentary - Medical or legal advice - Competitor pricing without context - Promises about future features not yet released If asked about these topics, politely redirect: "I'm focused on helping you with [your product/service]. For [topic], I'd recommend consulting with a qualified [professional type]." ``` #### 4. Include examples ```md When explaining our return policy: User: "Can I return this after 30 days?" Response: "Our standard return window is 30 days from purchase. If you're slightly past that date, I can check if we can make an exception. May I have your order number?" Always offer to help even when the standard policy doesn't apply. ``` ### Predefined fields by agent type Each agent type has different predefined guideline fields optimized for its use case. Fill out the **Goal** field first to establish your agent's primary objective, then add supporting context in the other fields. Customer Support agents use **Objections** and **Custom instructions** fields. **Custom instructions:** ```md Deliver clear and knowledgeable assistance in every interaction. Always begin by acknowledging the customer's concern and showing understanding of their situation. Guide them through solutions in a step-by-step manner, ensuring they feel supported throughout the process. When possible, offer educational resources, FAQs, or tutorials that empower customers to solve issues independently in the future. Turn challenges into positive experiences that strengthen trust and loyalty. ``` **Objections:** ```md ## I've already tried that and it didn't work I'm sorry that didn't resolve your issue. Let me look into this more closely and find an alternative solution for you. ``` Early Engagement agents use **Goal**, **Overview**, **Features**, **Loyalty**, **Objections**, and **Custom instructions** fields. **Goal:** ```md Build meaningful relationships with potential customers by understanding their needs and guiding them toward the right solutions. ``` **Overview:** ```md We help businesses connect with their customers through personalized engagement strategies, proactive outreach, and value-driven conversations. ``` **Features:** ```md Personalized recommendations, needs assessment, product demonstrations, resource sharing, and relationship building through ongoing communication. ``` **Loyalty:** ```md Engaged customers become brand advocates who return for repeat purchases and recommend our products to others. ``` **Objections:** ```md ## I'm just browsing for now That's perfectly fine! Is there anything specific you're looking for that I can help point you in the right direction? ``` **Custom instructions:** ```md Focus on creating a welcoming and engaging first impression to build trust early in the conversation. Take the initiative to understand the customer's needs, goals, or challenges by asking open-ended questions. Offer relevant information, product insights, and helpful resources before the customer makes a decision. Avoid being pushy — instead, aim to guide the customer to establish a long-term relationship. ``` Product Adoption agents use **Goal**, **Overview**, **Features**, **Loyalty**, **Objections**, and **Custom instructions** fields. **Goal:** ```md Guide customers through a seamless onboarding experience that helps them start using the product effectively and confidently. ``` **Overview:** ```md Our product helps customers get started quickly with intuitive setup wizards, guided tutorials, and personalized onboarding paths tailored to their needs. ``` **Features:** ```md Interactive tutorials, progress tracking, milestone celebrations, personalized tips, quick-start guides, and in-app help resources. ``` **Loyalty:** ```md Customers who complete onboarding successfully are more likely to become long-term, engaged users who advocate for our product. ``` **Objections:** ```md ## I don't have time right now The setup only takes a few minutes, and you can pause and resume anytime. Would you like me to highlight the essential steps first? ``` **Custom instructions:** ```md Guide customers through a seamless onboarding experience that helps them start using the product effectively and confidently. Provide clear, easy-to-follow steps that highlight key features and benefits. Anticipate common challenges during setup and proactively offer guidance to prevent frustration. Encourage engagement by celebrating milestones and progress. Share actionable tips, best practices, and real-world examples that help customers quickly realize the value of the product and become long-term, confident users. ``` Upsell agents use **Goal**, **Overview**, **Features**, **Loyalty**, **Objections**, and **Custom instructions** fields. **Goal:** ```md Help customers discover premium features and upgrades that can enhance their experience and deliver additional value. ``` **Overview:** ```md We offer tiered solutions that scale with customer needs, from essential features to comprehensive enterprise packages. ``` **Features:** ```md Advanced analytics, priority support, extended storage, premium integrations, dedicated account management, and custom solutions. ``` **Loyalty:** ```md Customers who upgrade often experience greater success with our product and become our most loyal, long-term partners. ``` **Objections:** ```md ## I'm happy with what I have That's great to hear! Just so you know, when you're ready to scale or need additional features, our premium options are designed to grow with you. ``` **Custom instructions:** ```md Actively look for moments when an upgrade or additional feature could genuinely improve the user's experience or results. Understand their current usage, needs, and priorities before suggesting an upsell. Highlight how higher-tier options deliver extra value, convenience, or capabilities that directly support their goals. Focus on helping the customer see the benefits rather than pushing for a sale. Always present upgrades as opportunities for growth, efficiency, or enhanced satisfaction. ``` Debt Collection agents use **Goal**, **Objections**, and **Custom instructions** fields. **Goal:** ```md Encourage the user to initiate payment for delinquent amounts by highlighting the potential benefits of resolving their debt promptly. ``` **Objections:** ```md ## I can't afford to pay right now I understand finances can be tight. We have flexible payment plans that can work with your budget. Would you like me to walk you through your options? ``` **Custom instructions:** ```md Approach every interaction with respect and professionalism. Acknowledge the customer's situation and express a willingness to help them find the best solution. Offer flexible repayment or settlement options when possible and explain terms, deadlines, and available assistance clearly. Emphasize collaboration and reassurance — the goal is to resolve the debt smoothly while preserving a positive customer relationship and encouraging future engagement. Divide the conversation into clear, simple steps: 1. Explain the reason for the conversation. 2. Present the available payment options and highlight any available discounts. 3. Present the installment payment option. ``` ### Adding custom guidelines In addition to the predefined fields, you can add custom guidelines for specific topics or scenarios. Each custom guideline has a title and body. **To add a custom guideline:** 1. Navigate to your AI Agent's **Knowledge** tab 2. Click **Add guideline** 3. Enter a descriptive title (e.g., "Return Policy", "Pricing Questions") 4. Write the guideline content in the body ### Advanced guideline techniques #### Dynamic personalization Use context variables to personalize responses: ```md If the user's account type is "Premium": - Mention premium-only features - Provide priority support language - Reference their dedicated account manager If the user is a new customer (account age < 30 days): - Be extra helpful and patient - Proactively offer onboarding resources - Check in on their progress ``` #### Conditional responses Create branching logic in your guidelines: ```md For technical questions: - If basic user: Provide simple, non-technical explanation - If power user: Include advanced options and shortcuts - If developer: Reference API docs and code examples Identify user type by their question complexity and terminology used. ``` #### Multi-language considerations ```md When responding in languages other than English: - Maintain the same tone and professionalism - Use formal address unless the culture prefers informal - Be aware of cultural sensitivities - Localize examples (currency, dates, measurements) ``` #### Channel-specific guidelines Channel-specific guidelines let you customize how your AI agent responds on different communication channels. Each channel has unique characteristics — a voice call requires concise, spoken-friendly responses while an email can include detailed formatting and attachments. The Guidelines page has two tabs: - **Guidelines** — Your default guidelines that apply across all channels (Goal, Overview, Objections, Custom instructions, etc.) - **Channel-specific** — Per-channel overrides for **Voice**, **Email**, and **Chat** Channel-specific instructions are layered on top of your default guidelines during response generation. If a channel has specific guidelines, those instructions are included alongside the defaults to shape how the agent responds on that channel. The available channels are **Voice**, **Email**, and **Chat**. **To configure channel-specific guidelines:** 1. Navigate to your AI Agent's **Guidelines** page 2. Select the **Channel-specific** tab 3. Write guidelines for each channel (Voice, Email, Chat) 4. Click **Save** :::tip Channel-specific guidelines count toward your total guideline character limit. Keep an eye on the character counter when writing guidelines across multiple channels. ::: ### Testing and iterating guidelines Your guidelines should evolve based on real interactions: 1. **Start simple** - Begin with core guidelines and add complexity gradually 2. **Monitor conversations** - Review actual interactions to identify gaps 3. **A/B test variations** - Try different guideline approaches 4. **Gather feedback** - Ask users if responses were helpful 5. **Update regularly** - Refine based on new products, policies, or learnings :::tip Pro tip Use the Insights feature to get AI-powered suggestions for improving your guidelines based on actual conversation patterns. ::: ### Common guideline mistakes to avoid | Mistake | Why it's problematic | Better approach | | ------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------ | | Too vague | "Be helpful" doesn't guide specific behavior | "When users ask for help, first clarify their specific need, then provide step-by-step guidance" | | Contradictory rules | Confuses the agent and creates inconsistent responses | Review all guidelines together to ensure alignment | | Over-scripting | Makes responses robotic and inflexible | Provide frameworks and principles, not word-for-word scripts | | Ignoring edge cases | Agent struggles with unusual requests | Include "If unsure..." fallback instructions | | No personality | Creates generic, unmemorable interactions | Define specific tone, style, and even catchphrases | ### Combining knowledge and guidelines The magic happens when knowledge and guidelines work together: **Example scenario:** User asks "How do I reset my password?" 1. **Knowledge provides:** The actual reset process from your documentation 2. **Guidelines shape:** How to present this information (tone, detail level, additional offers) **Result:** A response that's both accurate (from knowledge) and on-brand (from guidelines). ### Best practices summary ✅ **Do:** - Write guidelines as if training a new team member - Use specific examples and scenarios - Update guidelines based on real conversations - Test different approaches and measure results - Keep guidelines organized and non-conflicting ❌ **Don't:** - Write vague or generic instructions - Create overly rigid scripts - Ignore cultural and language considerations - Forget to handle edge cases - Neglect regular updates and improvements ## Next steps - [Knowledge base overview](../knowledge-base/overview.md) - Create and manage your content - [Setup](./setup.md) - Configure tone, response length, and reminders - [Test your agent](./test.md) - Validate responses before deployment - [Analytics](../analytics/overview.md) - Monitor agent performance --- ## Local tools Local tools are built-in tools provided by Moveo that your AI agent can invoke directly from guidelines. They let the agent trigger workflows, compose rich responses, execute code, detect voicemails, and search the knowledge base on demand — without requiring external server configuration. :::note Local tools are different from [MCP servers](./mcp-servers). MCP servers connect to external tool providers, while local tools are internal to Moveo and ready to use out of the box. ::: ## Available tools | Tool | Description | Channel support | |------|-------------|-----------------| | **Trigger workflow** | Hands off the conversation to a specific workflow. The workflow takes over the response — the AI agent does not respond separately. | All channels | | **Compose rich response** | Lets the AI agent compose structured responses with buttons, carousels, images, and files. | Chat, web widget, and messaging channels only. Not available on voice, email, or SMS. | | **Execute code** | Lets the AI agent run code for math calculations and complex operations. | All channels | | **Voicemail detection** | Detects voicemail systems and optionally leaves a message. | Voice channels only | | **On-demand knowledge retrieval** | Lets the AI agent fetch relevant information from the knowledge base on demand. | All channels | ## Enable or disable a tool Navigate to your AI agent → **Workflows** → **MCP servers**, then select the **Local tools** tab. Each tool has a toggle switch. Activate a toggle to make that tool available to the AI agent. :::warning Disabling a tool that is referenced in your guidelines removes all its references automatically. Review your guidelines after disabling a tool that was central to the agent's behavior. ::: When you disable a tool that is already referenced in guidelines, a warning dialog appears: - The dialog explains that all tool references will be removed from guidelines - Select **View guideline** to review the affected guidelines before confirming - Select **Disable** to proceed, or **Cancel** to keep the tool enabled ## Reference a tool in guidelines You can reference local tools in any guideline editor — Goal, Overview, Features, Loyalty, Objections, or Custom Instructions. ### Insert a tool reference 1. Open a guideline editor 2. Type `@` to open the suggestion menu 3. Select a tool from the list The tool appears as an inline badge in the editor (for example, `@compose_rich_response`, `@execute_code`, or `@search_knowledge_base`). ### Insert a trigger workflow reference The **Trigger workflow** tool requires you to select a specific workflow: 1. Type `@` and select **Trigger workflow** 2. A workflow picker opens automatically 3. Select the target workflow from the list The badge displays as `@trigger_workflow(workflow name)`, where the workflow name updates automatically if you rename the workflow. :::tip If the `@` menu is empty, no tools are enabled. Select the link in the empty state prompt to go to the Local tools settings and enable them. ::: ## Runtime behavior When the AI agent encounters a tool reference in guidelines during a conversation, it invokes the tool automatically. ### Trigger workflow The conversation hands off to the selected workflow. The workflow owns the response from that point — the AI agent does not receive a result back and does not respond separately. ### Compose rich response The AI agent composes a structured response with elements like text with buttons, carousels, images, or files. The response is sent directly to the user. :::caution This tool only works on channels that support rich payloads (chat, web widget, messaging). Enabling it has no effect on voice, email, or SMS channels. ::: ### Execute code The AI agent runs code to perform complex operations such as math calculations. The result is used in the agent's response. ### Voicemail detection The AI agent detects whether a voicemail system has answered and can optionally leave a message. :::caution This tool only works on voice channels. Enabling it has no effect on other channels. ::: ### On-demand knowledge retrieval The AI agent can search the knowledge base for additional information during the conversation. The default knowledge base retrieval still happens automatically at the start of each turn, but when the prefetched results are not enough to answer the user's question, the agent can fetch extra information on demand. ## Delete a workflow referenced in guidelines When you delete a workflow that is referenced by `@trigger_workflow` in guidelines, a warning appears: - The dialog explains that the tool reference will be removed from guidelines - Select **View guideline** to review the affected guidelines - On confirmation, all `@trigger_workflow` references pointing to that workflow are removed automatically ## Troubleshooting
The @ menu shows no tools No local tools are enabled. Go to your AI agent → **Workflows** → **MCP servers** → **Local tools** tab and enable the tools you need.
Tool references disappeared from guidelines Tool references are removed automatically when you disable a tool or delete a workflow that the tool points to. Re-enable the tool and re-insert the references.
Compose rich response has no effect This tool only works on channels that support rich payloads (chat, web widget, messaging). It has no effect on voice, email, or SMS channels.
Voicemail detection has no effect This tool only works on voice channels. It has no effect on chat, web, email, SMS, or messaging channels.
--- ## Next steps - [MCP servers](./mcp-servers) — connect external tools via the Model Context Protocol - [Workflows](./dialogs) — build conversation workflows that tools can trigger --- ## MCP servers MCP servers extend your AI agent with external tools through the Model Context Protocol (MCP). Once connected, the agent can use the server's tools during conversations to query databases, call APIs, or interact with third-party services — without you having to write any custom integration code. :::note MCP servers connect external tool providers. For tools built into Moveo (workflow triggers, rich responses, code execution, voicemail detection, on-demand knowledge), see [Local tools](./local-tools). To build your own MCP server — including tool design and prompting practices — see [Build an MCP server](./build-an-mcp-server). ::: ## Overview An MCP server exposes a set of tools over the Model Context Protocol. After you connect a server, Moveo discovers the tools it offers, you choose which ones to enable, and the agent can call them while talking to a user. ### Authentication modes Moveo automatically detects the authentication mode of the server you connect. | Mode | When it applies | What you provide | |------|-----------------|------------------| | **None** | Server is publicly accessible | Just the URL | | **Header** | Server expects credentials in HTTP headers (for example, an API key) | Header key and value pairs | | **OAuth** | Server uses OAuth 2.0 with PKCE | Connect via popup; client credentials registered automatically when the server supports RFC 7591, otherwise entered manually | If you are building the server yourself, see [Authentication](./build-an-mcp-server#authentication) for how to implement each mode. ### Transport Moveo connects over **Streamable HTTP**. The legacy SSE transport is deprecated and rejected at the URL-validation step. For the route setup on the server side, see [Create the route](./build-an-mcp-server#create-the-route). ## Prerequisites Before adding an MCP server, ensure you have: - An MCP server endpoint URL that supports Streamable HTTP - Credentials for the server's authentication mode (if any) ## Add an MCP server Navigate to your AI agent → **Workflows** → **MCP servers**, then select **Add MCP server**. {/* TODO: Replace static images in this section with a single Arcade walkthrough showing URL entry → discovery → authentication → tool selection → save. */} To connect a server: 1. Enter the server URL. 2. Authenticate using the mode Moveo detects. 3. Select which tools the agent can use. ### Enter the server URL Enter your MCP server URL. When you tab out of the field, Moveo contacts the server, detects the authentication mode, and shows a status indicator next to the URL. :::warning SSE transport is deprecated. If your URL ends with `/sse`, remove that suffix and use the base endpoint instead. ::: ### Authenticate The next step depends on the authentication mode Moveo discovered. #### No authentication If the server is public, Moveo confirms the connection automatically and moves on to tool selection. No further input is needed. {/* TODO: Arcade — show a discovery completing on a public MCP server with the green checkmark and immediate tool list reveal. */} #### Header authentication For servers that expect credentials in HTTP headers (for example, an API key passed as `Authorization: Bearer ` or `X-Api-Key: `): 1. Enter a name for the server. 2. In the **Custom headers** section, add one or more header key/value pairs. 3. Use the eye toggle to mask or reveal a value. 4. Select **Connect**. Moveo calls the server with your headers to verify access and retrieve the tool list. :::tip Header values are stored as secrets. Anyone with edit permission can update them, but they are masked by default in the UI. ::: {/* TODO: Arcade — show the header rows being added, eye toggle masking the value, then a successful Connect that reveals tools. */} For how to validate the header on the server side, see [Header authentication](./build-an-mcp-server#header-authentication) in the implementation guide. #### OAuth authentication For OAuth-protected servers: 1. Enter a name for the server. 2. If the server supports **dynamic client registration (RFC 7591)**, Moveo registers a client automatically and shows a confirmation. Otherwise, enter the **client ID** and **client secret** issued by the authorization server. The **authorization URL** and **token URL** are filled in from server discovery, but you can override them. 3. Select **Connect** to start the OAuth flow. 4. A popup opens to the authorization server. Sign in and authorize Moveo. 5. The popup closes automatically on success and Moveo retrieves the tool list. {/* TODO: Arcade — show the OAuth flow end-to-end: dynamic registration confirmation, Connect button, popup auth, return with tools loaded. */} :::note Moveo uses PKCE (RFC 7636) for every OAuth flow. The callback URL shown in the panel is the redirect URI to whitelist on your authorization server when dynamic registration is not available. ::: For the server side — JWKS verification, the OAuth Resource Metadata endpoint, and refresh tokens — see [OAuth](./build-an-mcp-server#oauth) in the implementation guide. ### Select tools After authentication succeeds, Moveo lists every tool the server exposes. All tools are selected by default. 1. Use **Select all** to enable all tools, or **Select none** to clear selections. 2. Hover over a tool to see its description. 3. Select **Add** to save the server with the chosen tools enabled. The tool names and descriptions you see here are set by the server. For guidance on writing them so the agent uses the tools correctly, see [Tool design](./build-an-mcp-server#tool-design). --- ## Manage MCP servers The MCP servers table lists every configured server with its current status. ### Table columns | Column | Description | |--------|-------------| | **Name** | Server name and number of enabled tools | | **URL** | Server endpoint | | **Created by** | User who created the server | | **Last used** | When the server was last called | | **Status** | Connection and sync status | | **Enable** | Toggle to activate or deactivate the server | | **Actions** | Edit, resync, or delete | ### Status indicators | Status | Meaning | |--------|---------| | **Verified** | Connected; tools and authentication are in sync | | **Outdated** | Tool definitions changed on the server and need to be resynced | | **Error** | Moveo cannot reach the server with the current credentials | ### Edit a server Select a row in the table or choose **Edit** from the actions menu to modify a server. {/* TODO: Arcade — show opening the edit panel, renaming, toggling individual tools, then Update. */} The edit panel lets you: - **Rename** the server. - **View the URL** (read-only, with a copy button). The URL cannot be changed after creation; delete the server and create a new one to point at a different endpoint. - **Update custom headers** — only when the server uses [header authentication](./build-an-mcp-server#header-authentication). - **Toggle individual tools** on or off. Hover over a tool to see its description and last-used time. Tool descriptions are set on the server side — see [Tool descriptions](./build-an-mcp-server#tool-descriptions). When you open the edit panel, Moveo refetches the latest tools from the server. Tools added on the server side appear here so you can enable them. :::warning If the server status is **Outdated**, you must resync before saving. The **Update** button stays disabled until the resync completes. ::: Select **Update** to save changes. ### Resync tools When an MCP server changes its tool definitions, the server status switches to **Outdated**. Resync brings your local tool definitions back in line with the server. 1. Select **Resync** from the actions menu or from the edit panel. 2. The dialog shows a diff: - **Updated** — the tool's description or input schema changed. - **Deleted** — the tool no longer exists on the server. 3. Select **Resync** to apply the changes. {/* TODO: Arcade — show the Outdated badge, opening Resync, the diff dialog, and the badge flipping to Verified. */} :::note Resync only updates or removes existing tools. **New tools added on the server do not appear in the resync dialog.** To enable a newly added tool, open the edit panel — the tool list there is always refetched live. ::: For guidance on evolving tools without breaking guidelines that reference them, see [Version tool definitions deliberately](./build-an-mcp-server#version-tool-definitions-deliberately). ### Enable or disable a server Use the toggle in the **Enable** column to activate or deactivate an MCP server. A disabled server stays configured, but the agent cannot call any of its tools. ### Delete a server From the actions menu, select **Delete** to remove a server. This action cannot be undone, and any guideline that referenced the server's tools loses those references. For how guidelines reference tools, see [Referencing tools from guidelines](./build-an-mcp-server#referencing-tools-from-guidelines). --- ## Runtime behavior Once a server is verified and enabled, Moveo invokes its tools during conversations the same way it invokes local tools. A few details are worth knowing as a server author or operator. ### Connection and discovery - Connection establishment, tool discovery, and the connection test that runs when you add or edit a server are bound by a **30-second timeout**. A server that does not complete the MCP handshake in that window is reported as unreachable. To stay inside this window, see [Respect the connection budget](./build-an-mcp-server#respect-the-connection-budget). - Moveo negotiates **Streamable HTTP** first and falls back to SSE only when the server returns 404 or 405 on the Streamable HTTP endpoint. New servers should set `disableSse: true` — see [Create the route](./build-an-mcp-server#create-the-route). ### Tool invocation Tools are invoked at conversation time. Moveo bounds each invocation by a timeout and surfaces the result back to the agent for it to incorporate into its reply. - **Connect timeout** — 3 seconds to establish the HTTP connection. - **Read timeout** — 65 seconds for the server to return the tool result. To stay inside this budget, see [Implement timeouts on the server side](./build-an-mcp-server#implement-timeouts-on-the-server-side). - **Retries** — Connection-level failures and the HTTP statuses 5xx and 429 are retried once by default with exponential backoff (up to 10 seconds). Tool errors returned with `isError: true` are **not** retried — they are passed back to the agent as a deliberate signal it can act on. To make retries safe, see [Make tool calls idempotent](./build-an-mcp-server#make-tool-calls-idempotent). - **Tool definition cache** — Discovered tool schemas are cached for 2 minutes. After a resync in the UI, expect a brief window before every running conversation sees the updated schemas. Plan schema changes accordingly — see [Version tool definitions deliberately](./build-an-mcp-server#version-tool-definitions-deliberately). - **Argument validation** — Moveo validates each tool call against the tool's input schema before sending it to the server. Invalid arguments are returned to the agent as a structured error for self-correction; your server is not contacted in that case. Schemas with clear field descriptions and enums get fewer invalid calls — see [Input schemas](./build-an-mcp-server#input-schemas). ### Error codes When a connection or tool call fails, Moveo records one of the following error codes: | Code | Meaning | |------|---------| | `connection_timeout` | Server did not respond within the timeout window | | `unauthorized` | Server returned HTTP 401 — credentials are missing, invalid, or expired | | `not_found` | Server returned HTTP 404 | | `connection_refused` | TCP connection was refused (server not listening) | | `http_` | Other HTTP status returned by the server | | `connection_failed` | Catch-all for other transport failures | --- ## Troubleshooting
SSE endpoint error The SSE transport is deprecated. If your server URL ends with `/sse`, remove that suffix and use the base endpoint: - **Wrong:** `https://example.com/mcp/sse` - **Correct:** `https://example.com/mcp`
Discovery times out Moveo waits up to 30 seconds for the server to complete the MCP handshake. If discovery times out: 1. Confirm the server is reachable from the public internet. 2. Make sure the server completes its initial handshake quickly — defer any cold-start work until the first tool call. See [Respect the connection budget](./build-an-mcp-server#respect-the-connection-budget). 3. Check that the URL points at the Streamable HTTP endpoint, not a marketing or documentation page.
OAuth connection fails If OAuth authorization fails: 1. Verify the server supports OAuth and is properly configured. See [OAuth](./build-an-mcp-server#oauth) for the server-side setup. 2. If dynamic client registration fails, enter client credentials manually. 3. Make sure your authorization server allows the Moveo redirect URI shown in the panel. 4. Confirm the scopes the server requires are available on the access token.
Header authentication fails If a header-authenticated server returns **Error** after Connect: 1. Check the header names exactly. Common patterns: `Authorization: Bearer `, `X-Api-Key: `. See [Header authentication](./build-an-mcp-server#header-authentication) for server-side validation. 2. Confirm the credential is valid and has not been rotated. 3. Reopen the edit panel and re-enter the value — masked values are not visible after save.
Tools not appearing after resync Resync only updates or removes existing tools. New tools added on the server do not appear in the resync dialog. Open the edit panel and select the new tools from the live tool list.
Server shows "Error" status The server cannot be contacted. Verify: 1. The server is running and accepting connections. 2. Any required authentication credentials are still valid. 3. The endpoint did not move to a new URL. If the issue persists, delete the server and add it again.
--- ## Next steps - [Build an MCP server](./build-an-mcp-server) — implementation, tool design, and operating practices - [Local tools](./local-tools) — built-in tools your agent can use without an external server - [Dialog Webhooks](./action-webhooks) — trigger custom logic during conversations - [Webhooks](./webhooks) — overview of all webhook types and how to configure them --- ## Message path '@site/src/components/Img'; To better understand how a message travels through Moveo to generate a reply, it's important to explore the full path it follows across the system. Each stage in this process plays a critical role in ensuring the conversation is handled accurately and efficiently. From the moment a user reaches out via an [integration](../integrations/overview.md), to the [rules](../environments/rules.md) that determine the next steps, and finally to the [AI Agent](./overview.md) that processes and replies to the message,each component contributes to a smooth and intelligent conversational experience. ## Sending a message A conversation typically begins when a user reaches out via an **integration**. In other words, the user initiates the conversation. The channel used by the user depends on the channels configured in your account. This same channel will be used to send the reply after the message is processed by the system. When a user sends a message, they are contacting an **integration** associated with a specific [**environment**](../environments/overview.md). This **integration** is responsible for receiving the message, processing it through the system, and sending a reply back to the user. ## Rules Once the message is received by the environment's **integration**, it is evaluated by the set of [**rules**](../environments/rules.md) configured in that environment. At this stage, the system checks which **actions** should be taken based on the [**conditions**](../environments/rules.md#apply-the-condition) defined in the rules. For example, one possible action is assigning an **AI Agent** to the conversation. Other available actions can be found [**here**](../environments/rules.md#then). The most common actions related to message handling are: - Assigning an [**AI Agent**](./overview.md). - Assigning a [**department**](../chat/departments.md). :::note A **human agent** can manually take over a conversation at any time, regardless of whether an **AI Agent** or **department** has been assigned. ::: It's possible to have multiple **rules** that assign an **AI Agent**. In such cases, the system will assign the **first AI Agent whose rule matches**. Assigning a **department** works differently. Unlike **AI Agent** assignment, **departments can be assigned even when an AI Agent is already handling the conversation**. A **human agent** will be assigned to the conversation if: - The **AI Agent** triggers a [**handover**](./operations/handover.md) to a **human agent**. - No matching **rule** assigns an **AI Agent**. ## AI Agent reply Once the message reaches the **AI Agent**, the system begins processing it through the following steps: 1. **Standalone**: A specialized **NLP model** enhances the original message by generating a standalone version. This version includes contextual information to clarify the user's intent. 2. **Intent**: After the standalone message is created, the system searches the configured [**intents**](./intents.md) and selects the one with the highest confidence. It then triggers the corresponding [**dialog**](./dialogs.md). If the system is not confident enough, the message is passed to the **response synthesizer**. 3. **Response synthesizer**: This model generates a reply based on the user's message and **conversation history**. ## Conversation start By default, the first user message goes through the same path as any other. If a node is selected under [Conversation start](./setup.md#conversation-start) in the AI Agent's settings, the first turn skips intent classification entirely: the conversation always begins at that node, regardless of what the first message says, and the greetings intent does not fire. ## Authentication [Authentication](../authentication/authentication-overview.md) is a subagent action placed inside a dialog node. When the conversation reaches that node, the **Authentication Agent** — an LLM-powered subagent — takes over the message path: each user message goes to it instead of intent classification until the flow ends. Once the user passes (or fails), the conversation continues from the configured success or failure node. When the node holding the Authentication action is also the [conversation start node](./setup.md#conversation-start) — the most common setup — the Authentication Agent owns the session from the first turn and generates the first message itself. --- ## Model strategy A **model strategy** defines which language models power your AI Agent. You build a **default** ordered chain of model steps, and you can optionally override it for individual channels. The AI Agent tries each step in the chain in order and falls back to the next one if a step is unavailable, so a single misconfigured or temporarily unreachable model never takes the agent offline. You configure the model strategy from your AI Agent's **Advanced** page, where it replaces the single language model selector. ## How the fallback chain works A chain is an ordered list of models that run in order — if one fails, the next takes over. When the AI Agent generates a response, it works through the chain from top to bottom: 1. It starts with the first model in the chain. 2. If that model is unavailable, it moves on to the next one. 3. It keeps going until a model succeeds. The first model is your primary choice, and the models below it act as **fallbacks**. Reorder them at any time to change which model the agent reaches for first. ## Model types When you add a model, the picker groups the available options into three types. You can mix different types across the models in the same chain. - **Moveo-built (free)** — Maestro, Moveo's own built-in model. This is the default option and carries no extra model cost. - **Moveo-hosted (paid)** — Third-party models hosted by Moveo (for example, a `gpt` model). Choose one of these when you want a specific model without managing your own provider credentials. - **Your language models** — Models from providers you have connected to your account (BYOLLM). To make your own models available here, connect them first by following the [Language Models](../platform/language-models.md) guide. Each step uses either a Moveo model or one of your own language models — not both. ## Default chain and per-channel overrides Your **default** chain applies to every channel. On top of it, you can configure overrides for specific channels when you want different models depending on where the conversation happens: - **Chat** - **Email** - **Voice** A channel without an override **inherits the default** chain. When you start overriding a channel, it is seeded from the current default so you can adjust from there, and you can **reset** a channel at any time to go back to inheriting the default. - A chain can have up to **3 models** (a primary model plus fallbacks). - **Voice supports a single model only** — it does not use fallbacks, because voice interactions are latency-sensitive. When Voice inherits the default, it uses only the default's first model. :::tip Use higher-quality models on channels where response quality matters most, and faster models on latency-sensitive channels such as Voice. ::: ## Reasoning effort Some models support a **reasoning effort** setting that controls how much the model deliberates before answering. Where a model supports it, you can set the reasoning effort per model — **None**, **Low**, **Medium**, or **High** — letting you balance response quality against speed and cost. If a model doesn't support reasoning, the setting is shown as unavailable. :::caution High reasoning effort on Voice typically pushes response latency past four seconds. For voice, prefer **Medium** or **Low**. ::: ## Edit the chain You can adjust a chain at any time: - **Add a fallback** and choose its model. - **Change** a model or its reasoning effort. - **Remove** a model you no longer need. - **Reorder** the fallbacks by dragging them — the new order takes effect immediately. ## Test a model Before committing a model to your chain, you can try it out. In the **Test AI Agent** panel, open the **Model** tab and choose a specific model and reasoning effort for the conversation. This overrides the configured chain for that test conversation only, so you can compare how different models respond without changing your live configuration. Use **Clear override** to go back to the configured chain. ## Empty and unavailable states - **Cleared models** — If you clear the models, all channels fall back to the default Maestro model. - **Unavailable model** — If a model in a chain has been deleted or is otherwise unavailable, it is marked as unavailable and the AI Agent skips it and continues to the next one. Review the chain and replace the affected model to restore your intended configuration. --- ## Conditions This document explains how conditions work within the [dialog](../dialogs.md) system. Conditions determine which actions to execute based on the current context, user input, and conversation history. The system supports two types of conditions: rule-based conditions using context variables and tags, and guideline-based conditions evaluated by AI models. ## Overview Conditions in the dialog system determine which actions to execute based on the **[current context](../context.md)**, **user input**, and **conversation history**. The system supports two types of conditions: - **Rule-based conditions**: Evaluated using deterministic logic with [context variables](../context.md#types-of-context-variables) and entities - **Guideline-based conditions**: Evaluated using AI models to understand natural language guidelines ## Condition evaluation flow When a [node](../dialogs.md#add-a-trigger) has conditions, the system evaluates them in the following order: 1. **Conditions are evaluated from left-to-right** in their original order as defined in the JSON 2. **"Else" conditions are automatically moved to the end** regardless of their position 3. **Only the first matching condition** (in left-to-right order) is selected and executed 4. **All other matching conditions are ignored** - only one condition's actions are executed ## Rule-based conditions Rule-based conditions use deterministic logic to evaluate context variables, entities, and user input. They are suitable for precise matching scenarios and support three match strategies: - **`all`** - All rules must be true for the condition to match - **`any`** - At least one rule must be true for the condition to match - **`else`** - Always matches when no other conditions match (fallback) ### Supported operators | Operator | Description | Example | | ------------------ | --------------------------------- | -------------------------------- | | `equal` | Exact value match | `$user.name == "John"` | | `not_equal` | Value does not match | `$user.verified != false` | | `greater` | Numeric greater than | `$seats > 2` | | `less` | Numeric less than | `$amount < 1000` | | `greater_or_equal` | Numeric greater than or equal | `$seats >= 1` | | `less_or_equal` | Numeric less than or equal | `$amount <= 500` | | `contain` | String contains substring | `$user.email contains "gmail"` | | `not_contain` | String does not contain substring | `$user.email not_contain "spam"` | | `exist` | Variable/entity exists | `$user.phone exists` | | `not_exist` | Variable/entity does not exist | `$payment_method not_exist` | ### Context variables Context variables are referenced using the $ prefix: ### Entity references Conditions with entities will match if the user input contains a matching entity. This can be either in the input that triggered the intent node, or if there is a question in a previous step of the same dialog that validates the entity. From user input are referenced using the `@` prefix. ## Guideline-based conditions Guideline-based conditions use AI models to evaluate natural language guidelines against the conversation context. They are flexible and can understand complex scenarios that are difficult to express with rigid rules. The **Condition Evaluator** is an AI model that: - Analyzes the dialog history, context variables, and user input - Returns matching conditions based on natural language understanding ### Used data The Condition Evaluator sends the following to the AI model: - **Context Variables**: All relevant context data (user info, session data, etc.) - **Live Instructions**: Special variables to dynamically change the AI Agent's behavior - **Dialog History**: Recent conversation turns - **User Question**: The current user input - **Guideline Conditions**: All available conditions as multiple choice options ## Mixed conditions Nodes can contain both rule-based and guideline-based conditions. The system evaluates them separately and combines the results. ### Use case: Loan request – Rule vs guideline conditions This example shows how to combine rule-based and guideline-based conditions to handle a user requesting a loan. 1. A **rule-based condition** checks if the variable `$loan_status` is equal to `"unpaid"`. If true, it blocks the loan request and shows a message asking the user to settle their debt first. 2. If the rule-based condition does not match, a **guideline-based condition** is evaluated next. It uses an AI model to detect if the user expresses willingness to repay the loan (e.g., "I can pay monthly"). If matched, the system allows the user to proceed. 3. If neither condition matches, an **else condition** acts as a fallback. It's used when the user doesn't show a clear intent to repay, and blocks the request. ## Condition priority The system will evaluate the conditions and execute the actions for the first condition that matches. When multiple conditions match: - **Left-to-right ordering** - Conditions are evaluated in the order they appear - **First match wins** - The first matching condition is executed ## Best practices ### Rule-based conditions - Use for precise, deterministic logic - Use `exist`/`not_exist` for optional data - Template values with `{{$variable}}` for dynamic comparisons ### Guideline-based conditions - Use for complex, nuanced scenarios - Write clear, specific guidelines - Avoid ambiguous language - Test with various conversation scenarios ### General - Always include an `else` condition as fallback - Order conditions by priority (most specific first) - Monitor condition evaluation performance and accuracy --- ## Jump to Events are a core function of Moveo. Unlike the classic tree-branch format, Moveo uses small tree-like dialogs and flows. This approach allows you to reuse any of your dialogs and trace back to an event trigger without having to build or write them again. **Jump** actions enable you to jump into different dialogs and serve as shortcuts to other points in the dialog. ## Use of a Jump action | Jump action | Event trigger | | :-----------------------------------------------------------: | :---------------------------------------------------------: | | | | In the above example, the jump action (left) triggers the dialog that has an event trigger as its parent node (right). --- ## Handover Moveo allows you to transfer the conversation to a live agent when necessary. This can be useful if the AI Agent does not understand the user's questions or if the user brings up a sensitive topic. To perform a handover, add the handover action in the dialog. All conversations where the AI Agent has left the chat and have not been assigned to an agent are available in the **Live chat** menu, under the **Unassigned** section. ## Zendesk department routing Choose which **Zendesk** department handles the conversation when the handover action is triggered. To do this, copy the department ID from the **Zendesk integration** settings and paste it into the `department_routing` field of the handover action in the dialog. | Zendesk Departments | Dialog | | ----------------------------------------------------------------------- | ----------------------------------------------------------------- | | | | ## Facebook Messenger handover Hand the conversation over to **Facebook Messenger** inbox by enabling the respective field in the dialog. ## Voice handover When configuring handover for voice agents on [Twilio Voice](../../integrations/twilio-voice.md) or [Telnyx Voice](../../integrations/telnyx-voice.md), the active call leg is transferred to a destination you specify in the handover action's settings. Provide either: - An **E.164 phone number** (e.g., `+12025551234`), or - A **SIP URI** (e.g., `sip:agent@example.com`) ### Transfer method Choose how the active call is transferred: - **Standard transfer (default)** — Moveo stays on the call and connects the caller to the agent. Recording continues. Works with a phone number or a SIP destination. - **SIP REFER** — Moveo hands the call to your phone system and drops off; recording continues on your side. Requires a **SIP destination**, and the incoming call must have **arrived over SIP** — a caller who reached you over a phone line cannot be transferred with SIP REFER. See [Voice call transfer](../../integrations/voice-call-transfer.md) for how each method works, a comparison, and when to use which. :::tip Pause before handover Add a [`Pause`](./pause.md) action of 1–2 seconds immediately before `Handover` so the caller hears the AI Agent's last sentence in full before the call is transferred. ::: ### Custom SIP headers When the destination is a **SIP URI**, you can attach custom SIP headers to the transfer through the **Attributes** field of the handover action. Each attribute is a key–value pair sent as a SIP header on the outgoing call leg, allowing the receiving system to route or label the call based on context from the AI Agent. Allowed header names: - Any `X-*` custom header, except headers starting with the prefix your provider reserves: `X-Twilio` on Twilio Voice and `X-Telnyx` on Telnyx Voice. - The following standard SIP headers: `User-to-User`, `Remote-Party-ID`, `P-Preferred-Identity`, `P-Called-Party-ID`. Headers outside the allow-list are silently dropped before the transfer. The combined size of all header names and values, after URL encoding, must not exceed 1024 characters. Attributes are ignored when the destination is a phone number — SIP headers only apply to SIP URI destinations. Example handover attributes for a SIP destination: | Key | Value | | --------------- | -------------------------------- | | `X-Customer-Id` | `12345` | | `User-to-User` | `priority=high;origin=ai-agent` | ### Limitations - **Web (browser-based) voice calls do not support handover.** The transfer is rejected by the provider because a browser-origin call has no caller ID to use on the transferred leg. Gate the `Handover` action in your workflow so it does not run on browser calls. - **Standard transfer keeps both legs billed.** The original inbound leg stays open while the new outbound leg to the destination is dialled, so both are billed. With **SIP REFER**, Moveo leaves the call path once the transfer succeeds and is not part of the onward call. - **Recording on a Standard transfer continues into the transferred call.** With **SIP REFER**, Moveo's recording stops at the handoff (the onward call is between the caller and your system). See [Voice call transfer](../../integrations/voice-call-transfer.md). - **No automatic retry.** If the destination is busy, does not answer, or rejects the transfer, the call drops. There is no built-in fallback — handle this in your brain workflow if needed. ### Zendesk voice handover setup An example of a successful implementation for voice handover is shown below, using Twilio Voice as the provider. It uses two separate numbers configured in Zendesk. The same pattern applies with [Telnyx Voice](../../integrations/telnyx-voice.md): forward the calls to the Telnyx number connected to the integration, and Moveo transfers the call to the agent number on handover. To configure these numbers in Zendesk, navigate to **Admin settings → Channels → Talk → Lines**. #### Number configuration Number 1: "Forwarding Number" (user entry point) Number 2: "Agent Number" (handover target) This is the primary number the user calls to initiate a conversation. It is configured in Zendesk with an overflow rule This rule immediately forwards all incoming calls to the Twilio number associated with the Moveo integration This is a separate Zendesk number. It is configured to route calls directly to a specific department or group of available agents #### Handover flow 1. **Call initiated**: The user dials the forwarding number (#1) 2. **Moveo connects**: The Zendesk overflow rule instantly forwards the call to the Moveo Twilio integration. The user begins their conversation with the Moveo voice assistant 3. **Handover triggered**: When a handover event is triggered (via dialog configuration), the Moveo platform executes the next step 4. **Twilio API transfer**: Moveo makes a Twilio API call on the active call leg. This API call instructs Twilio to dial and transfer the user to the agent number (#2) 5. **Call received in Zendesk**: - If agents are available: The call is routed to the configured department, and available agents are notified to pick up the call - If no agents are available: The call is dropped. However, Zendesk provides native options to manage this scenario, such as: - Sending the user to voicemail - Automatically creating a ticket for the abandoned call - Offering the user a callback when an agent becomes available --- ## Inactivity reminder The **Inactivity reminder** action sets a timer that triggers a reminder event node after a period of user inactivity. Use this to re-engage users who stop responding during a conversation. ## How it works When a user becomes inactive (stops sending messages), the inactivity timer counts down. After the specified duration, the system triggers a **reminder event node** that executes your configured flow. ## Configure an inactivity reminder 1. Open your dialog in the editor 2. Add an **Inactivity reminder** action to your flow 3. Set the timeout duration (in seconds or minutes) 4. Create a **reminder event node** in the dialog 5. Build the reminder flow under this node ## Common use cases ### Re-engage during checkout Send a reminder if a user pauses during payment: > "Still there? I noticed you paused during checkout. Need help completing your order?" ### Prompt for missing information Nudge users to provide required details: > "I'm waiting for your email address to continue. You can type it whenever you're ready." ### Offer assistance Check if the user needs help: > "It looks like you might be busy. Feel free to come back anytime, or let me know if you need help!" ## Canceling the timer The inactivity timer automatically cancels when: - The user sends a new message - The conversation ends or closes - A new inactivity reminder is set (replaces the previous one) ## Next steps - [Handover action](./handover.md) - Transfer conversations to human agents - [Tag action](./tag.md) - Add tags for conversation routing - [Questions](./questions.md) - Collect information from users --- ## Pause Predetermine how fast or slow Moveo responds to the user. Moveo's default response time is one second, but this can be changed to other values, such as three or eight seconds. This changes the elapsed time for the next message from Moveo, and the only visible change to the user is that the animated 💬 lasts longer. :::note Network issues or large files like videos can affect your AI Agent's elapsed time. ::: The pause is very useful not only if your previous message was a bit long for the user to have time to read it, but the pause also gives your AI Agent character and makes it more human. The pause has two fields: - **`duration`**: The pause duration (in seconds). - **`show_typing`**: Show a typing indicator during the pause. A good example of a pause implementation is shown below. The AI Agent sends two large texts to the user. Without the pause, the texts come one immediately after another, leaving no time for the user to read them and at the same time flooding their screen. ## Voice integrations For voice integrations such as [Twilio Voice](../../integrations/twilio-voice.md) and [Telnyx Voice](../../integrations/telnyx-voice.md), `Pause` has a different role. It delays the next action in the response, but it does **not** prevent the caller from interrupting the AI Agent during text-to-speech playback. The recommended use of `Pause` on voice is **immediately before** a [`Resolve`](./resolve.md) or [`Handover`](./handover.md) action, so the AI Agent's last sentence is heard in full before the call ends or transfers: ``` [ Text: "Transferring you to an agent now." ] [ Pause: 1s ] [ Handover ] ``` Guidelines: - **1 second** is enough for most desktop and VoIP callers. - **2 seconds** is safer for mobile callers on cellular networks with higher jitter. :::note Why the pause is needed The telephony provider signals "audio dispatched" before the caller has actually finished hearing it. There can be 200–300 ms of audio still in flight through the carrier and the caller's device when the next action would otherwise fire, which clips the tail of the last sentence. The pause gives that audio time to play out. ::: --- ## Questions Questions enable your AI Agent to collect information from users through conversational Q&A. The system intelligently extracts answers from context when possible, reducing repetitive questions and creating a natural flow. Add questions below any [text](../triggers/text.md) or [event](../triggers/event.md) trigger. Your AI Agent can request single or multiple pieces of information within a dialog. ## Understanding context variables When your AI Agent asks a question, the user's answer is saved to a [context variable](../context.md) that persists throughout the conversation session. **Save As field:** The **Save As** field defines the context variable name where the answer is stored. You can use simple names like `email` or `phone`, or use dot notation (`.`) to organize variables in JSON structure: `user.email`, `booking.date`, `payment.amount`. :::note If a context variable is already filled, the AI Agent may skip the question automatically unless configured otherwise. ::: **Example question configuration:** **User message example:** ## How auto-fill works Auto-fill attempts to extract answers before prompting the user. The ability to extract from conversation history depends critically on whether you configure a validation guideline. ### With validation guideline (LLM-based) When a validation guideline is configured, the AI can extract information from **anywhere in the conversation history** only if is **not** a mandatory question: - **Analyzes full conversation**: Reviews all previous messages, not just the current one - **Understands context**: Can extract information mentioned several messages ago - **Intelligent inference**: Understands natural language like "tomorrow", "my email is...", etc. - **Context variable access**: Can use previously stored context variables **Example scenario (WITH guideline):** ``` Message 1 User: "Hi, my email is sarah@example.com" Agent: "Nice to meet you! How can I help?" Message 2 User: "I'd like to schedule a demo" Message 3 User: "What times are available?" Agent: "We have slots at 2pm and 4pm" Message 4 User: "I'll take the 2pm slot" [Question node triggers with validation guideline: "Extract user's email"] Agent: "Perfect! Demo booked for 2pm. Confirmation sent to sarah@example.com" ``` ☝️ The email was mentioned in **Message 1**, but the question triggered in **Message 4**. With a validation guideline, the AI found it in the history. :::warning If the question was a mandatory one, the user would be prompted to answer it. Even if they already mentioned it earlier in the conversation. ::: ### Without validation guideline (rule-based) Without a validation guideline, auto-fill is **limited to the current user message only**: - **Context variable access**: If the context variable already has a value, it will skip the question. (Only if the question is not mandatory) - **No conversation history**: Cannot look at previous messages - **No natural language understanding**: Requires exact format (no "tomorrow", just "2025-03-15") - **Current message only**: If the entity isn't in the current message, auto-fill fails The variable type, **Same scenario (WITHOUT guideline):** ``` Message 1 User: "Hi, I'm Sarah and my email is sarah@example.com" Agent: "Nice to meet you, Sarah! How can I help?" Message 2 User: "I'd like to schedule a demo" Message 3 User: "What times are available?" Agent: "We have slots at 2pm and 4pm" Message 4 User: "I'll take the 2pm slot" [Question node triggers WITHOUT validation guideline] Agent: "What's your email address?" ← Auto-fill FAILED - email not in current message - User is prompted ``` ☝️ Without a guideline, the system only checks **Message 4** for an email entity. Since it's not there, auto-fill fails and the user gets prompted. :::tip **For intelligent auto-fill from conversation history, always configure a validation guideline.** Without it, questions can only auto-fill from entities detected in the current user message, not from earlier context. ::: **When auto-fill is skipped:** - The question is marked as **Mandatory** (see below) - No relevant data exists (in history with guideline, or current message without guideline) - The system requires explicit user confirmation ## Ask only Select **ask only** for simple data extraction without validation constraints. **Required fields:** - **Ask**: The question to ask the user. - **Save input in variable**: The context variable key where the answer is saved. ## Check and ask Select **Check and ask** to add validation rules to your questions. **Required fields:** - **Ask**: The question to ask. Optionally set a **reprompt** message if the user's input fails validation. - **Validation**: Choose one of the following validation types: - [Entity](../entities): Checks for a specific entity in the user's message. - **Input type:** Validates the response format: - Text - Email - Number - Integer - Phone - URL - Date - Time - Datetime - Currency - Percentage - Boolean Each validation type automatically validates format and normalizes values to a standard format. This ensures consistent data storage, enables reliable integrations with external systems, and simplifies downstream processing in your workflows. **Why use validation types:** - **Email**: Ensures valid format for email delivery systems, normalizes to lowercase for database consistency - **Phone**: Validates international format, removes formatting for SMS/call integrations - **URL**: Extracts clean URLs for link processing, ensures valid format for web requests - **Date/Time/Datetime**: Standardizes to ISO formats for calendar integrations, scheduling systems, and database storage - **Number/Integer**: Ensures numeric calculations work correctly, prevents type errors in APIs - **Currency**: Standardizes monetary values for payment processing and financial calculations - **Percentage**: Converts to decimal format (0.0-1.0) for mathematical operations - **Boolean**: Normalizes to true/false for conditional logic and integrations - **Text**: Cleans whitespace for consistent display and storage The validation behavior depends on whether you configure a validation guideline: **With validation guideline (LLM-based):** The AI understands natural language and converts it to standard format before validation. | Validation Type | Input Example | Normalized Output | Purpose | |-----------------|---------------|-------------------|---------| | **Email** | "Steve@Gmail.com" | "steve@gmail.com" | Lowercase for consistency | | **Phone** | "+1 (415)-432-5355" | "+14154325355" | Remove formatting for SMS APIs | | **URL** | "Visit https://moveo.ai now" | "https://moveo.ai" | Extract URL from text | | **Date** | "03/15/2025" or "tomorrow" | "2025-03-15" | ISO format for databases | | **Time** | "2:30 PM" | "14:30:00" | 24-hour format for scheduling | | **Datetime** | "March 15, 2025 at 2:30 PM" | "2025-03-15T14:30:00" | ISO 8601 for calendar APIs | | **Number** | "one and a half" or "1.5" | 1.5 | Float for calculations | | **Integer** | "twenty" or "20" | 20 | Integer for counting | | **Currency** | "100 dollars" | "USD 100.0" | Standard format for payments | | **Percentage** | "20%" | 0.2 | Decimal fraction (0.0-1.0) | | **Boolean** | "yes" / "true" / "1" | true | True/false for logic | | **Text** | " Hello World " | "Hello World" | Trim whitespace | **Without validation guideline (rule-based):** Only accepts pre-formatted inputs. Natural language requires validation guidelines. | Validation Type | Accepted Input | Normalized Output | Rejected Input | |-----------------|----------------|-------------------|----------------| | **Email** | "steve@gmail.com" | "steve@gmail.com" (lowercase) | Invalid email format | | **Phone** | "+1 (415)-432-5355" | "+14154325355" | Invalid phone format | | **URL** | "https://moveo.ai" | "https://moveo.ai" | Invalid URL format | | **Date** | "03/15/2025" or "2025-03-15" | "2025-03-15" | ❌ "tomorrow" | | **Time** | "2:30 PM" or "14:30" | "14:30:00" | Invalid time format | | **Datetime** | "2025-03-15T14:30:00" | "2025-03-15T14:30:00" | Invalid datetime format | | **Number** | "1.5" or "1,5" | 1.5 | ❌ "one and a half" | | **Integer** | "20" | 20 | ❌ "twenty" | | **Currency** | "USD 100.0" | "USD 100.0" | ❌ "100 dollars" | | **Percentage** | 0.2 or "0.2" | 0.2 | ❌ "20%" | | **Boolean** | "yes" / "true" / "1" | true | "maybe" | | **Text** | " Hello World " | "Hello World" | (accepts any text) | :::warning Natural language inputs like "tomorrow", "twenty", or "100 dollars" **require a validation guideline**. Without a guideline, questions only accept pre-formatted values like "2025-03-15", "20", or "USD 100.0". ::: - **Guideline** (Optional): Custom validation instructions in natural language. An LLM validates the user's response using this guideline. :::note The guideline option is not available when using entity validation. ::: **Customizing clarification messages:** When a user provides invalid or ambiguous input, the AI Agent generates a clarification message explaining why the input was rejected. You can influence this message through the validation guideline. For example, if your guideline includes instructions like "Must be a future date within 90 days. If invalid, remind the user about the 90-day limit", the agent will incorporate this context into its clarification responses. - **Save input in variable**: The context variable key where the validated answer is saved. :::note Entity validation creates a second variable with the suffix `_value` added to your defined key. This variable stores the entity's actual value. ::: ## Mandatory questions The **Mandatory** checkbox controls whether auto-fill is attempted and how the agent handles information collection. **When mandatory is OFF (default):** - The system tries auto-fill first using conversation context - Only prompts the user if auto-fill fails - May move forward if the user doesn't provide valid input or changes topic. **When mandatory is ON:** - Skips auto-fill entirely (see [data access](#data-access-during-question-processing) for details) - Always asks the user explicitly, even if the answer exists in context - Continues asking until a valid answer is provided **Use mandatory questions for:** - Sensitive information requiring explicit confirmation (payment details, credit card numbers) - Legal or compliance requirements (explicit consent, terms acceptance) - Situations where inference could be incorrect (e.g., "Which email should we use?" when multiple exist) - Critical workflow steps that cannot be skipped :::tip Use mandatory questions sparingly. Auto-fill provides better user experience by reducing repetitive questions. ::: ## Data access during question processing The AI Agent has access to different information depending on the question type: **Regular questions:** - Full conversation history (all previous messages) - All context variables from earlier in the conversation - Current user message - Session metadata (date, time, language) **Mandatory questions:** - Limited context (only recent conversation for continuity) - Current user message - No access to context variables for auto-fill This design ensures mandatory questions require explicit user input rather than inferred answers from context. ## How the agent responds to user input When processing a question, the AI Agent analyzes the user's response and classifies it into response types that control the conversation flow. | Response Type | Available For | What It Means | Agent Behavior | Example | |--------------|---------------|----------------|----------------|---------| | **SUCCESS** | All questions | Answer successfully extracted and validated | Saves the value to the context variable and continues | User: "john@example.com" → Variable filled, workflow continues | | **CLARIFICATION** | Regular questions | Answer is ambiguous or incomplete | Generates a clarification message explaining the issue | User: "50 euros" when asking for dollars → Agent: "I need the amount in dollars, not euros" | | **DETAILS_REQUESTED** | Regular questions | User asks for more information before answering | Provides context then re-asks the question | User: "Why do you need my email?" → Agent explains, then asks again | | **TOPIC_CHANGE** | Regular questions | User changed the subject | Handles topic change, may return to question later | User: "Actually, I want to cancel" → Agent pivots to cancellation | | **MEMORY_UPDATE** | Regular questions | User is correcting a previous answer | Updates the earlier context variable | User: "Actually my email is jane@example.com, not john@example.com" | | **FAILURE** | All questions | Cannot extract valid answer | States that information is needed to proceed | User provides invalid input → Agent explains requirement and re-asks | **Key behaviors:** - **Regular questions**: Support all response types including topic changes and memory updates - **Mandatory questions**: Only support SUCCESS and FAILURE response types—the agent always re-asks until valid input is provided - **CLARIFICATION vs FAILURE**: For regular questions, CLARIFICATION generates helpful follow-up messages; for mandatory questions, FAILURE is used instead - **MEMORY_UPDATE**: Users can naturally correct mistakes without breaking conversational flow (regular questions only) - **TOPIC_CHANGE**: Prevents forcing answers when users have urgent needs (regular questions only) :::note Conversation Tip Design question prompts to handle clarification naturally. If asking for a date, mention the expected format: "When would you like to schedule? (e.g., March 15 or next Monday)" ::: ## Validation guideline best practices Keep validation guidelines short and specific—the AI uses these to validate user input. Focus on constraints and format requirements. **Example 1: Date validation** ``` Validation Type: Date Validation Guideline: "Must be a future date within the next 90 days" ``` *Why it works:* Clear constraint, specific timeframe, easy to validate. **Example 2: Phone validation** ``` Validation Type: Phone Validation Guideline: "US phone numbers only, must include area code" ``` *Why it works:* Specifies format and regional requirement concisely. **Example 3: Text validation** ``` Validation Type: Text Validation Guideline: "Full legal name as it appears on government ID" ``` *Why it works:* Sets clear expectation for format and formality level. :::note Keep validation guidelines under 15 words when possible. Focus on what makes an answer valid rather than lengthy explanations. ::: ## Questions in your workflow **Integration tips:** - Questions execute in sequence—the agent asks them one at a time - If validation fails, the agent automatically uses the "Reprompt" message - Slot values can be used in downstream nodes with `{{"{{$variable_name}}"}}` syntax - Context variables persist throughout the session—no need to ask twice - For optional information, consider using conditional logic instead of questions - The agent naturally handles topic changes and clarifications—design for conversational flow, not rigid forms --- ## Replay ## Overview The **Replay** action allows you to send a message on behalf of the user within a conversation. You can choose to replay the user's last message or define a custom one. This message is visible only in the conversation logs and the live chat (if applicable). ## Use Cases ### Routing Conversations Since replayed messages are treated as user messages, you can leverage this action to match conditions in [rules](../../environments/rules.md). This allows you to route the conversation to a different AI Agent, escalate it to a human agent, or trigger another action within the rules system. See [this guide](../../environments/rules-route-agent.md) for details on routing conversations. ### Triggering a Synthetic Response If the replayed message (whether the last user message or a custom one) does not match any intent, but your AI Agent has **Knowledge** enabled, a synthetic response will be triggered. This ensures that the user receives an appropriate answer even if their original message is not explicitly covered in the AI’s dialog setup. --- ## Reset Your AI Agent remembers users' responses but can also reset any value in a flow when needed. This means that if you were going to ask for the user's phone number, but they have already provided it, your AI Agent won't ask for it again. A reset removes either all the [context variables](../context) or specific ones. For example, if a user types something incorrectly by mistake, give them the opportunity to correct it. Use a reset to remove the variable where the user stored their information, then prompt them to enter it again. Choose between resetting **all** or **specific** variables. 1. When you select **All variables**, all the [variables in the dialog](../context) are reset. User, bundle variables, and tags are not reset. 2. When you select **Specific variables**, you must specify all the variables you want to reset. With this option, you can also reset user variables, except for `$user.user_id`. :::note System variables are not eligible for reset. ::: --- ## Resolve Close a conversation automatically through the **resolve** action inside the AI Agent. When the user triggers a resolve action, the AI Agent performs the following actions: 1. The assistant closes the conversation, always respecting the **Keep alive** setting at the environment level. This setting determines the duration, in seconds, after which resolved conversations expire and any additional user messages create a new conversation. 2. The assistant displays the post-conversation survey if the user and the assistant have exchanged more than three messages. 3. If you are using Zendesk Sunshine Conversations, the assistant passes control to the next integration in the switchboard without showing a survey. ## Voice integrations For voice integrations such as [Twilio Voice](../../integrations/twilio-voice.md) and [Telnyx Voice](../../integrations/telnyx-voice.md), `resolve` hangs up the call. The platform ends the call within a couple of seconds, whatever the environment's [keep alive](../../guides/timeouts.md#keep-alive) value. Add a [`Pause`](./pause.md) action of **1–2 seconds** immediately before `Resolve`, so the bot's final sentence is fully heard by the caller before the line drops. ``` [ Text: "Thanks for calling. Goodbye." ] [ Pause: 1s ] [ Resolve ] ``` --- ## Set variables The **Set variables** action creates or modifies variables during a conversation. Use variables to store information, track state, and personalize responses. ## How to set a variable 1. Open your dialog in the editor 2. Add a **Set variables** action to your flow 3. Enter the variable name (key) 4. Set the value (text, number, or reference to another variable) 5. Save your changes ## Variable types | Type | Example | Use case | |------|---------|----------| | Text | `"premium"` | User preferences, status flags | | Number | `42` | Counters, quantities, scores | | Boolean | `true` | Feature flags, confirmation states | | Reference | `{{$user.email}}` | Copy value from another variable | ## Common use cases ### Track conversation state ``` variable: $step_completed value: "payment" ``` ### Store user preferences ``` variable: $preferred_language value: "Spanish" ``` ### Copy from user context ``` variable: $customer_email value: {{$user.email}} ``` ## Best practices - **Use descriptive names** - Choose clear names like `order_total` instead of `val1` - **Keep scope in mind** - Variables persist for the entire conversation - **Initialize values** - Set default values to avoid undefined references - **Document your variables** - Maintain a list of variables used in your dialogs ## Accessing variables After setting a variable, access it in: - **Text responses**: `Hello, {{$customer_name}}!` - **Conditions**: Check if `$customer_tier` equals `"premium"` - **Webhooks**: Include variables in request payloads - **URL responses**: `https://example.com?user={{$user.user_id}}` ## Next steps - [Context variables](../context.md) - Learn about the context system - [Questions](./questions.md) - Collect and store user input - [Conditions](./conditions.md) - Use variables in conditional logic --- ## Tag Add tags to the conversation to track when a certain dialog has been triggered. This feature is useful for obtaining helpful and insightful [analytics](../../analytics/overview.md). All the tags of a conversation are stored in a context variable called `$tags`. The tag action supports the following operations: 1. **Add tags** (`add`): Add new tags to the conversation (default). 2. **Remove tags** (`remove`): Remove one or more existing tags from the conversation. 3. **Remove all tags** (`clear`): Clear all tags from the conversation. --- ## AI Agents AI Agents are the intelligent core of Moveo's platform, designed to understand and respond to user queries using modern AI technologies. They leverage knowledge-based systems (RAG - Retrieval Augmented Generation) combined with customizable guidelines to deliver accurate, contextual responses to your users. ## Knowledge-first approach Moveo AI Agents primarily operate using a **knowledge-based system** that combines two key components: ### 1. Knowledge (What your agent knows) The [knowledge base](../knowledge-base/overview.md) contains curated sets of information from various sources: - **FAQs** - Direct answers to common questions - **Documents** - PDFs, Word docs, and other files - **Websites** - Crawled web content - **Knowledge bases** - Structured information repositories Your AI Agent uses this knowledge to understand context and find relevant information to answer user queries using RAG (Retrieval Augmented Generation) technology. ### 2. Guidelines (How your agent responds) [Guidelines](../ai-agents/knowledge.md#guidelines-prompting) are instructions that shape how your AI Agent communicates and behaves. They include: - **Custom guidelines** - Specific instructions for your use case - **Product information** - Details about your offerings - **Response style** - Tone, format, and personality - **Handling objections** - Strategies for common concerns - **Business rules** - Compliance and operational requirements Think of guidelines as prompting instructions that teach your AI Agent not just what to say, but how to say it in alignment with your brand and business needs. ## How AI Agents respond When a user sends a message, your AI Agent: 1. **Searches its knowledge** - Finds relevant information from the connected knowledge base 2. **Applies guidelines** - Uses your custom instructions to shape the response 3. **Generates an answer** - Creates a contextual, accurate response using the configured LLM This knowledge-first approach means you can build powerful AI Agents by: - Uploading your content (FAQs, documentation, product info) - Writing clear guidelines - Testing and refining No coding or complex workflows required for most use cases. ## When to use Dialogs (Advanced) While knowledge and guidelines handle most conversational needs, [Dialogs](./dialogs.md) are available for specific automation requirements: - **API integrations** - Connect to external services via [webhooks](./responses/webhook.md) - **Multi-step workflows** - Guide users through complex processes - **Conditional logic** - Create branching paths based on user input - **Task automation** - Execute specific actions (send emails, update databases) Dialogs are optional and complement the knowledge-based approach when you need deterministic, structured workflows. ## AI Agent types AI Agents can be of different types, each optimized for a specific use case with predefined guideline fields tailored to that purpose. :::tip Complete the predefined guidelines to get the best out of your AI Agent. ::: ### Seller agents These agent types share the same guideline fields: **Goal**, **Overview**, **Features**, **Loyalty**, **Objections**, and **Custom instructions**. - **Early Engagement** Build meaningful relationships with potential customers by understanding their needs and guiding them toward the right solutions. Engage customers early to answer questions and offer information before they commit. - **Product Adoption** Guide customers through a seamless onboarding experience that helps them start using the product effectively and confidently. Provide clear steps, celebrate milestones, and share best practices. - **Upsell** Help customers discover premium features and upgrades that enhance their experience. Focus on identifying moments when an upgrade could genuinely improve the user's results. ### Specialized agents These agent types have guideline fields optimized for their specific use case. - **Customer Support** Provide customer support, addressing inquiries, troubleshooting, and FAQs. Uses **Objections** and **Custom instructions** fields. - **Debt Collection** Help manage overdue payments with flexible options and professional communication. Uses **Goal**, **Objections**, and **Custom instructions** fields. ## Next steps - [Knowledge agent quick start](./quickstart.md) - Build your first AI agent in 10 minutes - [Knowledge & Guidelines](./knowledge.md) - Configure what your agent knows and how it responds - [Setup](./setup.md) - Fine-tune tone, response length, and reminders - [Dialogs](./dialogs.md) - Create advanced workflows with conditional logic --- ## Knowledge agent quick start Build your first knowledge-based AI agent in under 10 minutes. This guide walks you through creating an agent that can answer questions using your content - no coding or complex workflows required. ## What you'll build A fully functional AI agent that: - Answers questions using your uploaded content - Responds in your brand's voice and style - Handles common customer queries automatically - Can be deployed to multiple channels ## Step 1: Create your AI Agent 1. Navigate to **AI Agents** 2. Click **+ Create AI Agent** 3. Choose a descriptive name (e.g., "Customer Support Agent") 4. Select your agent type based on your use case: - **Customer Support** - For FAQs, troubleshooting, and help content - **Product Adoption** - For onboarding and feature guidance - **Early Engagement** - For building relationships and pre-purchase conversations - **Upsell** - For promoting premium features and upgrades - **Debt Collection** - For managing overdue payments and settlements 5. Select a language for your AI Agent 6. Click **Create** :::tip The agent type provides pre-configured guidelines optimized for specific use cases. You can customize these later. ::: ## Step 2: Create and populate your knowledge base The knowledge base is your agent's information source. Create one with your content: ### Create the knowledge base 1. Navigate to **Knowledge** 2. Click **+ Create** 3. Name your knowledge base (e.g., "Product Documentation") 4. Select the primary language 5. Click **Create** ### Add your content Perfect for FAQs and common questions: 1. Click **+ Add FAQ** 2. Enter the question and answer 3. Click **Save** Example: ``` Question: What are your business hours? Answer: We're open Monday-Friday 9AM-6PM EST. For urgent issues, our emergency support is available 24/7. ``` Upload existing documentation: 1. Click **Upload Documents** 2. Select your files (PDF, DOCX, TXT) 3. Click **Upload** Supported formats: - PDF files - Word documents (.docx) - Text files (.txt) - Markdown files (.md) Import content from your website: 1. Click **Add Website** 2. Enter your website URL 3. Configure crawl settings (optional) 4. Click **Start Crawling** The system will automatically extract and index your web content. :::note Knowledge bases automatically chunk content into fragments for optimal retrieval. Each fragment is approximately 400 words. ::: ## Step 3: Connect knowledge base to your agent 1. Open your AI Agent 2. Navigate to the **Guidelines** tab 3. In the **Knowledge base** section at the top of the page, select your knowledge base from the dropdown 4. Click **Connect** Your agent now has access to all the content in your knowledge base. :::warning If the Knowledge Base is not visible, make sure it has the **same** language as your AI Agent. ::: ## Step 4: Configure guidelines Guidelines shape how your agent communicates. Based on your agent type, you'll see predefined guideline fields optimized for that use case. 1. In your AI Agent's **Guidelines** tab, fill out the predefined fields (Goal, Overview, Objections, etc.) 2. For more specific topics, write them in **Custom instructions** or click the **+** button to add a new guideline in this section. :::tip Start with the **Goal** field to establish your agent's primary objective, then fill out the other fields to provide supporting context. ::: For detailed guidance on writing effective guidelines, see [Knowledge & Guidelines](./knowledge.md#guidelines). ## Step 5: Test your agent 1. Click the **Test** button in the top-right corner 2. The test console opens on the right side 3. Type a question that your content covers 4. Press Enter to see your agent's response ### Testing tips Try different types of questions: - Direct questions from your FAQs - Questions requiring information synthesis - Edge cases and unclear queries - Questions outside your content scope :::tip If responses aren't optimal, refine your guidelines or add more specific content to your knowledge base. ::: ## Step 6: Configure your language model (Optional) For advanced users who want to use a specific LLM: 1. Navigate to your AI Agent's **Advanced** tab 2. Select your preferred **LLM Provider** (Moveo.AI, OpenAI, Anthropic, etc.) 3. Choose the specific **Model** (e.g., GPT-4, Claude 3.5) 4. Save your changes The default Moveo.AI models work great for most use cases. ## Next steps Your knowledge agent is ready! Here's what you can do next: ### Deploy to channels - [Web channel](../integrations/web/getting-started.md) - Add to your website - [WhatsApp](../integrations/whatsapp.md) - Connect to WhatsApp Business - [Facebook Messenger](../integrations/facebook-messenger.md) - Integrate with Facebook ### Enhance your agent - [Add more content](../knowledge-base/overview.md) - Expand your knowledge base - [Live instructions](./build-a-webhook.md#use-case-live-instructions) - Dynamic user data ### Monitor performance - [Analytics](../analytics/overview.md) - Track agent effectiveness - [Insights](../analytics/insights.md) - AI-powered improvement suggestions ## Common questions **Q: How much content do I need?** A: Start with 20-30 FAQs or 10-15 pages of documentation. You can always add more as you learn what users ask. **Q: Can I use multiple knowledge bases?** A: Yes! Connect multiple knowledge bases to cover different knowledge domains. **Q: How do I handle questions the agent can't answer?** A: Add a fallback guideline like "If you don't know the answer, say: 'I don't have that information, but I can connect you with our support team.'" **Q: When should I use dialogs instead?** A: Use dialogs only when you need specific workflows like API integrations, multi-step forms, or conditional logic. Most conversational needs are handled by knowledge + guidelines. ## Troubleshooting If your agent isn't responding as expected: 1. **Check knowledge base content** - Ensure relevant information exists 2. **Review guidelines** - Make instructions clear and specific 3. **Test variations** - Try different phrasings of questions 4. **Check language settings** - Ensure agent and knowledge base languages match 5. **Review the Insights tab** - Get AI-powered suggestions for improvements --- ## AI Response An **AI Response** lets the agent generate a reply on demand at a specific step in a dialog, instead of sending a fixed, scripted message. When the conversation reaches the step, the agent writes a tailored response that fits the user and the current context. ## When to use it Reach for an AI Response instead of a [text response](./text.md) when a single, fixed message isn't enough: - The reply needs to adapt to what the user said or to their context. - The answer depends on information the agent looks up at that moment, such as content from your [knowledge base](../../knowledge-base/overview.md) or data from a connected tool. - You want the agent to handle a step in its own words while still following your guidance. The AI Response always respects your agent's overall instructions. You can optionally add step-specific guidance that applies only to this step. ## AI Response guidelines The only setting is an optional **AI Response Guidelines** field — a rich text editor where you guide how the agent should respond when this step runs. Within the editor you can: - Type `@` to reference the agent's tools and point it at a specific tool for this step. - Type a dollar sign (\$) to reference [context variables](../context.md) and personalize the response. If you leave the field empty, the agent still replies — grounded in its general instructions and knowledge — without any step-specific guidance. :::tip Keep guidelines focused on this step only. Broad, agent-wide guidance belongs in your agent's general instructions, not in every AI Response step. ::: ## Using tools and knowledge While generating the reply, the agent can search your [knowledge base](../../knowledge-base/overview.md), call connected [MCP tools](../mcp-servers.md), and trigger a workflow — all as part of the same response. This lets a single step both fetch the information it needs and answer with it. The response is produced by the model configured in your [model strategy](../model-strategy.md). --- ## Carousel response The carousel is an ideal response format when you need to display multiple items in one view. Carousels can contain up to six cards, each consisting of the following fields: - **`title`**: The title of the card. - **`subtitle`**: A short description or subtitle for the card. - **`media`**: An image or video to display in the carousel. It includes the following sub-fields: - `type`: Specifies whether the media is an `image` or `video`. - `url`: The URL of the media. - **`default_action`** _(Optional)_: An action triggered when the media is clicked, with the following sub-fields: - `type`: Can be `postback`, `url`, `webview`, or `phone`. - `value`: The value associated with the action type. - **`buttons`**: Each card must have at least one and up to three buttons, formatted as follows: - `label`: The text displayed on the button. - `type`: Can be `postback`, `url`, `webview`, or `phone`. - `value`: The value associated with the button type. :::note Postback responses provide the same result as [options](./text#options). ::: --- ## Email Send email notifications to keep your team updated with the latest information or events within your AI Agent, or send a confirmation to your customers—all with an email response. ## Fields Each email response contains the following four fields: - **From**: The sender of the email, fixed to no-reply@moveo.ai - **To**: The (one or more) receivers of the email, which you can set to either an email address or a variable. - **Subject**: The subject of the email, which also appears in the dialog. - **Body**: The contents of the email. The body field supports **markdown** formatting for rich text emails, using HTML tags might **not** work as expected. ```markdown Hi {{first_name}}, Your order **#{{order_number}}** has been shipped! 📦 You can track it here: [Track Order]({{tracking_url}}) Thanks for shopping with us, **The {{company_name}} Team** ``` :::tip To make the message more personalized for the user, refer to [context variables](../context.md). ::: ## Implementation The following image shows an example of an email response implementation. ## Troubleshooting - **Line breaks are not working**: Use `\n` to create line breaks. - **Not receiving emails**: Contact us at [support@moveo.ai](mailto:support@moveo.ai). --- ## File response Your end user can download a file with the file response. Either add the URL of the file or upload it directly. The file response contains the following fields: - **`url`**: The URL of the file. Note that when you upload a file, the `url` automatically fills with the file's URL. - **`name`**: The name you want to show the user. --- ## Google Sheet Keep records of conversation data, generate reports, make notes, and perform any other functionality served by a spreadsheet with the Google Sheet add-on inside Moveo. ## Choose a spreadsheet 1. Open your Google Sheet and click on the icon on the top right corner of your screen. 2. Add Moveo's service account `moveosheets@fiery-protocol-326906.iam.gserviceaccount.com` with **editor** access to the list. ## Dialog The Google Sheet action contains the following three fields: - `spreadsheet_id`: The ID of the Google Sheet, which you can find in the URL of the form `https://docs.google.com/spreadsheets/d/{SPREADSHEET_ID}/edit#gid=0`. - `sheet_id`: The name of the sheet in which you want the AI agent to write. - `inputs`: A list of the context variables that the assistant appends on the first empty row of the sheet. You can find an example below: --- ## Image response Instead of text, you can respond with an image. Either add the URL of the image or upload it directly. Each image response contains two fields: 1. **`url`**: The URL of the image. Note that when you upload an image, the `url` automatically fills with the image's URL. 2. **`name`**: The name you give to the image, which is only shown when the image cannot load. --- ## Responses Each time the user sends a message, the AI Agent activates one or more [triggers](../triggers/overview.md). It can then respond in a variety of forms. There are different kinds of responses such as plain text, links, menus, and options. You can add one or more responses below a [trigger](../triggers/overview.md) by dragging and dropping them. ## Types of actions Moveo.AI supports the following responses, operations, and extensions: ### Responses | Response | Description | | :------------------------------ | :---------------------------------- | | [Text](./text.md) | Reply with a text | | [AI Response](./ai-response.md) | Generate a tailored reply on demand | | [Image](./image.md) | Send an image | | [Carousel](./carousel.md) | Reply with a carousel | | [Webview](./webview.md) | Display a webview | | [Video](./video.md) | Send a video | | [File](./file.md) | Send a file | | [Survey](./survey.md) | Display a survey | | [URL](./url.md) | Send a URL | ### Operations | Operation | Description | | :---------------------------------------------- | :------------------------------------------------ | | [Question](../operations/questions.md) | Ask a question to the user | | [Jump to](../operations/event.md) | Trigger a specific node | | [Condition](../operations/conditions.md) | Create a logic tree | | [Handover](../operations/handover.md) | Transfer the conversation to an agent | | [Tag](../operations/tag.md) | Label the conversation with a tag | | [Pause](../operations/pause.md) | Pause the conversation | | [Set variables](../operations/set-variables.md) | Set a variable equal to a value | | [Reset variables](../operations/reset.md) | Reset specific or all context variables | | [Resolve](../operations/resolve.md) | Close the conversation | | [Replay](../operations/replay.md) | Transfer the conversation to a different AI Agent | ### Extensions | Extension | Description | | :------------------------------- | :--------------------------- | | [Webhook](./webhook.md) | Call a predefined webhook | | [Google Sheet](./googlesheet.md) | Store data in a Google Sheet | | [Email](./email.md) | Send an email | ## Add a response Add one or more actions below a [trigger](../triggers/overview.md) by using Moveo's drag-and-drop functionality. --- ## Passthrough :::note Enterprise only This feature is only available for accounts on the Enterprise plan. Want access? [Contact our sales team to learn more](https://moveo.ai/book-a-demo). ::: The passthrough feature allows you to send custom payloads directly to messaging channels without Moveo's standard message processing. This extends the capabilities of your [AI Agent](../overview.md) by leveraging platform-specific features to their full potential. ## Overview When you need to utilize platform-specific features or send specialized message formats, the passthrough feature enables you to bypass Moveo's standard message processing and send payloads directly to the channel. ## Supported channels The passthrough feature is currently available for the following messaging channels: - Viber - WhatsApp - Sunshine Conversations ## Schema To use the passthrough feature, add a `passthrough` field to your text or carousel response. The field contains a list of objects with the following structure: | Field | Type | Description | | ------- | ------ | -------------------------------------------------------------------------------------------- | | channel | string | The target messaging channel (`"whatsapp"`, `"sunco"` (Sunshine Conversations) or `"viber"`) | | payload | string | A JSON stringified string containing the channel-specific message format | :::important Ensure your payload matches the target channel's message format requirements. ::: **Example Structure:** ```json { "passthrough": [ { "channel": "string", "payload": "string" // JSON stringified payload } ] } ``` ## Platform-specific implementations ### Sunshine Conversations For Sunshine Conversations (Sunco), the passthrough feature integrates with their native passthrough API. The payload is placed in the `override` field of the WhatsApp message. See the [Sunshine Conversations passthrough documentation](https://docs.smooch.io/guide/whatsapp/#passthrough-api) for detailed examples. ## Examples The following example demonstrates sending a custom WhatsApp message using passthrough. On all other channels, the AI Agent sends only the text "Hello!". ```json { "type": "text", "text": "Hello!", "passthrough": [ { "channel": "whatsapp", "payload": "{\"type\":\"template\",\"template\":{\"namespace\":\"XXXXXXXX_XXXX_XXXX_XXXX_XXXXXXXXXXXX\",\"element_name\":\"hello_world\",\"language\":{\"policy\":\"deterministic\",\"code\":\"en_US\"},\"components\":[{\"type\":\"header\",\"parameters\":[{\"type\":\"image\",\"image\":{\"link\":\"https://image.jpg\"}}]}]}}" } ] } ``` ## Best practices 1. Always validate your channel-specific payloads against the platform's documentation. 2. Test passthrough messages in a development environment first. 3. Keep track of platform-specific features and limitations. 4. Consider fallback options for channels that don't support certain message types. ## Limitations - The passthrough feature is only available through the API. - Each channel has specific message format requirements and limitations. - Messages sent via passthrough bypass Moveo's standard message processing and validation. ## Channel documentation For detailed message format specifications, refer to these platform-specific resources: - [WhatsApp Business API documentation](https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages) - [Viber REST API documentation](https://developers.viber.com/docs/api/rest-bot-api/#message-types) - [Sunshine Conversations passthrough documentation](https://docs.smooch.io/guide/whatsapp/#passthrough-api) --- ## Survey response The survey response is essentially a [webview](./webview.md) that makes it easy for users to provide their thoughts and opinions on your AI Agent's performance. You can either use the default satisfaction survey, as shown in the following demonstration, or [create your own](../../guides/survey.md). ## Fields A survey contains the following fields: - **`url`**: A valid and public URL to the survey webview. Its default value is the default satisfaction survey, hosted at [https://webviews.moveo.ai/common/survey](https://webviews.moveo.ai/common/survey). - **`name`**: The text shown at the top of the box. - **`label`**: The text that appears on the button. - **`height`**: The height of the survey webview window. --- ## Text response '@site/src/components/Img'; The most common response to a question is a text response. It is mainly used to inform the user or guide them. ## Use of a text response The following images show the implementation of a simple intent trigger-response model. When the user sends a message like "Hello, when are you open?", the AI agent replies with the text response specified within the dialog node. ## Options Give **options** to the user in the form of buttons. Under a text response, optionally add one or more options to facilitate the conversation with the user and lead them to predetermined sections. For example, you could suggest a continuation of the above conversation by introducing a _Location_ and an _Appointment_ request as options. Options consist of **`label`** and **`text`** fields. The `label` is what the user sees as an option, and the `text` is what you want to send to Moveo upon the user's click. The following example shows an implementation of options in a `#store_hours` intent. When the user clicks on the _Location_ button, Moveo receives the text "Where are you located?" and answers accordingly. ## Alternative text Write alternative text responses within the same response to avoid being repetitive. When triggered, the AI agent randomly selects one of the texts you give it as options. ## Customization Moveo's rich text editor allows you to customize your text responses using Markdown. You can add emphasis to your text using **bold** or _italics_, create [hyperlinks](#customization) to relevant content, and even insert emojis 😃 to convey emotions. This feature gives you the flexibility to tailor your responses to your audience and make them more engaging and effective. --- ## URL response Respond with a URL instead of text. This opens the link directly in the user's browser or messaging app. ## Why use URL responses Use a URL response rather than adding a URL inside a text response. This approach: - Prevents encoding errors with special characters - Handles context variables in query parameters correctly - Provides a cleaner user experience on messaging platforms - Allows tracking and analytics on link clicks ## How to add a URL response 1. Open your dialog in the editor 2. Add a new response node 3. Select **URL** as the response type 4. Enter your URL in the input field ## Using context variables Include context variables in your URL to create dynamic links: ``` https://example.com/order?id={{$order_id}}&user={{$user.email}} ``` The system replaces variables with their values before sending the URL to the user. ## Common use cases | Use case | Example URL | |----------|-------------| | Order tracking | `https://store.com/track?order={{$order_id}}` | | Password reset | `https://app.com/reset?token={{$reset_token}}` | | Documentation | `https://docs.example.com/{{$topic}}` | | External forms | `https://forms.example.com?prefill={{$user.email}}` | ## Next steps - [Text responses](./text.md) - Standard text messages - [Image responses](./image.md) - Send images to users - [Context variables](../context.md) - Learn about using variables in responses --- ## Video response Instead of a text response, you can reply with a video. Either add the URL of the video or upload it directly. The video response contains the following fields: 1. **`url`**: The URL of the video. Note that when you upload a video, the `url` field automatically fills with the video's URL. 2. **`name`**: The name you give the video, which is only shown when the video cannot load. --- ## Webhook ## Overview A [webhook](../webhooks.md) allows you to use another program, platform, or database. By connecting to it, your end user can perform various actions directly from the AI Agent chat without ever having to leave it. These actions include: - Booking appointments - Making purchases, handling returns, and processing refunds - Filling out web forms - Sending emails - Retrieving end user information - Updating a Google Sheet with necessary data ## Use of webhook response A webhook contains the following two fields: - **WEBHOOK**: The selected webhook from the list of webhooks in the AI Agent - **FALLBACK**: The text to send to the user if the webhook call fails --- ## Webview response '@site/src/components/Img'; ## Overview A webview can be used when it is necessary to collect a large amount of information from the user. It offers a similar experience to a common website, where the user interacts with a static HTML page. This is typically used to complete a form, register for an event, or any other applicable scenario. :::note A webview can **only** be used with Webchat, Facebook Messenger, and Viber, and **must** be hosted on a public URL. ::: See the step-by-step guide on [how to create a webview](./webviews). ## Fields A webview contains the following fields: - **`url`**: A valid and public URL to the webview - **`name`**: The text shown at the top of the box - **`label`**: The text that appears on the button - **`trigger_node`**: The trigger node that the flow returns to when the user closes the webview - **`height`**: The height of the webview window :::note The height option is only available in Facebook Messenger, Webchat, and Zendesk Sunshine. ::: --- ## Webviews ## Templates - If you want to jump straight into some template code, go to our [integration-guides repository on GitHub](https://github.com/moveo-ai/integration-guides). - You can test [a template AI Agent that uses a form webview](https://web-client.moveo.ai/preview?integrationId=28b47bb5-63cd-4ea8-a821-f1c0d242af3f). ## How to create your own webview When the [Webview response node](./webview.md) is triggered, and the customer presses the **Open Form** button, Moveo calls your webview URL and appends the necessary query parameters. For example, the URL `https://webviews.moveo.ai/Company/webview-name` would be called like: `https://webviews.moveo.ai/Company/webview-name?channel=facebook&integration_id=1a234567-b8cd-9e0f-1234-g5h6ij78klmn&page_id=1234567890123456&session_id=ab1c23d4-5ef6-7gh8-i9hj-k0lm12345n6o&trigger_node_id=123456a7-bc89-01d2-345e-67f89g012h34&user_id=1234567890123456` ### Ensuring the origin of the webview request In some cases, the webview may need to exchange context with the AI Agent. To ensure that the data is secure in that event, create a pair of RS256 private and public keys by executing the following commands: ```shellscript openssl genrsa -out private.pem 2048 openssl rsa -in private.pem -outform PEM -pubout -out public.pem ``` Add the public key to your integration (example for Facebook): - Go to the Integrations tab of your account. - Select your environment and integration. - Add the public key in the **YOUR PUBLIC KEY** field of the integration. ### Creating the webview Here is a step-by-step example of creating a webview that uses a form to collect data from the user and sends it back to Moveo. 1. Get the following query parameters from the URL: | Parameter | Required | Description | | ----------------- | :----------------: | --------------------------------------------------------- | | `integration_id` | :heavy_check_mark: | The ID of the integration that triggered the webview | | `session_id` | :heavy_check_mark: | The ID of the current conversation session | | `user_id` | :heavy_check_mark: | The user's unique ID in Moveo | | `channel` | :heavy_check_mark: | The integration channel (e.g. `web`, `facebook`, `viber`) | | `trigger_node_id` | ➖ | The ID of the node that triggered the webview response | | `page_id` | ➖ | The Facebook page ID (Facebook Messenger only) | | `lang` | ➖ | The language code of the AI Agent, if set | :::tip The `user_id` is also available in the payload of any Moveo webhook call to your backend — it is included under `context.user.user_id` in [event webhooks](../webhooks.md#first-message-and-pre-message-webhooks) and can be passed explicitly as a context variable in [dialog webhooks](../action-webhooks.md). This is useful if your webview is opened from a flow where a webhook has already run and you want to correlate the two requests server-side. ::: 2. Collect data using a form or in any other way you wish. 3. Prepare the request body: ```ts data = { trigger_node_id, // required, UUID of the trigger node context: { // optional, any context variables you want to pass back to the AI Agent. ...contextFromForm, }, }; ``` The `context` field is merged into the conversation's context object and the variables become available to the flow. See [Context and variables](../context.md) for details on how context works and what system variables are already available. 4. Generate a signature (example in JavaScript) ```ts const secret = Buffer.from( // your private RSA key process.env.PRIVATE_RSA_KEY, 'base64' ).toString(); const payload = { sub: , // Required iss: 'www.webviews.moveo.ai', // Required }; // The "expiresIn" option adds an "exp" claim to the payload. sign(payload, secret, { algorithm: 'RS256', expiresIn: '4000ms' }); ``` 5. Send the data to Moveo by making an HTTP POST request to: `https://channels.moveo.ai/v1/webview/${integration_id}`, using the following headers: ```ts headers: { Authorization: `Bearer ${signature}`, 'X-Moveo-Session-Id': sessionId, 'Content-Type': 'application/json', } ``` A successful request returns HTTP `200 OK`. Error responses return a JSON body with `error_code`, `error_message`, and `status_code` fields. Common error cases include an invalid or expired JWT (`401`), a missing or expired session (`401`), or a missing `trigger_node_id` (`400`). 6. Finally, close the webview by performing the following: ```ts const closeWebview = () => { if (channel === "facebook") { return closeFacebookWebview(); } return window.close(); }; ``` ### Additional utilities For Facebook, check out the [Messenger utility methods](https://developers.facebook.com/docs/messenger-platform/reference/messenger-extensions-sdk/) to learn more about some methods you could use for your webview. --- ## Setup This configuration framework fine-tunes the AI agent's behavior, tone, and response style to better serve customers. Proper setup ensures that the AI agent enhances the user experience, drives platform adoption, and aligns seamlessly with business goals. ## Company name Each AI agent can be designed to serve different companies under the same account. This ensures a tailored user experience that aligns with the branding, tone, and goals of each company. ## AI Agent goal Define the specific objective of the AI agent to align with the desired outcomes. This ensures the agent delivers targeted and accurate assistance to end-users. :::tip Setting a clear goal helps the AI agent support business priorities, improve user engagement, and drive measurable outcomes. ::: ## Tone of voice Set the communication style for the AI agent to ensure it matches your company's branding and user experience. ### Available tone options 1. **Creative**: Engaging, fun, and expressive tone for interactive and informal user interactions. 2. **Neutral**: Balanced and clear communication suitable for general use. 3. **Matter-of-fact**: Straightforward, practical tone focused on delivering clear and direct information. 4. **Professional**: Polite, formal, and competent style ideal for business and enterprise environments. Matching the tone to your audience enhances user satisfaction, builds trust, and ensures the AI agent communicates effectively. :::info Tone options may slightly differ based on the selected **AI Agent type** to better align with its purpose. ::: ## Response length Customize how detailed the AI agent's responses should be based on user interaction needs and the complexity of your business. Tailoring response length optimizes user interactions, ensuring clarity while balancing speed and detail based on your workflows and user needs. ### Available response options 1. **Short**: Minimal, concise replies covering only the essentials. 2. **Standard**: Balanced responses with clear and informative details. 3. **Comprehensive**: In-depth replies that provide additional context and thorough explanations. ## Conversation start The **Conversation start** setting lets you pick the dialog node every new conversation begins at — always, regardless of how the user opens the conversation. The opening becomes **deterministic**: you design it once, in a regular dialog node, and every user gets the same entry point. Set **When a conversation starts, trigger:** to the node of your choice and save. Common use cases: - **Authentication at the start of the session** — the most common case. Place an [Authentication action](../authentication/authentication-overview.md) in a node and have every conversation start there. - **Scripted welcome flows** — a fixed greeting, an introduction of the agent's capabilities, or a routing menu. - **Compliance disclaimers** — recording notices, terms the user must see before anything else. - **Data collection up front** — questions or webhooks that populate context the rest of the workflow depends on. In the dialog builder, the chosen node is marked with a *"Conversation starts here"* icon in its header. ## Global reminders The Global Reminders feature allows you to configure automated follow-up messages when a user does not respond within a set timeframe. These reminders ensure that conversations stay active and users receive timely nudges to engage with the AI agent. ### Configuration options - You can set up to **three (3) reminders**. - Reminders must be configured in **ascending order** (i.e., the first reminder must be the shortest interval, followed by longer intervals). - Each reminder is linked to a **specific node** that will be triggered when the reminder is sent. ### Timers Each reminder consists of: - **Time Delay**: The amount of time (e.g., 5 minutes, 15 minutes, 30 minutes) after which the reminder is sent if the user remains inactive. - **Connected Node**: The system calls a predefined node (e.g., "Affirmative" in the screenshot) when the timer expires. - **Preview**: Clicking the **Preview** button allows you to view the dialog in which the selected node is contained. The following example shows a possible configuration: - **Reminder 1**: Sent after **5 minutes** of inactivity, triggering the **Affirmative** node. - **Reminder 2**: Sent after **15 minutes** of inactivity, triggering the **Affirmative** node. - **Reminder 3**: Sent after **2 hours** of inactivity, triggering the **Goodbye** node. **Preview:** **Actions**: - **Add Timer**: Allows you to configure additional reminders (up to a max of 3). - **Delete Timer**: Removes an existing reminder. - **Save**: Confirms and applies your reminder settings. ## Next steps - [Knowledge & Guidelines](./knowledge.md) - Configure what your agent knows and how it responds - [Advanced settings](./advanced.md) - LLM selection, prediction thresholds, and timeouts - [Test your agent](./test.md) - Validate responses before deployment - [Dialogs](./dialogs.md) - Create advanced workflows with conditional logic --- ## Simulations Simulations are regression tests for your AI Agent. Describe a conversation in plain language, describe what success looks like, and Moveo runs the whole multi-turn conversation for you. The conversation goes through the same pipeline that serves your customers, and you get a pass or fail verdict with written reasoning. This turns agent changes from guesswork into something you can verify. Write 10 to 20 simulations covering the behavior you care about most, run them after every change, and you know within minutes whether you broke anything. :::note Paid feature Simulations require a paid plan. Trial accounts see an upgrade prompt instead of the feature. ::: ## How a simulation works Each simulation runs as a three-part loop: - **A simulated customer** plays the role you described in the scenario. It sends one message at a time and stays in character. - **Your AI Agent** answers through its real pipeline, using the same knowledge base, guidelines, dialogs, tools, and webhooks it uses in production. - **An evaluator** reads the finished conversation and grades it against your success criteria, then explains its verdict. The conversation ends when the simulated customer has nothing left to say, or when the turn limit is reached. ## Create a simulation 1. Go to **AI Agents**. 2. Select the AI Agent you want to test. 3. Open **Simulations**. 4. Click **Create**. 5. Fill in the fields described in the following table. 6. Click **Create** to save it. When **Schedule** is **Not set**, you can click **Create & Run** instead to save the simulation and run it immediately. | Field | What to enter | | --- | --- | | **Title** | A name that describes the purpose of the test. Titles are unique per AI Agent. | | **Scenario** | The situation, including the customer's goal and key details. | | **Success criteria** | The actions or outcomes required for the agent to succeed. | | **Channel type** | The format of the conversation: **Chat**, **Email**, or **Voice**. | | **Schedule** | How often the simulation runs on its own. Leave it as **Not set** to run it manually. | | **Category** | An optional label that groups and filters your results. | As you type, Moveo reviews your draft and suggests improvements, such as tightening success criteria that are too vague to grade. The suggestions are advisory and never block you from saving. ## Write an effective scenario The scenario describes both what happens and who the customer is. The simulated customer plays that role, so the more specific you are, the more realistic the conversation. Useful details include: - **The customer's goal** — "wants to deposit money", "asking about loan rates", "closing their account". - **Personality and emotional state** — "frustrated", "polite and elderly", "panicked after losing their card". - **Language** — "writes entirely in Greek", "starts in English, then switches to Spanish". - **Domain context** — "owes \$5,000", "long-time customer unhappy with a fee increase". - **Conversation dynamics** — "after three messages they get impatient and ask for a human". - **Adversarial behavior** — jailbreak attempts, social engineering, or heavy typos. The simulated customer also receives a summary of your agent's configuration, including its name, goal, and default language. Its messages therefore read as realistic against that specific agent. ## Write effective success criteria The evaluator grades the conversation against your wording, so describe observable behavior rather than a general impression. The evaluator reads the full transcript **and** structured data collected during the run: which tools the agent invoked, which webhooks fired, whether the conversation was handed over to a human, whether the agent ever fell into an unknown or fallback response, and the final session context. That means criteria can assert on far more than the words in a reply: | What you want to check | Example criteria | | --- | --- | | A specific answer | "The agent states that the current interest rate is 4.2%." | | A behavior | "The agent hands over when the customer explicitly asks for a human." | | Language compliance | "The agent responds in Greek throughout." | | Tool usage | "The agent calls `get_account_balance` before answering." | | Webhook usage | "The agent triggers the know your customer (KYC) webhook before confirming the transfer." | | Containment | "The conversation is never handed over to a human." | | Coverage | "The agent never falls back to an unknown response." | | Flow adherence | "The agent acknowledges, offers alternatives, and only closes if the customer insists." | | Refusals | "The agent refuses to share internal system details." | | Context variables | "The `user_tier` context variable holds the customer's tier by the end." | :::tip Make criteria observable "The agent responds well" cannot be graded, because nothing in the transcript proves it. Rewrite vague criteria as a concrete action or outcome, such as "The agent retrieves the balance and offers a payment plan." ::: ## Run simulations Run simulations from the **Simulations** tab in any of these ways: - Open the actions menu on a row and choose **Run** to run that one simulation. - Select several rows with their checkboxes, then click the run button to run the selection. - Click **Run all** to run every simulation on the AI Agent. A notification confirms the run has started and tells you it is usually done within minutes. A second notification arrives when the run finishes, even after you navigate elsewhere. To stop a run that is still going, open its actions menu in the **Runs** tab and choose **Stop**. Stopping cancels the remaining simulations and cannot be undone. ## Schedule runs Set the **Schedule** field on a simulation to run it automatically: | Cadence | When it runs | | --- | --- | | **Weekdays** | Monday to Friday at 09:00 UTC | | **Weekly** | Every Monday at 09:00 UTC | | **Monthly** | The first day of each month at 09:00 UTC | Simulations that share a cadence run together in one scheduled run. Set the field back to **Not set** to remove a simulation from its schedule. ## Read the results The **Runs** tab lists every run with its date, status, success rate, number of simulations, number of failures, duration, and what triggered it. Filter by status, trigger, or date range to narrow the list. Open a run to see a summary of its success rate, failure count, and total simulations, followed by a table of results. Each row shows one simulation and its result: | Result | Meaning | | --- | --- | | **Success** | The agent met your success criteria. | | **Fail** | The agent did not meet your success criteria. | | **Error** | The simulation could not complete. | | **Pending** | The simulation is queued. | | **In progress** | The simulation is running. | Click **Preview** on a row to replay the conversation turn by turn. The panel alongside it holds five tabs: - **Results** — the verdict and the evaluator's written reasoning, together with the scenario and pass condition used for the run. - **Details** — what the agent did on the selected turn. - **Context** — the context variables at the selected turn. - **Conversation** — the conversation ID, request ID, channel, turn count, and duration. - **Insights** — click **Generate insights** to run the insights configured on your AI Agent against this transcript. The evaluator's reasoning points at specific turns, so a failure tells you what to fix: a guideline, a dialog flow, a knowledge base document, or a tool. :::note Results reflect the agent at run time A run shows an **(outdated)** marker when the simulation changed after the run finished. Run it again to grade your agent against the current wording. ::: ## Examples | Title | Scenario | Success criteria | Channel | | --- | --- | --- | --- | | Frustrated handover | An impatient customer who has waited 10 minutes grows frustrated after two or three messages and demands a manager. | The agent acknowledges the frustration and hands over without trying to resolve further. | Chat | | Card-loss panic | A panicked customer whose card was stolen urgently demands that it be blocked. | The agent treats the request as urgent, confirms identity quickly, and calls `block_card`. | Chat | | Multilingual Greek | A Greek-speaking customer writes entirely in Greek to ask about loan rates. | The agent responds in Greek with accurate information from the knowledge base. | Chat | | Hardball debtor | An aggressive customer who owes \$5,000 refuses to pay and threatens legal action. | The agent stays calm, empathizes, and presents installment options without being confrontational. | Chat | | Email dispute | A customer sends a formal email disputing a \$150 charge from an unrecognized merchant. | The agent acknowledges the dispute, explains the investigation timeline, and starts the dispute flow. | Email | --- ## AI Agent training and testing ## Confidence Level When the AI Agent is not 100% certain about a user's message, it makes an elaborate prediction based on its smart AI algorithm and responds according to its confidence level. :::note The only way the AI Agent responds with 100% confidence is if the user's message exactly matches an intent expression you have written. ::: Review these predictions and use the [**Amend**](#add-new-training-phrases) functionality inside the test to manually link the [intent](./intents.md) with the correct expression. A very effective way to use training and increase the confidence level of your AI Agents is to invest time in feeding them profession-specific language and jargon. This helps the AI Agent learn and adapt to your needs. With state-of-the-art [NLP](https://en.wikipedia.org/wiki/Natural_language_processing) algorithms, machine learning, and a bit of guidance, your AI Agent will be able to engage in meaningful end-to-end conversations with your users. ## Testing Your AI Agent Click **Test** to interact with your AI agent and evaluate its responses. Pretend to be an end user and check if the assistant answers your questions correctly. Test your AI agent either within Moveo or with WhatsApp. :::note When testing with WhatsApp, you simulate the conversation using your phone number. This is different from [an integration with WhatsApp](../integrations/whatsapp), as it tests the integration with our Moveo number. You must have a WhatsApp account with this number to test. ::: ## Amend ### Rephrasing Before the user's message goes to the AI Agent, it passes through a specialized LLM that understands and routes the message to a specific intent. During this process, the message can be rephrased to improve understanding. However, this rephrasing may not always be accurate, leading to a lower confidence level in matching the intent. In such cases, you can use the Amend feature to correct the rephrased message. :::warning This rephrasing **WILL NOT** take effect immediately. It will be used to improve the training data for future versions of our LLM. ::: ### Add New Training Phrases In the replayed logs section, if an intent that should have a higher confidence level is not triggered, you can use the Amend feature to add the user’s input as a new training phrase. This helps the AI Agent better understand the user’s intent. If an intent already has a 100% match, the Amend button will not be displayed. ### Amend the Response If the source of the AI Agent's response is synthetic, you can amend the response to improve its accuracy. As with [rephrasing](#rephrasing), this will not take effect immediately. ## Context Add your own [context variables](./context.md), custom user information, or tags to the session to test the AI Agent's behavior under specific circumstances. --- ## Event trigger Event triggers are the links between different dialogs. They connect two or more dialogs together. Moveo breaks down the obsolete tree-like bot structure and uses many small, independent parts that interconnect with each other. The transition from one dialog to another is seamless. ## How to use an event trigger Use the event trigger to create a reusable dialog flow. Link it to a specific moment in a conversation using the **Jump to** action. In the following example, the **Jump to** action (left) triggers the dialog that has an event trigger as its parent node (right). | Jump action | Event trigger | | :--------------------------------------------------------: | :---------------------------------------------------------: | | | | --- ## Triggers Every [dialog](../dialogs.md) starts with a single trigger. Moveo.AI supports the following triggers: | Type | Description | | :---------------------- | :------------------------------------------------------------------------------------ | | [Text](./text.md) | Triggered by text messages | | [Event](./event.md) | Triggered internally from a different dialog node | | [Unknown](./unknown.md) | Triggered when Moveo cannot match any of the dialog nodes given the recognized intent | ## Add a trigger Add a new trigger using Moveo's drag-and-drop functionality. :::caution Avoid using the same trigger words for multiple intents to prevent collisions. ::: ## Uses of triggers Moveo has two different functionalities for triggers: 1. They can be used as the parent trigger (`$r_0$`, `nodes[0]`) in a dialog. 2. They can be used as child triggers to provide a different response. See what happens for an [intent trigger](./text.md) and a [fallback](./unknown.md). --- ## Intent trigger Use intent triggers to start a dialog **directly** from a user's message. When the AI Agent recognizes the intent behind the user's message, it activates the corresponding trigger and starts the respective dialog. An intent trigger is always connected to an **intent**, which signifies the activation of the trigger. ## How to use an intent trigger An intent trigger is connected with the intent `#store_hours`. When a user sends a message like "When are you open?", the AI Agent identifies the intent as `#store_hours` and starts the corresponding dialog. | Dialog | Chat | | :----------------------------------------------------------: | :-------------------------------------------------------: | | | | ## Multilevel dialog An intent trigger can also serve as a **child** node in a dialog. This means that the AI Agent activates the trigger only when it is already inside the dialog of a parent node. The following example shows a case in which the intent `#affirmative` is used as a parent and a child node. When `#affirmative` is the parent node, if the user types 'yes' the message 'I'm listening!' comes up. However, when they ask about appointments and the AI Agent asks for confirmation, given that `#affirmative` is a child node of the `#appointments` one, the response of booking appointments comes up. --- ## Fallback If your AI Agent doesn't recognize the user's intent, it activates the **fallback** trigger. This can occur in the following situations: - The AI Agent recognizes the intent with a [confidence level](../test#confidence-level) below the threshold you have set. - You have not connected the intent to a trigger that matches the dialogs you have already set up. This can be done for intents like [`#offtopics`](../intents#off-topic-messages). - The AI Agent does not recognize an appropriate answer to a [question](../operations/questions.md) (wrong type or entity). ## Multilevel dialog The fallback can also serve as a **child** node in a dialog. This means that the AI Agent activates this trigger only when it is already inside the dialog of a parent node. When the fallback is a child node, if the user types something that the AI Agent cannot understand within a dialog, the message it gives the user is different than when the user is not in the dialog. --- ## Versions Moveo allows you to create multiple versions of the same AI agent. Imagine you are operating an AI agent in production, with users asking questions throughout the day. If you want to implement new changes without making them visible to your users immediately, you can use versions. ## Draft state All changes you make are saved to the **draft** state of the AI agent. In [Test](test.md), you always interact with the draft version of the AI agent. It works as one more version of the AI agent, with the difference that already published versions will get locked and are not editable. This means that you can also assign a conversation to a draft version if you set a [rule](../environments/rules.md) to do so. ## Create a new version To create a new version: 1. Go to the AI Agent you want to create a new version of. 2. Click the **Publish version**. button in the top right corner of the screen. 3. Write a short description of your changes. 4. Click the **Save**. button. :::caution The system allows up to **25 versions** at any time. To exceed this limit, delete a previous version before creating a new one. ::: ## Manage a version For any version of the AI agent, you can perform the following operations in the **Versions** menu: 1. **Restore**: Revert the AI agent to the selected version. 2. **Export**: Download a JSON file of the selected version. 3. **Delete**: Permanently delete the selected version. ## Assign the new version After you create a new version and are ready to share it with your users, navigate to the [**rules**](../environments/rules.md) and set in the **then** section the new version of the AI agent. --- ## Webhooks ## Introduction Webhooks let your AI Agent call your own backend during a conversation. Whenever a webhook fires, Moveo sends an HTTP `POST` to a URL you provide; your endpoint can read the conversation context, run business logic, and respond with new context variables or replies for the agent to deliver. Moveo supports six webhook types, each firing at a different point in the conversation: | Type | When it fires | | --- | --- | | [Dialog](./action-webhooks) | A dialog node hits a webhook action | | First message | Once per session, on the user's first message to a given AI Agent | | Pre message | Before every user message is processed | | Post message | After the agent has generated its reply | | [Authentication validation](../authentication/authentication-webhooks#validation-webhook-contract) | The Authentication Agent submits a candidate answer for a question whose *Validate answer via* is set to Webhook | | [Authentication pre-enter](../authentication/authentication-webhooks#pre-enter-webhook-contract) | Once, when entering the verification step — used to fetch ground-truth context | The dialog and authentication types share the wizard UI but each authentication type has its own request / response contract — see [Authentication webhooks](../authentication/authentication-webhooks) for the body shapes, signature verification notes, and code samples. A few rules: - You can configure **multiple dialog, authentication validation, and authentication pre-enter webhooks** per AI Agent and reference each from any node or auth slot. - You can configure **at most one** first message, one pre message, and one post message webhook per AI Agent. - If a first message webhook is not configured, the pre message webhook (if any) is called for the first message instead. This page covers configuring webhooks in the UI and the differences in their payloads. For implementation, code samples, and the full type reference, see [Build a webhook](./build-a-webhook). ## Set up a webhook The setup is the same for all types. Navigate to your AI Agent → **Workflows** → **Webhooks** → **+ Create webhook**, pick the type from the three groups (Dialog / Event / Authentication), and fill in the form. ### Required fields | Field | Description | | --- | --- | | Name | A label for the webhook. Must be unique within the AI Agent. | | URL | The HTTPS endpoint Moveo will `POST` to. Non-HTTPS URLs and loopback or private addresses are rejected in production. | | Verification token | A secret you choose. Moveo signs every request with HMAC SHA256 using this token, so your endpoint can verify the call originated from Moveo. Treat it like a password. | | Type | One of dialog, first message, pre message, post message, authentication validation, or authentication pre-enter. | ### Custom headers You can add up to 10 custom headers that Moveo will include on every call to your endpoint — for example, an API key your backend expects. :::note Reserved headers The following headers cannot be set as custom headers: `Host`, `Connection`, `Content-Length`, `Transfer-Encoding`, `Origin`, `Referer`, `Range`, `Max-Forwards`, `Upgrade`, `TE`, `Trailer`, `X-Forwarded-*`, `Proxy-*`, `Access-Control-*`, `Sec-WebSocket-*`. ::: There is one Moveo specific custom header you can opt into: | Header | Effect | | --- | --- | | `X-Moveo-Include-History: true` | Adds the conversation history to the webhook payload under a `history` field. | ### Authenticating webhook calls Anyone who knows your URL could send a `POST` to it. Authentication ensures your endpoint only acts on requests that genuinely came from Moveo. Moveo signs every request with **HMAC SHA256** of the JSON body, using the verification token as the key. The signature is sent in the `X-Moveo-Signature` header. Your endpoint should recompute the signature and reject the request if it does not match. Code samples for verifying the signature are in [Build a webhook → Verify the signature](./build-a-webhook#verify-the-signature). If you cannot use HMAC and need to allow list IPs at your network edge instead, Moveo's webhook calls originate from your account region's outbound IP addresses — see [Outbound IP addresses](../platform/outbound-ip-addresses) for the full list per region. IP allow lists are a fallback, not a replacement, because Moveo's egress IPs may change. ### Other options | Option | Default | Description | | --- | --- | --- | | Enabled | On | Disable to stop the webhook from firing without deleting it. | | Fail on error | Off | If on, a non-2xx response or timeout interrupts the conversation. If off, the agent continues with whatever context it has. | ## Payload differences per type All four types share a common envelope and add type-specific fields on top. The fields below describe what your endpoint receives in the request body. Full TypeScript types are in [Build a webhook → Type reference](./build-a-webhook#type-reference). ### Common envelope | Field | Type | Description | | --- | --- | --- | | `channel` | string | Channel name (`web`, `whatsapp`, `viber`, etc.) | | `channel_type` | string | Channel category (e.g. `messaging`, `voice`) | | `session_id` | string | Conversation session identifier | | `desk_id` | string | Environment identifier | | `integration_id` | string | Integration the conversation is happening on | | `brain_id` | string | AI Agent identifier | | `lang` | string | Conversation language code | | `context` | object | All context variables collected so far, including `sys-*` system variables and the `user` object | | `timestamp` | integer | Unix epoch in milliseconds | | `history` | array | Optional. Included only when `X-Moveo-Include-History: true` is set as a custom header | ### Dialog webhook Fires when a dialog node executes a webhook action. Adds: | Field | Type | Description | | --- | --- | --- | | `input` | object | The user input that triggered the node, with `text` | | `intents` | array | Recognized intents, sorted by confidence | | `entities` | array | Entities extracted from the input | | `debug.dialog_stack` | array | The path of dialog nodes leading to this action | | `user_message_counter` | integer | How many user messages have been processed in the session | The endpoint can return both context updates and a `responses` array (text, media, carousel, webview, etc.) that the agent delivers to the user. ### First message and pre message webhooks Fire before the agent processes the user's input. Pre message fires every turn; first message fires only on the first message of a session for a given AI Agent. Adds: | Field | Type | Description | | --- | --- | --- | | `input` | object | The incoming user input, with `text` and `attachments` | | `business_closed` | boolean | `true` if the conversation is happening outside business hours | The endpoint can return a `context` update and an `input` object. Use `input.text` to rewrite the user message before the agent sees it, or `input.trigger_node_id` to route straight to a specific dialog node (bypassing intent classification). It cannot reply on the agent's behalf. ```json { "channel": "web", "session_id": "8563dcdf-64ef-4de2-a5ca-b96e0557e4e8", "desk_id": "d3d08940-f0ef-42e0-993c-1bea065dcqwe", "integration_id": "", "brain_id": "d3d08940-f0ef-42e0-993c-1bea065dcqwe", "lang": "en", "context": { "user": { "user_id": "test-O44vJC-TuXiJXh8hkXvlZ", "display_name": "Visitor 2020", "verified": false }, "sys-channel": "web", "sys-business": "open", "sys-user_message_counter": 1 }, "timestamp": 1761045302529, "input": { "text": "hi", "attachments": [] }, "business_closed": false } ``` ### Post message webhook Fires after the agent has generated its reply, before the reply is delivered to the user. Skipped if the interaction was interrupted mid flight. Adds: | Field | Type | Description | | --- | --- | --- | | `input` | object | The user input that started this turn | | `intents` | array | Intents recognized for this turn | | `entities` | array | Entities recognized for this turn | | `output` | array | The agent's planned reply, as an array of action objects. The set is broader than the responses your endpoint can return — see [agent actions](./build-a-webhook#agent-actions). | | `debug.dialog_stack` | array | Path of dialog nodes traversed | | `user_message_counter` | integer | Total user messages in the session | The endpoint can return a `context` update and, optionally, a `responses` array. If `responses` is present, it replaces the agent's planned reply and is delivered as-is — no templating or context-variable substitution is applied. ## Test your webhook Each webhook in the UI has a built in tester that sends a real request to your endpoint. ### Simple test Click **Send test request** to fire a default payload. The right hand panel shows the HTTP status code, execution time, and response body. ### Update context variables from the test When your endpoint returns context fields, you can click **Update context variables** to register them as known variables in the AI Agent. Once registered, they appear in the auto complete inside dialog nodes and other webhooks. ### Advanced test The **Advanced test** section lets you edit the request payload before sending — useful for reproducing a specific session's context or trying edge cases. ## Use case examples The following are the patterns customers use most often. Each one points to a worked implementation in [Build a webhook](./build-a-webhook). - **Live instructions on session start.** Use a first message or pre message webhook to fetch user data from your CRM and inject it into the conversation as the `live_instructions` context variable. The agent reads it on every turn and personalizes its replies. Worked example: [Live instructions](./build-a-webhook#use-case-live-instructions). - **Validate user input mid conversation.** Drop a dialog webhook action into a workflow node to check something the user said against your backend before the conversation continues. Update context with the result and branch on it downstream. Worked example: [Validate input](./build-a-webhook#use-case-validate-input). - **Audit or override the agent's reply.** Use a post message webhook to inspect the agent's planned reply and either log it or replace it. Useful for compliance review and trailing analytics. Worked example: [Post message audit and override](./build-a-webhook#use-case-post-message-audit). --- ## Workflow Generator The Moveo.ai Workflow Generator is a solution for building task-oriented virtual agents using large language models like [GPT-4](https://en.wikipedia.org/wiki/GPT-4). The main benefit of using the Workflow Generator is its ease of use. Create a dialog by describing the task in plain English. The Workflow Generator takes care of the rest, automatically generating the necessary code and training data. This saves time and effort compared to traditional methods of building virtual agents. However, it is important to note that the virtual agent generated by the Workflow Generator will require verification and refinement to meet specific requirements and perform optimally. The Workflow Generator offers a quick and easy way to create a first version of a dialog, complete with necessary intents and entities. This provides a solid foundation for you to make final touches and adjustments to meet your specific needs. ## Use Create your own dialog using the Workflow Generator by performing the following steps: 1. Create an AI Agent or select an existing one. 2. Go to **Dialogs**, create a new dialog and select **Generate from description**. 3. Describe a task that you want the AI Agent to perform. 4. The AI Agent will come up with a new dialog, intent, and, if needed, one or more entities. Click **Accept** to confirm. 5. Test the AI Agent to check if everything works as intended, and make any changes you need for it to meet your needs. ## Example prompts Experiment with the Workflow Generator using the following example prompts. Some prompts are straightforward and simple, while others are more complex and may require the AI Agent to ask the user questions and respond according to conditions. ### Simple prompts #### Provide Contact Details ``` When a user asks about your contact details, tell them that our phone number is +1 4153243324 and our email address is info@company.com. ``` #### Handover to Agent ``` When a user wants to speak to an agent, tell him/her politely that a representative will be with him/her shortly and handover the conversation. ``` #### Show Office Locations ``` When a user asks about where our offices are, give her a carousel with our office locations. ``` #### Display Available Apps ``` When a user wants to download an application from the app store, show him a carousel with all the available apps. ``` #### Share Messenger QR Code and Link ``` When a user wants to talk via Facebook messenger, give him an image with the QR code and a deep link. ``` ### Complex prompts #### Cancel Appointment ``` When a user wants to cancel an appointment, ask for the user's booking id (10 digits) and ask her to confirm the appointment cancellation. If she says yes, then write to a google sheet with the user's booking id. Else, ask the user if you can help with anything else. ``` #### Modify Booking ``` When a user asks for a booking modification, get their 1. name 2. email 3. modification reason and 4. booking code (starts with WH followed by 5 digits). Then send an email to info@company.com with the modification request details and tell the user that we will contact them soon with updates on their request. ``` #### Handle Viber Requests ``` When a user says they want to talk in Viber, check if they are already in Viber. If they are, tell them you can see they are in Viber, otherwise send them a carousel. ``` #### Check Reduced Ticket Eligibility ``` When a user asks if they are eligible for a reduced ticket, ask them if they are in any of these groups: Unemployed, Elderly, Disabled, or Students. If they are Elderly or Disabled, tell them that they are eligible for a reduced ticket by presenting their proper documentation. Else, inform the users that they can issue a reduced fare only if they have their ID on them. ``` #### Report Broken ATM ``` When a user asks you about a broken ATM, get the ATM's location, and ask the user if they want to receive updates for when it will be fixed. If yes, get the user's email and tell them that they will receive updates in their email and write the ATM's location, user's email, and channel to a google sheet. Else, tell the user "Sounds good! Thanks for bringing this to my attention". ``` --- ## AI Agent effectiveness The **AI Agent effectiveness** section shows how well your AI Agent handles conversations. ## Coverage The **Coverage** chart shows the percentage of conversations where the AI Agent did not trigger the [Unknown](../ai-agents/triggers/unknown.md) node. In this example, 83% of conversations were **covered**, meaning the Unknown node never triggered. Hover over any bar to see the percentage and absolute count. ## Containment The **Containment** graph shows the percentage of conversations that did not require a live agent handover. Blue bars represent **contained** conversations that concluded without human intervention. Hover over any bar to see the percentage and absolute count. --- ## Customer satisfaction The **Customer satisfaction** section tracks how happy users are with their interactions, including both AI Agent and live chat conversations. ## Rating The **Rating by day** graph displays the average or median rating that customers give to sessions per day. ## Rating percentage of more than three stars The **Rating percentage of more than three stars** graph shows the percentage of sessions in which users give a rating of more than three stars (out of a maximum of five) per day. ## Remarks from customers The **Remarks from customers** table displays all conversations where users left ratings or feedback. Filter by rating to find unhappy users and replay their conversations. See [Logs](logs.md) for details on the replay feature. --- ## Live agent effectiveness The **Live agent effectiveness** section shows response time statistics for your live agents. Filter by environment or individual agent. ## Live agent responsiveness The **Live agent responsiveness** graph shows first response time and general response time. Choose between average, median, maximum, or minimum values. Compare data to the previous time period. ## First response time The **First response time** graph provides data about the first response time to a message. The _first response time_ is defined as the elapsed time between the user's first message and the agent's response. ## Response time The **Response time** graph provides data about the general response time to a message, which is the time taken for a live agent to reply to a message, without considering if it is the first message. :::tip Use the **median** when extreme values are present, and the **average** otherwise. ::: --- ## Insights ## Overview Insights automatically extract specific, structured information from your conversation history. They grade 100% of conversations and reveal how your [**AI Agent**](../ai-agents/overview.md) performs at scale. Instead of sampling a small set of dialogs, you gain a complete picture to track outcomes, identify issues, and prioritize improvements. Insights use a large language model (LLM) to interpret each dialog in context and return actionable results. You can use these results to personalize follow-ups, enrich your CRM, and power analytics. ## Types of insights Insights include two types: system insights and custom insights. ### System insights System insights are predefined, high-quality metrics available out of the box. They are tuned for different AI Agent use cases (for example, debt collection, support, upsell) and provide a reliable foundation for performance analysis. - **AI CSAT (customer satisfaction score)**: A score from 1 to 5 estimating user satisfaction based on the full conversation. - **Goal achieved**: Indicates whether the AI Agent accomplished its task. Possible values: `SUCCESS`, `PARTIAL`, `FAIL`. - **Sentiment**: Indicates how the user feels about the conversation. Possible values: `POSITIVE` (😊), `NEUTRAL` (😐), `NEGATIVE` (😞). ### Custom insights Custom insights let you define and extract business-specific data. Each custom insight includes: - **Name**: A human-readable title (for example, "Promise to pay date"). - **Description**: Clear guidance for the LLM describing the exact information to extract (for example, "The date the user promises to pay the outstanding balance"). - **Type**: The expected data type: - **Boolean**: A boolean value (`true` or `false`). - **Datetime**: A date and time value (for example, `2025-01-01 12:00:00`). - **String**: A string value (for example, `Has two unpaid invoices`). - **Integer**: An integer value (for example, `123`). - **Number**: A number value (for example, `123.45`). - **Email**: An email address (for example, `john.doe@example.com`). - **Phone number**: A phone number (for example, `+1234567890`). - **Categorical**: A string from a predefined list (for example, `willing`, `neutral`, `unwilling`). - **Categories**: Required when `type` is `categorical`; provide a list of up to 10 allowed values (for example, `eager`, `neutral`, `reluctant`). #### Categorical This type is similar to `boolean` but instead of just `true` or `false`, it is more nuanced and can be any of the categories you provide. For example, if you want to extract the user's willingness to pay, you can set the type to `categorical` and provide the following categories: `willing`, `neutral`, `unwilling`. You can define up to 10 categories per categorical insight. ## Insight processing When a conversation expires, Moveo triggers an extraction job that sends the conversation history to the insight extractor powered by an LLM. The extractor analyzes the full context and returns values for both system and custom insights enabled for the AI Agent. ### How to create custom insights Custom insights are linked to a specific AI Agent. Create them in the AI Agent's settings: 1. Go to **AI Agents**. 2. Select the AI Agent. 3. Open **Review → Logs**. 4. If Insights are disabled, enable the toggle. 5. Click **Create insight**. 6. Enter a name to identify the insight in the **Logs** table. 7. Add a description that guides the LLM on what to extract. 8. Select the data `type`. 9. If the `type` is `categorical`, add the allowed categories. 10. Click **Create**. ### How to view insights When a conversation expires and Insights are enabled, values appear as a new column in the **Logs** table. To continue the example from the previous section, we can see how the insight value shows differently for two different conversations. In the first conversation the user owes more than \$100, so the insight value is `true`. In the second conversation the user owes less than \$100, so the insight value is `false`. :::note Insight columns appear in the AI Agent's **Logs** table only, not in **Analytics**. ::: ## Related - [Analytics API overview](/api/analytics/api-overview) - [Customer satisfaction analytics](./customer-satisfaction.md) - [Agent effectiveness analytics](./ai-agent-effectiveness.md) --- ## Logs Logs allow you to replay conversations in the Administrator view, similar to the [Test](../ai-agents/test.md) experience. When reviewing logs, you can see the predicted intents with their confidence scores, the [context](../ai-agents/context.md) of the conversation including variables and user information, and more. You can also use the [Amend](../ai-agents/test.md#amend) functionality to improve and fine tune the AI Agent's responses. ### Analytics logs Access conversation logs through the analytics page. This view focuses on overall conversation performance across all agents. Use it to monitor general performance trends. ### AI Agent logs Access conversation logs through the AI Agent page. This view provides detailed information about conversations for a specific AI Agent, including context data. Use it for debugging and improving individual agent performance. To extract structured outcomes directly in this view, enable Insights for the AI Agent. See [Insights](./insights.md) for setup and supported data types. ### Log views comparison ## Filtering options Filter results by: - Channel (Web, Viber, and others) - [Coverage](ai-agent-effectiveness.md#coverage) - [Containment](ai-agent-effectiveness.md#containment) - Preview sessions - Tags - Ratings --- ## Analytics ## Overview Analytics help you answer questions such as: - What was the number of conversations/users per week during the last month? - How often do customers need to speak to a live agent? - Which days had the largest or smallest numbers of conversations in the last month? - What time of day do most users contact my business? - How fast do my live agents reply to the users? - Are the users satisfied with the AI Agent? What ratings do they leave? - Are there questions that the assistant is not trained to answer? The **Overview** page summarizes interactions between users and your AI Agent. View traffic for a selected time period, the percentage of meaningful conversations, and the most used environments. Use filters to narrow by date, environment, AI Agent, or channel. Exclude test conversations or filter by minimum message count. ## Meaningful conversations A conversation is labeled as **meaningful** if either of the following is true: - **LLM meaningful**: The conversation has at least one covered LLM response. - **AI Agent meaningful**: After the user's first message, an AI Agent has at least one covered and contained response. A session is meaningful when the AI Agent replies successfully at least once after the user's first message. A successful response does not originate from the _Unknown_ flow. :::note Conversations in preview environments are considered non-meaningful. ::: Below are some examples of meaningful and non-meaningful conversations. ### Examples of non-meaningful conversations ```plaintext --- Conversation Start --- User: Hi Assistant: Hi, how can I assist you? --- Conversation End --- ``` This is classified as a **non-meaningful** conversation, since it contains just one user message. ```plaintext --- Conversation Start --- User: Hi Assistant: Hi, how can I help you? User: How do I change my credit card number? Assistant: I'm sorry, I'm not sure how to help you change your credit card number. User: I want to change the four last digits. Assistant: I apologize, but I'm not sure how to help you change the four last digits of your credit card. --- Conversation End --- ``` This is classified as a **non-meaningful** conversation, since, after the user's first message, there are no covered AI Agent responses. ```plaintext --- Conversation Start --- User: Hi Assistant: Hi, how can I help you? User: I would like to speak to an agent Assistant: Ok, let me connect you to an agent --- Conversation End --- ``` This is classified as a **non-meaningful** conversation, since, after the user's first message, there are no contained AI Agent responses. --- ### Examples of meaningful conversations ```plaintext --- Conversation Start --- User: Hi Assistant: Hi, how can I help you? User: What payment methods do you support? Assistant: We support Visa, MasterCard and PayPal. --- Conversation End --- ``` This is classified as a **meaningful** conversation, since, after the user's first message, there is a covered and contained response. ```plaintext --- Conversation Start --- User: What steps do I need to follow in order to reset my account? Assistant (LLM): To reset your account, please follow the step-by-step instructions provided in our account recovery guide. --- Conversation End --- ``` This is classified as a (LLM) **meaningful** conversation, since it contains an LLM response. --- ## Overall performance In the **Overall performance** section, you can find useful data to compare live agents and AI Agents. ## Number of conversations handled This section displays the number of conversations handled by live agents and AI Agents. ## Response time Here, you can see the response times for both live agents and AI Agents. ## Rating This section shows the average or median ratings for live agents and AI Agents, as well as overall ratings. ## Performance This section provides information on the performance of live agents and AI Agents. ### Live agent performance This subsection contains useful information about each live agent. ### AI Agent performance The **AI Agent performance** table contains similar information to the [live agents' one](#live-agent-performance), as well as containment and coverage percentages. --- ## Usage The **Usage** section shows AI Agent activity for a specific time interval. Three graphs display key metrics. ## Counts The **Counts** graph shows messages, conversations, and customers for the selected time period. Enable comparison to see the previous period as gray bars alongside current data, with percentage changes displayed. ## Messages by time of day The **Messages by time of day** graph shows message volume during specific time intervals. Use this to identify peak hours. For example, high volume between 10 AM and 2 PM on Wednesdays suggests scheduling live chat coverage during that period. Hover over any cell to see exact counts. ## Conversations per channel The **Conversations per channel** graph shows conversation distribution across channels. Identify which channels (Web, Facebook, Viber, etc.) users prefer for contacting your AI Agent. --- ## Guidelines and exit conditions The Authentication Agent's behavior is steered by two free-text fields per step: the **step guideline** (general behavior) and the **failure guideline** (exit conditions). Together they're how you customize tone, script greetings, define alternative scenarios in natural language, and tell the Authentication Agent when to give up and escalate. ## Two kinds of guidelines | Where you set it | Purpose | | --- | --- | | Step card → **Guidelines** link → drawer | The **step guideline** — general instructions to the Authentication Agent for this step: tone, scripted greeting, the natural-language description of any alternative scenarios enabled by your scoring, objection handling, etc. | | **Failed identification/verification** panel → *Guideline-based* toggle | The **failure guideline** — an exit condition. Describe when the step should be considered failed. The Authentication Agent will end the step with failure if it detects the condition, regardless of how many attempts are left or how much time is on the clock. | Both are plain prose. The Authentication Agent reads them as instructions and tries to follow them. They are not templates, regexes, or DSLs — write them the way you'd brief a new contact-center agent. Because the Authentication Agent has [intentionally limited context](./authentication-overview.md#what-the-authentication-agent-can-see), anything you want it to *know* — your tone, the alternative-scenario phrasing, escalation rules — has to be in the guideline. Anything you want it to *not know* — the answers, the scoring config, the validation methods — is automatically out of reach. ## Scripted greeting via the step guideline When Authentication runs at the start of the session — the usual setup, with the Authentication action sitting on the node selected under [Conversation start](../ai-agents/setup.md#conversation-start) — the Authentication Agent owns the first turn of the conversation. There is **no separate "greeting message"** — the Authentication Agent generates the first message using your step guideline. Write a greeting *into* the guideline to control it. For example: > *Greet the user and introduce yourself as David, the AI assistant of Moveo Financial Services.* > > *Politely inform the user you need to ask them some questions for authentication purposes. If the user asks questions regarding their account, let them know they need to authenticate first. Also tell them they can ask to speak to a human at any time.* > > *After the user gives an answer, repeat it back to them for confirmation before checking if it's valid.* The guideline shapes: - The persona and tone ("David, the AI assistant of …") - Pre-flight disclaimers (the reason for the questions) - Affordances available to the user during auth (the explicit "you can ask to speak to a human") - The micro-UX of each question (repeat back for confirmation) The Authentication Agent is also instructed by the platform — independently of your guideline — to never reveal expected answers, scoring details, or internal configuration. You don't need to add that to your guideline. ## Failure guideline as an exit condition The failure guideline is the most flexible of the three failure conditions (alongside max attempts and timeout). Use it to **define when the conversation should give up and escalate**, without forcing the user to burn attempts. Examples: > *The user asks to speak to a human, or explicitly refuses to authenticate.* > *The user repeatedly says they don't have the requested information and asks for an alternative the agent cannot offer.* > *The user provides information indicating they are a third party (e.g. "I'm calling on behalf of my father") and not the account holder.* When the agent detects the condition described in the failure guideline, it exits the step with failure and routes to the **Trigger node on failure** — typically a [handover](../ai-agents/operations/handover.md) dialog. The failure guideline combines with **Incorrect responses** and **Authentication timeout** on the same panel. The three are independent — any of them firing ends the step with failure. ## Defining alternative scenarios Weights and the score threshold are what make an alternative scenario *possible*; the step guideline is what makes it *real*. The agent decides which question(s) to ask based on the guideline — it has no visibility into the math. A short example tying the two together: **Weights and threshold:** full tax ID weighted 2 points; last 4 digits of tax ID weighted 1; date of birth weighted 1; score threshold 2. **Step guideline:** > *Ask the user for their full tax ID. If they don't have it on hand, accept the last 4 digits of their tax ID together with their date of birth as an alternative.* The agent will start by asking for the full tax ID; if the user pushes back, the guideline tells it to offer the alternative pair. The scoring config ensures that whichever the user ends up giving, the math works out to ≥ 2 and the step passes. See [Scoring → Designing alternative scenarios](./authentication-scoring.md#designing-alternative-scenarios) for two more shapes. ## Channel-aware behavior The agent's response shape adapts to the channel: - **Voice** — ask one question at a time, keep responses short, spell out numbers and dates. - **Email** — bundle all questions for the current step into a single message. - **Chat (default)** — ask one question at a time, keep responses concise. Your guideline **composes with** these defaults — it does not replace them. If you write *"Ask all the questions at once"* in the guideline for a voice channel, the channel-level rule still applies and the agent will keep asking one at a time. Write the guideline in terms of *what to say* and *what to accept*, and let the channel-level rules handle *how to pace it*. ## Variables in guidelines Inside a guideline, reference a context variable by wrapping its dollar-prefixed name in double curly braces: `{{$name}}`, `{{$segment}}`. At runtime, the value is substituted in before the Authentication Agent reads the guideline. This is useful for: - **Personalized greetings** — `Greet {{$name}} by their first name only.` (once you have a `$name` populated — for outbound flows, the [campaign CSV](../campaigns/outreach.md#csv-format-reference) carries a `name` column that becomes available as `$name` in the conversation context). - **Conditional behavior** — `If {{$segment}} is "premium", acknowledge it once at the start of the conversation.` Variables resolved into the guideline at runtime become part of what the agent reads. They are not secrets — don't reference ground-truth variables in the guideline (the agent would then know the expected answer). ## Where to next - [Webhooks](./authentication-webhooks.md) — pre-enter and validation webhooks that populate the context your guideline can reference. - [Scoring](./authentication-scoring.md) — pairing guidelines with point/threshold math for alternative scenarios. --- ## Authentication overview **Authentication** verifies the user's identity through a short, conversational question-based flow. It is a **subagent action**: you drag it from the Toolkit into a dialog node, the same way you add a text response or a webhook. When the conversation reaches that node, the auth flow takes over — and only after the user passes (or fails) does the conversation continue to your regular workflow. Because it's an action, *you* decide where authentication happens. Place it at the start of the session (the most common setup — see [running it at session start](#running-authentication-at-the-start-of-the-session)), or deeper in a workflow so users only authenticate when they reach a sensitive operation. Once the flow starts, the **Authentication Agent** — an LLM-powered subagent that runs inside the AI Agent's message path — handles the back-and-forth with the user, validates answers against the ground truth you control (variables, exact match, fuzzy match, or a webhook you own), and routes to a dialog node of your choice on success or on failure. ## When to use Authentication Use Authentication when a workflow is gated on knowing *who* the user is — and getting it wrong is costly. - **Account access** — looking up a balance, opening a ticket on the user's behalf, changing account settings. - **Debt collection / financial services** — required identity verification before discussing amounts. - **Healthcare / insurance** — HIPAA-style scenarios where the user must be identified before any case-specific information is shared. - **Any flow that contains sensitive customer data** as context variables you don't want to leak to an unauthenticated user. If you only need *light* identity context (e.g. just look up the user's name from the channel), a dialog webhook ([Dialog webhooks](../ai-agents/action-webhooks.md)) is usually simpler. Reach for Authentication when you need the AI to *converse* through the verification — handling clarifications, multiple acceptable forms of identity, failure paths to human handover, etc. ## The mental model ```mermaid flowchart LR A([Conversation reaches the node]) --> C[Identification step] C -->|score ≥ threshold| D[Verification step] C -->|fails| F([Failure node]) D -->|score ≥ threshold| S([Success node]) D -->|fails| F C -.optional.-> D ``` A typical auth flow has two steps. The distinction is easiest to see in terms of where the conversation originates: - **Identification** — *who do you claim to be?* Used when the conversation is **inbound** and you don't yet know who you're talking to — or whether they're a real customer at all. The user supplies an identifier (an SSN, an account number, a tax ID) that the agent can use to look the rest of them up. - **Verification** — *prove that you are who we think you are.* Used when you already know who the user should be. Either the conversation is **outbound** (the agent proactively reached out to a known customer), or identification just resolved them against a record. The user supplies a second piece of information (date of birth, last 4 of card, an OTP) that you compare against the record on file. Either step is optional, but at least one must be enabled. The shape of your flow follows from where the conversation comes from: - **Inbound** (most common) — both steps. Identification first, then verification. - **Outbound** — verification only. You already know who you called; you just need to confirm it's actually them. Both steps pass → the conversation jumps to the **Trigger node on success** you chose. Either step fails → the conversation jumps to the **Trigger node on failure** (typically a handover or a graceful decline). ## What you'll configure You add Authentication from the **subagents** group of the Toolkit in the dialog builder — drag the **Authentication** action into a node. The action card renders the whole flow inline; clicking any part of it opens the matching configuration panel. | In the builder | What it controls | | --- | --- | | **Where you place the action** | When the auth flow starts — it runs when the conversation reaches the node containing the action. For session-start auth, pair it with the [**Conversation start** setting](../ai-agents/setup.md#conversation-start). | | **Identify the user** step | The first step. Asks the user to claim an identity. Optional. | | **Verify the user** step | The second step. Confirms the identity against your records. Optional. | | **Trigger node on success** | The dialog node the conversation jumps to once auth passes. | | **Trigger node on failure** | The dialog node the conversation jumps to once auth fails. | Each step has its own panels: | In the builder | What it controls | | --- | --- | | Step toggle on the step card | Enables the step. | | **Add question** / **Choose from a template** | Up to 10 questions per step. Each one has its own answer type, weight, and validation method. | | **Successful identification/verification** panel → *Score threshold* | Total points needed for the step to pass. See [Scoring](./authentication-scoring.md). | | **Guidelines** drawer | Free-text instructions to the agent — your tone, your scripted greeting, your offered alternatives. See [Guidelines](./authentication-guidelines.md). | | **Failed identification/verification** panel | Three independent toggles: *Incorrect responses*, *Guideline-based*, *Authentication timeout*. | | **Verify the user** step → *Pre-enter webhook* | Optional. Runs a webhook just before verification starts, to fetch ground truth. See [Webhooks](./authentication-webhooks.md). | For a click-by-click setup walkthrough see [Set up Authentication](./authentication-setup.md). ## Running Authentication at the start of the session Most authentication use cases need the flow to run **before anything else** — the user must not reach any other part of the workflow unauthenticated. Since Authentication is an action inside a node, you get this with the [**Conversation start** setting](../ai-agents/setup.md#conversation-start): 1. Create a dialog node and drop the **Authentication** action into it. 2. In the AI Agent's **Settings**, set **When a conversation starts, trigger:** to that node. Every conversation now opens with the auth flow — the Authentication Agent generates the first message itself, shaped by your step [guideline](./authentication-guidelines.md). ## How Authentication changes the message path While the auth flow is in progress, the Authentication Agent owns the conversation: each user message goes to it — not to intent classification — until the flow ends in success or failure. Then the conversation continues from the configured success or failure node, where the rest of your workflow takes over. :::note One run per session The outcome is remembered for the rest of the session. If the conversation reaches an Authentication action again after the user has already passed, the flow does not re-run — the conversation routes straight to the success node (or to the failure node, if the user had failed). ::: See [How messages flow](../ai-agents/message-path.md) for the wider picture. ## What the Authentication Agent can see The Authentication Agent has **limited context by design** — the central safety property of Authentication. | Visible to the Authentication Agent | Hidden from the Authentication Agent | | --- | --- | | Question text | Expected answers / ground-truth values | | Question type (date, number, etc.) | Validation method on each question (exact match, fuzzy match, webhook, …) | | Your step guideline + failure guideline | Point values, score threshold, and number of failed attempts | | The conversation so far | Webhook URLs, tokens, headers | | User's display name (if available from the channel) | Other workflows / dialogs in the AI Agent | Validation happens **server-side**. The Authentication Agent submits a candidate answer for validation and learns only whether it was accepted — never *why*, never the expected value, never how close it was. Even if the Authentication Agent is prompt-injected, it has no secrets to leak. ## Where to next - [Set up Authentication](./authentication-setup.md) — step-by-step UI walkthrough. - [Conversation start](../ai-agents/setup.md#conversation-start) — trigger the auth node at the start of every conversation. - [Scoring and alternative scenarios](./authentication-scoring.md) — design "any two of three", "strong-or-two-weaker", etc. - [Guidelines](./authentication-guidelines.md) — scripted greetings, escalation, channel awareness. - [Webhooks](./authentication-webhooks.md) — pre-enter and per-question validation webhooks, with a worked CRM-backed two-step recipe. --- ## Scoring and alternative scenarios Authentication uses a simple per-step scoring model: every question has a **point weight**, the step has a **score threshold**, and the step passes when the user's accumulated points meet the threshold. The clever uses come from how you combine weights, threshold, and the step's [guideline](./authentication-guidelines.md) — that combination is how you design "any two of three", "strong-or-two-weaker", or "all required" flows. ## Per-question points Every question has a weight between **1 and 5** (default: 1). When the user gives an answer that the configured validation method accepts, the question's points are added to the step's running score. A question can be accepted at most once per step. You set this on each question with the **Assign a weight for this question** control: > *Set how many points this specific question contributes toward the total success score.* ## Score threshold On each step's **Successful identification** (or **Successful verification**) panel, the **Score threshold** is the minimum total points the user needs to pass: > *The minimum total points from correct answers needed to pass this step.* If the threshold is higher than the sum of all weights on the step, the panel shows a warning — *"Threshold exceeds the total available points."* — meaning the step would be impossible to pass. Adjust either the weights or the threshold. ## Designing alternative scenarios This is where scoring earns its keep. :::tip Scoring is the gate; the guideline is how the agent offers the choice. The auth LLM **does not see** point values or thresholds — it only sees the questions and the step guideline you wrote. To make an alternative scenario real, you have to do two things: 1. Configure points + threshold so the math allows the alternative. 2. Describe the alternative *in plain language* in the step guideline so the agent knows to offer it. Without the guideline, the agent will just ask the questions in order and never offer the alternative. Without the math, the agent's offer would be a lie — the user would think they'd passed and the step wouldn't actually advance. ::: Three worked examples: ### Strict identification — "all required" | Question | Points | | --- | --- | | Full tax ID | 1 | | Date of birth | 1 | | Registered phone number | 1 | **Threshold:** 3 (all three required). **Step guideline:** > *Ask the user for their full tax ID, their date of birth, and their registered phone number. All three are required.* The agent will ask all three and only pass when all three are accepted. ### Pick any two — "user's choice" | Question | Points | | --- | --- | | Full tax ID | 1 | | Date of birth | 1 | | Registered phone number | 1 | **Threshold:** 2. **Step guideline:** > *Ask the user to confirm any two of the following: their full tax ID, their date of birth, or their registered phone number. The user can choose which two to provide.* The agent will keep accepting answers until any two are correct. The user picks which two. ### Strong or two weaker | Question | Points | | --- | --- | | Full tax ID | 2 | | Last 4 digits of tax ID | 1 | | Date of birth | 1 | **Threshold:** 2. | User provides… | Score | Passes? | | --- | --- | --- | | Full tax ID alone | 2 | Yes — 2 ≥ 2 | | Last 4 + DOB | 1 + 1 = 2 | Yes — 2 ≥ 2 | | Last 4 alone | 1 | No — 1 < 2 | | DOB alone | 1 | No — 1 < 2 | **Step guideline:** > *Ask the user for their full tax ID. If they don't have it on hand, accept the last 4 digits of their tax ID together with their date of birth as an alternative.* This is the canonical "strong primary identifier with a fallback path" shape. :::note If the agent isn't behaving as expected Nine times out of ten the issue is the **guideline**, not the scoring. If you set a threshold of 2 but never described the alternative in the guideline, the agent will just walk through all three questions in order. Adjust the wording in the guideline first. ::: ## How a step fails A step has three independent terminal failure conditions. Any one of them ends the step with failure and routes the conversation to the failure node. | Condition | Where you set it | Default when enabled | | --- | --- | --- | | **Max failed attempts** | Failure panel → *Incorrect responses* | 3 | | **Step timeout** | Failure panel → *Authentication timeout* | 5 minutes | | **Failure guideline** | Failure panel → *Guideline-based* | — (free text) | The failure guideline is the most flexible of the three: it's a free-text description of when the step should be considered failed. The agent reads it, watches the conversation, and exits with failure when it judges the condition is met. A common pattern is to use the failure guideline as an **escalation hook**: > *The user asks to speak to a human, or explicitly refuses to authenticate.* When detected, the conversation routes immediately to a handover node, instead of forcing the user to fail attempts until they hit the max-attempts limit. See [Failure guideline as an exit condition](./authentication-guidelines.md#failure-guideline-as-an-exit-condition). ## What happens after success and failure Once a step reaches its threshold (success) or fires one of the failure conditions (failure): - **Success on the last enabled step** → the conversation continues from the **Trigger node on success** you configured. - **Success on identification when verification is also enabled** → the agent moves to the verification step. - **Failure on any step** → the conversation continues from the **Trigger node on failure** you configured. The two node selectors appear on the success and failure panels of the **last enabled step** (verification if it's on, otherwise identification). ## Where to next - [Guidelines](./authentication-guidelines.md) — how to write the step guideline and the failure guideline. - [Webhooks](./authentication-webhooks.md) — validation webhooks and pre-enter webhooks for fetching ground truth. --- ## Set up Authentication This page walks through the **Authentication** action in the dialog builder, panel by panel. By the end you will have a working two-step auth flow that runs at the start of every conversation on a test AI Agent. For a worked end-to-end example showing how scoring, guidelines, and webhooks fit together, see [the CRM-backed two-step recipe](./authentication-webhooks.md#putting-it-together-a-crm-backed-two-step-setup). ## 1. Add the Authentication action to a node Open a dialog in your AI Agent (**Workflows** → **Dialogs**). In the **Toolkit** on the right, find the **subagents** group and drag **Authentication** into the node where you want the auth flow to run. Where you place it is when it runs: the flow starts when the conversation reaches that node. To run it at the start of every session — the most common setup — see [step 9](#9-run-it-at-the-start-of-the-conversation). ## 2. The action card at a glance The action card shows the whole auth flow inline: the **Identify the user** and **Verify the user** steps, each with its success and failure outcomes. Click any part of the card to open its configuration panel on the right. The rest of this walkthrough goes panel by panel. ## 3. Enable the identification step The identification step asks the user to **claim** an identity ("what is your account number?"). It's the natural starting point for **inbound** conversations, where you don't yet know who's on the line. For outbound conversations — where the agent proactively reached out to a known customer — skip identification and use only verification (step 7). For more on the distinction see [the mental model](./authentication-overview.md#the-mental-model). Toggle the **Identify the user** card on. Its panel opens with an empty state and two ways to add questions: - **Choose from a template** — pre-built questions from three categories (Primary identifiers, Contact verification, Account & Transactional KBA). - **Add first question** — start from scratch. ## 4. Configure a question Each question expands into a form with up to seven fields. Some fields are conditional on the validation method. | Field | Purpose | | --- | --- | | **Question** | The text the agent will ask the user. Required, max 256 chars. | | **Answer type** | One of `Text`, `Date`, `Integer`, `Number`, `Phone`, `Alphanumeric`. Affects how the agent extracts the value. | | **Save correct answer as** | The context variable to store the accepted answer in (e.g. `$ssn`). Must start with a letter or underscore. | | **Assign a weight for this question** | 1–5 points. Defaults to 1. See [Scoring](./authentication-scoring.md). | | **Validate answer via** | How to check the answer. Three subgroups: Operator, Guideline, Webhook. | | **Ground truth** *(conditional)* | The variable holding the right answer (for `Exact match`, `Fuzzy match`, `Contains`, `Starts with`, `Ends with`). | | **Fuzzy match threshold** *(conditional)* | 0–100 similarity score. Defaults to 90. | | **Validation guideline** *(conditional)* | Free-text rule shown only when *Validate answer via* is set to **Guideline**. | ### Validation methods - **Operator** — server-side string comparison against a context variable: `Exact match`, `Fuzzy match`, `Contains`, `Starts with`, `Ends with`. - **Guideline** — a free-text instruction that's used to judge the answer (e.g. *"Accept if the user gives any valid US ZIP code."*). - **Webhook** — calls a webhook of type `auth_validation` configured on this AI Agent. Only validation-typed webhooks are listed in the dropdown. See [Webhooks](./authentication-webhooks.md). ### Max ten questions per step The **Add another question** button is disabled at ten questions per step. If you need more degrees of identification, split the work across the identification and verification steps. ## 5. Score threshold (success panel) Click the **Successful identification** box on the action card to open the success panel. The **Score threshold** is the minimum total points needed for the step to pass: > *The minimum total points from correct answers needed to pass this step.* If your questions sum to 4 points and you set the threshold to 5, you'll see a warning: *"Threshold exceeds the total available points."* — the step would never be able to pass. Adjust either the question weights or the threshold. Threshold and weights together give you alternative-scenario design. See [Scoring](./authentication-scoring.md). ## 6. Failure conditions Click the **Failed identification** box to open the failure panel. Three independent failure conditions: - **Incorrect responses** — *"End the authentication flow if the user provides the wrong information too many times."* Defaults to 3 attempts when enabled. - **Guideline-based** — *"Describe the failure conditions"* in free text. The agent will exit the step with failure if the condition is met (e.g. *"The user asks to speak to a human."*). See [Guidelines as exit conditions](./authentication-guidelines.md#failure-guideline-as-an-exit-condition). - **Authentication timeout** — caps the wall-clock time the user has to complete the step. Defaults to 5 minutes; options are 1, 3, 5, 10, 15, 30, or 60 minutes. Any one of the three firing routes the conversation to the failure node. ## 7. Enable the verification step (optional) The verification step asks the user to **prove** an identity you already think you know — either because identification just resolved them against a record, or because the conversation is outbound and you contacted a specific customer. It has the same shape as identification, with one extra control at the top: a **Pre-enter webhook** dropdown. The tooltip explains it: > *Runs just before the verification step starts. Use this to fetch the ground truth data needed to validate the user's answers.* A common pattern: identification asks for an SSN, validated via webhook against your CRM; once identification passes, the pre-enter webhook fetches the matching name and date of birth into the conversation context; verification then asks for those and validates them with **Exact match** / **Fuzzy match** against the freshly populated context variables. The pre-enter webhook only exists on the verification step. The dropdown only lists webhooks of type `auth_pre_enter` — create one in **Workflows → Webhooks** under the *Authentication webhooks* group. See [Webhooks](./authentication-webhooks.md#pre-enter-webhook-contract). ## 8. Trigger node on success / failure On the **last enabled step** (identification if you didn't enable verification; otherwise verification), the success and failure panels each include a node selector. - **Trigger node on success** — *"When authentication succeeds, the conversation will continue to this node."* - **Trigger node on failure** — *"When authentication fails, the conversation will continue to this node."* Both fields autocomplete against the dialog nodes in your AI Agent. Common patterns: - Success → a dialog node that greets the now-verified user by name and proceeds with the actual task. - Failure → a handover node that escalates to a human, or a graceful-decline dialog. ## 9. Run it at the start of the conversation Most use cases need authentication to be the very first thing in the session. In the AI Agent's **Settings**, set [**When a conversation starts, trigger:**](../ai-agents/setup.md#conversation-start) to the node containing your Authentication action. Every conversation now opens with the auth flow — the Authentication Agent generates the first message itself, shaped by your step guideline (step 10). ## 10. Guidelines Below each step's question list there's a small **Guidelines** link. Click it to open the guidelines drawer. The drawer header reads **Authentication Guidelines**, with the description: > *Configure how the agent should handle common objections and respond during authentication.* The editor supports: - `/` for commands (lists, headings, etc.) - The dollar prefix (e.g. `$user.name`) for context variables This is where you script the greeting, define alternative scenarios in natural language, and tell the agent how to handle common objections. See [Guidelines](./authentication-guidelines.md). ## 11. Test in Try It Open the **Try It** panel and start a conversation. While auth is running, an Authentication card appears in the panel showing the current step, status, score, attempts, and the list of variables successfully extracted. You can deep-link from the Try It panel back to a specific question in the configuration to inspect or fix it. --- ## Authentication webhooks Authentication uses webhooks for two distinct roles. Each role has its own dedicated webhook type — **Authentication pre-enter** and **Authentication validation** — that you pick in the wizard when creating the webhook. The Authentication setup dropdowns only list webhooks of the matching type, so you can't accidentally point a dialog-action webhook at an auth slot. | Role | Webhook type | Where you select it in the console | When it fires | What it returns | | --- | --- | --- | --- | --- | | **Pre-enter webhook** | `auth_pre_enter` | On the **Verify the user** step, the *Pre-enter webhook* dropdown | Once, when entering the verification step | Context updates to use as ground truth | | **Validation webhook** | `auth_validation` | On any question, by setting *Validate answer via* to **Webhook** | Every time the agent submits a candidate answer for that question | A boolean accept / reject | Pre-enter and validation are independent — you can use either, both, or neither. The most common production setup uses both: a validation webhook gates identification, then a pre-enter webhook fetches CRM data so verification can validate against it. You can create as many `auth_validation` and `auth_pre_enter` webhooks per AI Agent as you need — typically one validation webhook per question, and one pre-enter webhook for the verification step. :::note Shared webhook plumbing The HTTPS request shape, signature verification, custom headers, retries, and fail-on-error semantics work exactly like other Moveo webhooks. This page documents the **auth-specific** request and response bodies. For everything else, see [Build a webhook](../ai-agents/build-a-webhook.md) and [Webhooks](../ai-agents/webhooks.md). ::: ## Pre-enter webhook contract Available **only on the verification step**. The Pre-enter webhook lets you fetch data once — typically from your CRM — so the verification questions can validate against it. ### When it fires Once, on the first turn after the verification step is entered. It does not re-fire on subsequent turns within the same step. If the pre-enter webhook fails (timeout, non-2xx response, malformed body), the auth flow exits with a system failure and routes to the configured failure node — the verification step never starts. ### Request `POST` with JSON body: ```json { "request_id": "uuid", "session_id": "uuid", "context": { "/* all current context vars */": "..." } } ``` `context` is the full set of variables collected so far, including any captured during identification (e.g. `$ssn`, `$account_number`). ### Response ```json { "output": { "name": "Maria Papadopoulou", "dob": "1980-04-12" } } ``` Every key/value in `output` is merged into the conversation context. The returned variables become available as `$name`, `$dob`, etc. — and can be referenced as the **Ground truth** for the verification questions (e.g. *"Validate answer via Fuzzy match against `$name`"*). ### Example A pre-enter webhook that looks up a CRM record by SSN and returns the matching `name` and `dob`. The example below uses Next.js App Router and Zod; the same pattern applies to any HTTP framework. ```ts title="app/api/fetch-crm-data/route.ts" const bodySchema = z.object({ request_id: z.string().optional(), session_id: z.string().optional(), context: z.object({ ssn: z.string().min(1, 'context.ssn is required'), }), }); export const POST = async (req: Request): Promise => { const body = bodySchema.parse(await req.json()); // Look up the CRM record by SSN. Replace with your own data source. const row = await lookupCrmRow(body.context.ssn); return NextResponse.json({ output: row }); // row shape: { name: string, dob: string } | null }; ``` ```py title="fetch_crm_data.py" from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Context(BaseModel): ssn: str class Body(BaseModel): request_id: str | None = None session_id: str | None = None context: Context @app.post("/api/fetch-crm-data") async def fetch_crm_data(body: Body) -> dict: row = lookup_crm_row(body.context.ssn) # -> {"name": str, "dob": str} | None return {"output": row} ``` If the SSN doesn't resolve to a CRM record, return `{ "output": null }` (or omit the ground-truth keys). The verification step will then fail every question that depends on them. ## Validation webhook contract Available **per question** when you set *Validate answer via* to **Webhook**. Use it when the right-answer check can't be expressed as a string operator against a context variable. ### When it fires Every time the agent submits a candidate answer for the question. The same webhook may be called multiple times in one step (if the user gives a wrong answer and tries again, that's a new call) and across both steps if you configure validation webhooks on both. ### Request `POST` with JSON body: ```json { "request_id": "uuid", "session_id": "uuid", "value": "123-45-6789", "context": { "/* all current context vars */": "..." } } ``` - `value` is the candidate answer extracted by the agent — already normalized to the question's `type` (e.g. for a `date` question, an ISO-formatted string). - `context` is the full set of variables collected so far. Use this if the validation depends on more than just the candidate value (e.g. validating an OTP against a previously sent one stored in `$otp_token`). ### Response ```json { "valid": true } ``` …or `{ "valid": false }`. There is no third state; missing or malformed `valid` is treated as a system error. The Authentication Agent learns only the boolean. It does not learn *why* an answer was rejected. This is intentional — see [What the Authentication Agent can see](./authentication-overview.md#what-the-authentication-agent-can-see). ### Example A validation webhook that checks whether the SSN the user provided exists in a Google Sheet. ```ts title="app/api/identify-ssn/route.ts" const bodySchema = z.object({ value: z.string().min(1, 'value is required'), request_id: z.string().optional(), session_id: z.string().optional(), context: z.record(z.string(), z.unknown()).optional(), }); export const POST = async (req: Request): Promise => { const { value } = bodySchema.parse(await req.json()); // Replace with your own check against your source of truth. const valid = await ssnExists(value); return NextResponse.json({ valid }); }; ``` ```py title="identify_ssn.py" from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Body(BaseModel): value: str request_id: str | None = None session_id: str | None = None context: dict | None = None @app.post("/api/identify-ssn") async def identify_ssn(body: Body) -> dict: valid = ssn_exists(body.value) # -> bool return {"valid": valid} ``` ## Signature verification Authentication webhooks use the **same HMAC-SHA256 signature scheme** as every other Moveo webhook. The signature is in the `X-Moveo-Signature` header; the secret is the verification token you configured on the webhook in the UI. See [Build a webhook → Verify the signature](../ai-agents/build-a-webhook.md#verify-the-signature) for the full pattern with Node.js and Python examples. :::caution The examples on this page skip signature verification The minimal examples on this page omit signature verification for brevity. **Production webhooks must always verify the signature** to confirm the request actually came from Moveo and wasn't tampered with. ::: ## Creating an authentication webhook Open the AI Agent → **Workflows** → **Webhooks** → **+ Create webhook**. The type selector groups webhooks into three categories — pick from the **Authentication webhooks** group: - **Authentication validation** — validates a user's answer to an authentication question. - **Authentication pre-enter** — runs before an authentication step to fetch ground truth values. Then fill in the standard webhook form (name, URL, verification token, optional custom headers — see [Webhooks](../ai-agents/webhooks.md)). The wizard's Test panel shows the expected response shape for the type you picked, so you can build your endpoint against the right contract from the start. ## Selecting a webhook in the console Once you've created the webhook, it becomes selectable on the **Authentication action** in exactly one place, determined by its type: - **Validation webhooks** (`auth_validation`) — appear on each question, when *Validate answer via* is set to **Webhook**. - **Pre-enter webhooks** (`auth_pre_enter`) — appear in the *Pre-enter webhook* dropdown on the **Verify the user** step. The dropdowns are strictly filtered: only webhooks of the matching type are listed. Dialog-action webhooks and event webhooks (first/pre/post message) are never offered for auth slots. ## Deploying your webhook Both webhooks just need a public HTTPS endpoint. The platform you deploy on is up to you — Vercel, Cloudflare Workers, AWS Lambda behind API Gateway, or your own infrastructure all work. The only constraint is that the endpoint must be reachable from Moveo's servers and respond within the webhook timeout. A typical workflow: 1. Implement and deploy the endpoint. 2. In the webhook wizard, pick **Authentication validation** or **Authentication pre-enter** under the *Authentication webhooks* group, then fill in URL, verification token, and any custom headers — see [Webhooks](../ai-agents/webhooks.md). 3. Select it on the **Authentication action**: on a question for a validation webhook, or on the verification step's *Pre-enter webhook* dropdown for a pre-enter webhook. Each dropdown is filtered to its matching type. 4. Test end-to-end in the Try It panel. ## Type reference Copy-paste-ready TypeScript types. ```ts title="auth-webhooks.types.ts" // Pre-enter webhook export type AuthPreEnterRequest = { request_id: string; session_id: string; context: Record; }; export type AuthPreEnterResponse = { output: Record | null; }; // Validation webhook export type AuthValidationRequest = { request_id: string; session_id: string; value: string; context: Record; }; export type AuthValidationResponse = { valid: boolean; }; ``` ## Putting it together: a CRM-backed two-step setup The canonical real-world setup. Use this when your identifying credential (an SSN, a passport number) lives in a CRM and the rest of the user's record needs to come from the same source. **On the AI Agent's Webhooks page**, configure two webhooks: | Webhook | Type | Role | Returns | | --- | --- | --- | --- | | **Identify SSN** | `auth_validation` | Validation webhook for the identification question | `{ "valid": true }` or `{ "valid": false }` | | **Fetch CRM data** | `auth_pre_enter` | Pre-enter webhook for the verification step | `{ "output": { "name": "...", "dob": "..." } }` | **On the Authentication action** (in a dialog node — see [Setup](./authentication-setup.md)), configure both steps: - **Identify the user** — enabled. - One question: *"What is your Social Security number?"* (**Number**, weighted 1, saved as `ssn`). - *Validate answer via* → **Webhook** → **Identify SSN**. - *Score threshold* on **Successful identification**: 1. - The **Guidelines** drawer carries the persona and compliance disclaimer the Authentication Agent will deliver on its first turn (the Authentication Agent owns the first turn — see [Guidelines → Scripted greeting](./authentication-guidelines.md#scripted-greeting-via-the-step-guideline)). The drawer also tells the user explicitly that they can ask to speak to a human at any time. - On **Failed identification**, enable *Guideline-based* with the exit condition *"The user asks to speak to a human."* — that catches the affordance you just promised. - Enable *Incorrect responses* (max 2) and *Authentication timeout* (5 minutes) as belt-and-braces. - **Verify the user** — enabled. - *Pre-enter webhook* → **Fetch CRM data**. - Two questions: - *"What is your full legal name?"* — **Text**, *Validate answer via* **Fuzzy match** against `$name`, threshold 95. - *"What is your date of birth?"* — **Date**, *Validate answer via* **Exact match** against `$dob`. - *Score threshold* on **Successful verification**: 2 (both required). - **Trigger node on success** → a verified-customer dialog that picks up `$name` in its greeting. - **Trigger node on failure** → a handover dialog. **In the AI Agent's Settings**, under [Conversation start](../ai-agents/setup.md#conversation-start), set **When a conversation starts, trigger:** to the node holding the Authentication action, so the auth flow runs before anything else in the session. ### What happens at runtime 1. The conversation starts at the auth node — regardless of the user's first message. The Authentication Agent delivers the scripted greeting from the identification guideline and asks for the SSN. 2. The user answers. The agent submits the SSN to the **Identify SSN** webhook. The webhook returns `{ "valid": true }` if the SSN exists in the CRM, otherwise `{ "valid": false }`. 3. Once identification passes, the **Fetch CRM data** pre-enter webhook fires. It looks up the user record and returns `{ "output": { "name": "...", "dob": "..." } }`. Those become available as `$name` and `$dob`. 4. Verification asks for the user's full legal name and date of birth, validating each against the freshly-loaded ground truth. 5. Both accepted → the success node fires, and the next dialog can greet the user by `$name`. 6. At any point during identification, if the user says *"speak to a human"* (or similar), the failure guideline fires and the conversation routes immediately to the handover dialog — no need to burn through attempts. Both webhooks can be backed by anything that exposes the data — a CRM API, a Google Sheet with `name`, `ssn`, `dob` columns, an internal microservice. The contract the brain cares about is just the JSON shapes documented above. ## Where to next - [Build a webhook](../ai-agents/build-a-webhook.md) — generic signature verification, body validation, type reference. - [Webhooks](../ai-agents/webhooks.md) — configuring URL, verification token, and custom headers on the AI Agent. --- ## Campaigns ## Overview Campaigns reach your audience across multiple channels and route every reply to an [AI Agent](../ai-agents/overview.md). Upload a contact list, define how the agent engages each person, then track results from one place. Moveo offers two campaign types. Both share the same foundation — an audience, an AI Agent, and multi-channel messaging — but serve different goals. ## Campaign types ### Outreach Proactive engagement for marketing and lifecycle messaging, such as promotions, reminders, and re-engagement. An outreach campaign sends a primary message, retries with a fallback if delivery fails, and follows up when a contact stays silent. See [Outreach campaigns](./outreach.md). ### Payment recovery Regulated debt collection that contacts people with overdue balances and works toward a resolution, such as a promise to pay or a completed payment. Payment recovery captures debt details per contact and, with autonomous actions, runs under a compliance profile. See [Payment recovery campaigns](./payment-recovery.md). ## How a campaign works Every campaign shares the same building blocks, regardless of type: - **Audience** — Upload a CSV of contacts. The platform previews each row and flags issues, such as missing contact details or duplicates. - **AI Agent** — Choose the [AI Agent](../ai-agents/overview.md) that handles replies. The dropdown lists the latest published versions. - **Tags** — The campaign name generates a matching tag for filtering conversations. Add more tags for reporting or routing. - **Message journey** — Define how contacts are reached, either as a fixed sequence or with [autonomous actions](#autonomous-actions). - **Scheduling** — Send immediately or schedule a future launch with date, time, and timezone. - **Tracking** — Follow campaign status, subscriber activity, and message logs after launch. ## Autonomous actions Autonomous actions let the AI Agent decide the best next action for each contact, instead of following a fixed message sequence. When enabled, the campaign becomes *agentic*: the agent chooses the channel, message, and timing per person to work toward a goal you define. Autonomous actions is a capability you turn on during campaign setup, under the **AI capabilities** section. It applies to both campaign types. ### Standard versus autonomous | Aspect | Standard campaign | Autonomous actions | | ------------ | ----------------------------------- | -------------------------------- | | Message flow | Fixed: primary, fallback, follow-up | Chosen per contact by the agent | | Channel | Set per step | Selected by the agent | | Timing | Fixed delays | Adapts to contact behavior | | Goal | Not required | Required | ### Setting a goal When autonomous actions is on, a **Goal** is required. It defines what a successful conversation achieves. How you set it depends on the campaign type: - **Outreach** — Enter the goal as free text, such as booking a demo or confirming an appointment. - **Payment recovery** — Select a goal from the dropdown, such as securing a promise to pay or completing a payment. A [compliance profile](#compliance-profiles) is also required. :::note The goal guides the agent's decisions for every contact. Keep it to a single, measurable outcome. ::: ### Availability Autonomous actions is rolling out gradually. If you do not see the **AI capabilities** section in campaign setup, contact your account manager or [support](mailto:support@moveo.ai). ## Compliance profiles A compliance profile is part of the autonomous agent. When you enable [autonomous actions](#autonomous-actions) on a payment recovery campaign, you select a compliance profile that applies protections respecting legal restrictions, such as quiet hours, frequency caps, and stop-contact requests. Outreach campaigns do not use compliance profiles. See [Compliance profiles](../ai-agents/compliance-profiles.md) for the available profiles and the rules each one enforces. ## Choose a campaign type - Reach your audience with marketing or lifecycle messaging → [Outreach campaigns](./outreach.md) - Recover overdue payments under regulatory rules → [Payment recovery campaigns](./payment-recovery.md) --- ## Outreach campaigns ## Overview An outreach campaign proactively reaches your audience for marketing and lifecycle messaging, such as promotions, reminders, and re-engagement. It is one of two campaign types, alongside [Payment recovery](./payment-recovery.md). For shared concepts, see the [Campaigns overview](./campaigns.md). Upload an audience list, define the messages each person receives, and configure fallback behavior for failed deliveries or silent contacts. Every campaign tags its conversations and routes replies to your selected [AI Agent](../ai-agents/overview.md). ## Before you start - Prepare a CSV file with at least one `phone` or `email` column. Add extra columns (such as `name`, `plan`, or `appointment_date`) to personalize messages. - Confirm that your integrations are connected and active: [WhatsApp](../integrations/whatsapp.md), [Infobip SMS](../integrations/infobip-sms.md), [Telnyx Voice](../integrations/telnyx-voice.md), [Twilio Voice](../integrations/twilio-voice.md), or email. - Choose which [AI Agent](../ai-agents/overview.md) handles replies. You select it during setup. ## Step 1 - Set up the campaign 1. Go to **Campaigns** and click **+ Create**. 2. Select **Outreach** as the campaign type. 3. Enter the campaign name. The system generates a matching tag from this name for filtering conversations. Add additional tags for reporting or routing as needed. 4. Pick the [AI Agent](../ai-agents/overview.md) that manages replies. The dropdown lists the latest published versions. 5. Upload your CSV or use **Quick add** to create contacts manually. - To see the expected format, click **Download sample file** for a ready-made template. - The table previews every row and highlights issues (missing phones, emails, or duplicates). - Fix or remove flagged rows, then re-upload so the audience shows only valid recipients. 6. Review the audience summary panel to confirm contact count, available phones and emails, and reusable custom fields. ### Turn on autonomous actions (optional) Under **AI capabilities**, turn on **Autonomous actions** to let the agent decide the best next action for each contact. When enabled, a **Goal** is required — for outreach, enter it as free text, such as booking a demo. The agent then composes and sequences messages toward that goal instead of following the fixed journey below. See [Autonomous actions](./campaigns.md#autonomous-actions). ### CSV format reference Each row must follow these rules: - Include at least one contact method (`phone` or `email`). Rows missing both are rejected. - Provide clean, one-value-per-cell entries. Avoid merged columns or notes inside the same field. - Keep contact identifiers unique. Remove duplicates to avoid verification errors. - Add helper columns to personalize messages. During the build step, you can insert these fields as variables. | email | phone | name | appointment_date | | ----------------- | ------------- | ----------- | ---------------- | | alex@example.com | +12025550101 | Alex Doe | 2024-09-12 | | jamie@example.net | +442071838750 | Jamie Shaw | 2024-09-13 | | priya@example.in | +122233344555 | Priya Singh | 2024-09-15 | After the upload, the audience table flags rows that fail validation so you can correct them before moving on. ## Step 2 - Build the message journey The builder walks you through three stages: the starting message, fallback options for failed deliveries, and follow-up messages for silent contacts. :::note This fixed journey applies to standard outreach. With [autonomous actions](./campaigns.md#autonomous-actions) enabled, the agent decides the journey per contact instead. ::: ### Primary message 1. Choose the integration for the first message. 2. Compose your message in the editor. For **WhatsApp**, use the template placeholders and variables dropdown to fill fields with CSV data. For **Infobip SMS**, type `$` to open the variable picker and insert any column. 3. Preview the result on the right to verify formatting, variables, and branding. ### Fallback when delivery fails Toggle **Send a fallback if not delivered** to configure a backup plan: 1. Select a second integration and write the fallback message. 2. The campaign sends this fallback if the first message fails. If a contact lacks the required information (for example, no phone number for SMS), they skip that fallback and proceed to the next step. ### Follow up when there's no reply Enable **Follow up if there is no response** to nudge silent contacts: 1. Choose how long to wait. The dropdown offers day-based delays (1–7 days) to match your follow-up cadence. 2. Select the integration and compose the follow-up content, just as you did for the primary step. 3. If the contact replies at any point, the timer stops and the follow-up does not send. If no reply arrives, the message delivers once at the scheduled time. :::note Email integration is in alpha and may not appear in your account. ::: ### Tips - Switch between the primary, fallback, and follow-up sections to preview the recipient's journey. - The default tag from the campaign name stays in place. Add more tags to trigger automations or segment reports. - Move backward to the setup step at any time to update the audience or replace the AI Agent before launching. ## Step 3 - Review and launch The review screen summarizes everything you configured: - **Audience**: Total contacts, available phone numbers, available emails, and a quick look at the custom fields detected in your CSV. - **Messaging flow**: A snapshot of the primary message, any delivery fallback, and the no-reply follow-up so you can double-check tone and sequencing. - **Automation settings**: The [AI Agent](../ai-agents/overview.md) handling replies and the tags applied to resulting conversations. - **Scheduling**: In the **Start** dropdown, choose **Immediately** to launch as soon as you confirm, or **Schedule for later** to set a date, time, and timezone. Scheduled campaigns stay in the queue until the start time you specify. When everything looks right, click **Review and start**. A confirmation modal opens; click **Start campaign** to launch. You can also **Save and Exit** at any point; drafts remain in the Campaigns list until you return. ## How fallbacks behave - **Delivery issues**: If a primary message bounces, the campaign routes that contact to the configured fallback. Each contact tries fallbacks in order. Steps that lack required data (missing contact details) are skipped. - **No-response timers**: The platform schedules a follow-up after the primary message delivers. Replies cancel the timer. If no reply arrives before the delay ends, the follow-up sends once. - **Campaign completion**: Each contact's progress updates in real time as they finish the journey. Once all contacts complete, the campaign status changes to "Sent". ## After launch - Track campaign status from the Campaigns list. Click any campaign to open its progress view, subscriber activity, and message logs. - Use filters in the list or reporting tabs to group conversations by campaign tag. - To reuse the audience, download the CSV from the campaign or copy contacts into another workflow. - [Payment recovery campaigns](./payment-recovery.md) also get a [Performance tab](./performance.md) with recovery and call metrics. Outreach campaigns do not. ## Troubleshooting Check campaign logs for error codes when messages fail to deliver. For WhatsApp-specific errors, see the official [error codes page](https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes/). ### Common issue: Error **131026 - Message Undeliverable** Possible reasons include: - The recipient’s number is not registered on WhatsApp. - The recipient has not accepted the latest Terms of Service or Privacy Policy. - The recipient is using an outdated version of WhatsApp. - The recipient has blocked or reported your business. - Per-user marketing message limits have been reached to maintain quality. - The recipient has not come online within the 30-day offline message window. - The recipient is in a [restricted or sanctioned country](https://developers.facebook.com/docs/whatsapp/cloud-api/support/#country-restrictions). - You are sending an [authentication template](https://developers.facebook.com/docs/whatsapp/business-management-api/authentication-templates) to an Indian user (+91). ## Additional resources - [WhatsApp Cloud API Support](https://developers.facebook.com/docs/whatsapp/cloud-api/support/#message-not-delivered) - [Related Bug Report](https://developers.facebook.com/support/bugs/994815942105900/) --- ## Payment recovery campaigns ## Overview A payment recovery campaign contacts people with overdue balances and works toward a resolution, such as a promise to pay or a completed payment. It is one of two campaign types, alongside [Outreach](./outreach.md). For shared concepts, see the [Campaigns overview](./campaigns.md). Payment recovery pairs an audience of debtors with an AI Agent that follows up, sends reminders, and adapts its messaging per contact. When you enable [autonomous actions](./campaigns.md#autonomous-actions), the agent decides the best next step for each person instead of following a fixed message sequence. A [compliance profile](../ai-agents/compliance-profiles.md) keeps that contact within the rules that apply to your region. ## Key concepts - **Campaign type** — Payment recovery is a dedicated type built for regulated debt collection. It captures debt details per contact for reporting and for the AI Agent to act on. - **AI Agent** — A [Debt Collection agent](../ai-agents/overview.md) handles replies, negotiates options, and generates payment links. Build one first with the [Build your first AI Agent](../guides/build-an-ai-agent.md) guide. - **Autonomous actions** — An optional capability that lets the agent choose the channel, message, and timing for each contact. See [Autonomous actions](./campaigns.md#autonomous-actions). - **Compliance profile** — A set of protections that block or delay contact when regulations require it. You select one when autonomous actions is enabled. See [Compliance profiles](../ai-agents/compliance-profiles.md). ## Before you start - Build and publish a [Debt Collection AI Agent](../guides/build-an-ai-agent.md) to handle replies. - Confirm that your messaging [integrations](../integrations/whatsapp.md) are connected and active. - Prepare a CSV of debtors with the required debt fields. See [CSV format reference](#csv-format-reference). - If you plan to use autonomous actions, decide which [compliance profile](../ai-agents/compliance-profiles.md) applies. ## Step 1 - Set up the campaign 1. Go to **Campaigns** and click **+ Create**. 2. Select **Payment recovery** as the campaign type. 3. Enter the campaign name. The system generates a matching tag from this name for filtering conversations. Add more tags for reporting or routing as needed. 4. Upload your CSV. Click **Download sample file** to get a template with the required debt columns. The audience table previews every row and flags issues, such as missing contact details or unmapped required fields. 5. Match each CSV column to a field. The platform suggests mappings automatically; adjust any that are wrong. :::note If a required field stays unmapped, the setup step keeps the warning active until you map it. Optional fields can be skipped. ::: ### Turn on autonomous actions Under **AI capabilities**, turn on **Autonomous actions** to let the agent decide the best next action for each contact. When enabled: - A **Goal** is required. Select it from the dropdown — it defines what a successful conversation achieves, such as securing a promise to pay or completing a payment. - A **Compliance profile** is required. It applies the contact rules for your region, such as quiet hours, frequency caps, and stop-contact requests. - The agent uses next-best-action logic to pick the channel and message per contact, rather than a fixed sequence. For the full behavior and how it differs from a standard campaign, see [Autonomous actions](./campaigns.md#autonomous-actions). ## Step 2 - Build the message journey The messaging step depends on whether autonomous actions is on: - **Autonomous actions on** — Choose the channels the agent may use, then write the initial message. The **Campaign guidelines** panel lists the read-only rules that shape how the agent sequences its attempts. The agent picks the channel, message, and timing per contact, and uses only the channels that contact has. - **Autonomous actions off** — Build a fixed journey: a primary message, a fallback for failed deliveries, and a follow-up for silent contacts, as described for [Outreach campaigns](./outreach.md#step-2---build-the-message-journey). ## Step 3 - Review and launch The review screen summarizes the audience, messaging, and scheduling. The layout adapts to the campaign: - **Agentic review** — Shows the goal, the AI Agent, and the compliance profile that governs contact. - **Standard review** — Shows the primary message, delivery fallback, and no-reply follow-up. In the **Start** dropdown, choose **Immediately** to launch as soon as you confirm, or **Schedule for later** to set a date, time, and timezone. Click **Review and start** to open the confirmation modal, then **Start campaign** to launch. Click **Save and Exit** to keep the campaign as a draft. ## CSV format reference Each row represents one debtor. Map every required field during setup. The required fields do more than identify each debtor. They power payment-recovery-specific analytics, such as the total amount due across your audience. When [autonomous actions](./campaigns.md#autonomous-actions) is enabled, the AI Agent also uses the amount and currency to personalize messages and decide the next best action. The optional due date and original creditor add further context to those messages when you provide them. **Required fields** | Field | Description | | ------------------ | -------------------------------------------------------- | | Consumer full name | Full name of the debtor | | Contact | At least one of `phone` or `email` | | Amount | Outstanding balance | | Currency | Currency of the balance | | Country code | Two-letter ISO country code for the debtor, such as `US` | | Residence state | Used to apply state-level compliance rules | **Optional fields** | Field | Description | | ----------------- | ------------------------------------- | | Account ID | Unique identifier for the account | | Due date | Date the balance became due | | Original creditor | The creditor the debt originated with | :::caution Provide clean, one-value-per-cell entries and keep account identifiers unique. Rows missing both a phone and an email are rejected. ::: ## Compliance and safety When autonomous actions is enabled, a payment recovery campaign runs under a [compliance profile](../ai-agents/compliance-profiles.md) that enforces contact rules for your region, such as quiet hours, frequency caps, and stop-contact requests. During live conversations, the AI Agent applies further guardrails, such as stopping collection when a consumer disputes the debt or reports identity theft. :::warning Compliance protections take precedence over custom instructions and guidelines. Compliance profiles assist with regulatory compliance but are not a substitute for legal counsel. ::: ## After launch - Track campaign status from the Campaigns list. Open a campaign to view subscriber activity and message logs. - Read the recovery, promise, and call metrics on the [Performance tab](./performance.md). - Review blocked contacts and their reasons on the Performance tab, under **Barriers to progress**. - Filter conversations by the campaign tag for reporting. ## Related pages - [Campaign performance](./performance.md) - [Campaigns overview](./campaigns.md) - [Outreach campaigns](./outreach.md) - [Autonomous actions](./campaigns.md#autonomous-actions) - [Compliance profiles](../ai-agents/compliance-profiles.md) - [Build your first AI Agent](../guides/build-an-ai-agent.md) --- ## Campaign performance ## Overview The **Performance** tab reports how a [payment recovery campaign](./payment-recovery.md) is doing: how many people you reached, how many were verified as the debtor, how much they promised to pay, and what is holding the campaign back. For outbound voice campaigns it also shows how long the calls run. Open a campaign from the **Campaigns** list, then select **Performance**. The tab sits between **Overview** and **Conversations**. :::note Availability Only payment recovery campaigns have a Performance tab. [Outreach campaigns](./outreach.md) do not, because the metrics below are built on debts, promises to pay, and verified-debtor checks. If a payment recovery campaign has no Performance tab, the feature is not enabled for your account yet. Contact your Moveo representative. ::: Every number covers the whole campaign since it started. There is no date filter on the tab. The call duration chart is the one exception: it reaches back 189 days. A metric shows `—` when it cannot be calculated, most often because its denominator is zero. That is not the same as `0`, which means the value was measured and came out at zero. ## Campaign results Five tiles summarizing the money and the commitments. | Tile | What it counts | | ----------------------------- | ------------------------------------------------------------------------------------ | | Debt amount | Total outstanding balance across every debt linked to the campaign | | Total promised amount | Total amount promised across the campaign | | PPA | Average promised amount, across the promises that carry an amount | | PTP | People who committed to pay | | Debts with a promise to pay | Debts covered by a promise | **PTP** counts people and **Debts with a promise to pay** counts debts, so they differ whenever one person owes on more than one account. **Total promised amount** also shows the share of the total debt that has been promised, with a progress bar underneath. The bar stops at full when a campaign promises more than the debt on file, but the percentage next to it keeps climbing past 100%. Amounts use the campaign's own currency, taken from the audience you uploaded. When no currency can be found, the tile shows a bare number with the caption **campaign currency**. ## Outreach conversion A four-stage funnel, with a conversion rate on each step between stages. | Stage | What it counts | | ----------------- | ---------------------------------------------------------------------------------- | | Attempts | People the campaign tried to reach, counting sent, failed, and replied | | Responded | People who replied | | Verified debtors | People who replied and were confirmed as the debtor | | Promised | People who committed to pay | Each rate compares a stage with the one directly above it, not with **Attempts**: - **Hit rate** — Responded ÷ Attempts - **RPC rate** — Verified debtors ÷ Responded - **Conversion** — Promised ÷ Verified debtors Rates are rounded to a whole percentage. A stage counts a person once, however many messages or channels the campaign used to reach them, and a failed delivery still counts as an attempt. ## Promises over time Two running totals across the life of the campaign, one in debts and one in money. - **Cumulative PTP count** — promises to pay, adding up day by day - **Cumulative promised amount** — the money behind those promises, in the campaign currency Days with no activity are carried forward flat rather than dropping to zero. Hover any point for the exact value on that date; the axis labels round large numbers for readability. The amount chart is empty more often than the count chart, because a promise can be recorded without an amount attached. When that happens the chart is replaced by the message **No promise has an amount attached yet.** ## Barriers to progress What is stopping the campaign, split into two groups. - **Disputes** — Disputed debts, the count of debts marked as disputed, and Dispute rate, the share of verified debtors who disputed a debt. The rate is a share of verified debtors, not of everyone contacted. - **Campaign exclusions** — Stopped subscribers, the people the campaign no longer contacts. A contact is stopped by an opt-out, by a [compliance profile](../ai-agents/compliance-profiles.md) rule, or by reaching the end of their journey. ## Call duration Only outbound voice campaigns fill this chart. It covers calls on the voice channels (Twilio, Telnyx, and web voice), splits them into four fixed length ranges, and shows each range as a share of all answered calls. The card is on every payment recovery campaign, so a campaign that does not place calls shows the empty state instead. | Range | Call length | | -------- | ---------------------- | | `<30s` | Under 30 seconds | | `30–60s` | 30 seconds to 1 minute | | `1–2m` | 1 to 2 minutes | | `≥2m` | 2 minutes and over | All four ranges always appear, including any that hold no calls. A range starts at its lower bound and stops just short of the next one. A call of exactly 30 seconds is in `30–60s`, and a call of 29.9 seconds is in `<30s`. The last range starts at exactly 2 minutes, so a 2-minute call sits there. Each bar is that range's share of all answered calls, worked out on its own. The four are never adjusted to total 100. Three equal ranges come out at 33.33% each, which adds up to 99.99%. On top of that the bars round to whole numbers, so they can read 99% or 101%. A range that holds calls but less than 1% of them shows `<1%` instead of `0%`. **Answered means the other end sent something back.** It is not a confirmed pickup from the phone carrier. A call that went to voicemail counts as answered, because the AI Agent plays its opener to the machine and the recorded greeting comes back as a message. Voicemail cannot be separated out yet. Dials that rang out, failed, or were rejected are left out. Most dials on a voice campaign end that way and last under a second, so counting them would push almost the whole chart into the first range. The chart tells you how long your conversations run. It does not tell you how often people pick up. Duration runs from the start of the conversation, when the campaign places the call, to the last message in it. It stops at the last message rather than when the conversation closes, because a voice conversation stays open for minutes after the call ends and counting that wait would make every call look longer. This is Moveo's own measure and will not match a carrier's billed duration exactly. The chart reaches back 189 days, so older calls drop out. When a campaign has no answered calls yet, the chart is replaced by **No data available** and **No answered calls have been recorded for this campaign yet.** ## When numbers appear - Recovery metrics, the funnel, and the promise charts refresh within about five minutes of the underlying activity. - A call joins the duration chart only after its conversation closes, which is about ten minutes after the last message on it. Accounts set to hold conversations open for longer take more than that. - Today's chart is always incomplete while a campaign is still dialing. It keeps changing for about ten minutes after each call ends, and for the same day it will not match the voice conversation counts on the Analytics pages, which do not wait for a conversation to close. The two agree once the conversations close. If the whole tab fails to load it shows **Something went wrong** with a **Reload** button. ## Related pages - [Payment recovery campaigns](./payment-recovery.md) - [Campaigns overview](/docs/campaigns/) - [Compliance profiles](../ai-agents/compliance-profiles.md) - [Outreach campaigns](./outreach.md) --- ## Views When handling a large volume of conversations with [human agents](overview.md), you may find it helpful to use **views** to organize and filter your conversations. Views allow you to segment conversations based on specific conditions and criteria. Similar to [rule conditions](../environments/rules.md#apply-the-condition), views filter conversations by their properties. Each view is associated with a specific [environment](../environments/overview.md), meaning views created in one environment are not visible in others. ## Conditions Conditions help you filter conversations based on particular properties. Besides the standard conditions shared with [rules](../environments/rules.md#apply-the-condition), views also offer a unique condition: ### Conversation status - **Open**: Conversations that have an active session which hasn't expired. These can still be answered by a human agent. - **Closed**: Conversations that can no longer receive messages. A conversation is closed when its status is `resolved`, `expired`, or `closed by the user`. - **Missed**: A conversation is marked as missed when it's closed without receiving responses from either an [AI Agent](../ai-agents/overview.md) or a [Human Agent](human-agents.md). Typically, these conversations expire without being addressed. ## Create a view Follow these steps to create a view: 1. Navigate to **Live chat**. 2. Hover over the **Views** tab in the left sidebar. 3. Click on the **+** icon. 4. Provide a **name** and select an **emoji** for the view. 5. Choose if the view should be **public** or **private**. 6. Under the **Conditions** section, specify conditions to filter conversations. 7. Click on **Create** to finalize your new view. --- ## Departments ## Introduction Departments in your environment allow for a more structured and efficient management of conversations by categorizing teams based on their specific functions, such as Support, Sales, etc. This feature enhances the organization and allocation of conversations to the most appropriate agents, ensuring a smoother workflow and better customer service. ## Create a department To utilize departments, they must be added to your environment. This allows you to segment your teams based on their specific roles or functions. Go to your environment, then navigate to **Departments** and click on **Create department**. ### Configuration - Name - [Assignment modes](#assignment-modes) - Members ### Add agents to department Assign agents to specific departments. This ensures that agents receive conversations that are most relevant to their area of expertise. 1. Go to the department settings. 2. Select the department you want to manage. 3. Add agents to the department by selecting from your team list. ### Assignment modes Departments can operate under different assignment modes to distribute conversations among agents. These modes are designed to enhance efficiency and ensure fair distribution of workload. 1. **Manual Assignment**: Agents or supervisors manually assign conversations to specific agents within a department. 2. **Balanced Assignment**: The system automatically assigns conversations to agents based on their current workload, ensuring a balanced distribution. 3. **Round Robin**: Conversations are assigned to agents in a cyclical manner, ensuring each agent receives an equal number of conversations over time. Set a limit for how many conversations can be automatically assigned to agents by changing the default number in the [environment settings](../environments/overview.md). ## Connect the department To activate the newly created department, click **Connect**. This navigates you to the rules section. Select the rule you want to modify or create a new rule, and add the option to "Assign department". To assign the department when the AI Agent hands over a conversation, use a rule with the **After the AI agent replies** trigger and a **Tag** condition. See [Route a handover to a department](../environments/rules.md#route-a-handover-to-a-department). --- ## Human agents In Moveo, a conversation can be handled by an [AI Agent](../ai-agents/overview.md) or a human agent. When a conversation is out of scope for the AI Agent and requires human intervention, a person can step in and continue the conversation. A single Moveo account can have multiple human agents. They are users who have been [invited to the account](../platform/invitations.md) and have at least one of the following roles: - **Chat Agent** - **Chat Manager** - **Admin** - **Owner** :::warning Inviting team members to the account might incur **additional costs**. Please refer to the [pricing page](https://moveo.ai/pricing) for more information. ::: ## Conversation assignment When a conversation is assigned to a human agent, they start receiving notifications about it. On the user's side, depending on the channel, they may see a notification indicating that a human agent has joined the conversation. There are several ways a conversation can be assigned to a human agent. Below is a brief description of each method: ### 1. Sending a message If an agent sends a message in an ongoing conversation, that conversation will be assigned to the agent who sent the message—regardless of the agent currently assigned. ### 2. Reassigning a conversation Agents can manually reassign a conversation to another human agent, including themselves. ### 3. Handover action This method involves the use of [departments](./departments.md). When a [handover action](../ai-agents/operations/handover.md) is triggered in a [dialog](../ai-agents/dialogs.md), the AI Agent leaves the conversation, making it unassigned. After this, two scenarios can occur: - **No department assigned**: This is the default behavior. The conversation remains unassigned until an agent manually picks it up. - **Department assigned** ([Learn how to use departments](./departments.md)): If a department is assigned, the system will automatically assign the conversation to a **connected** human agent who belongs to **that** department. The criteria for selecting the agent depend on the [department settings](./departments.md#assignment-modes). Think of this process as the department assigning the conversation, while the handover action removes the AI Agent from it. --- ## Notes Notes let [live agents](human-agents.md) add private annotations to conversations. They are **only visible to teammates** — end users never see them. Use notes to leave context, reminders, or observations about a conversation for yourself or other agents. ## Add a note To add a note to an open conversation: 1. Click on the **Note** icon (sticky note) in the chat box toolbar. 2. The chat box switches to note mode, showing a yellow header labeled **Note · only visible to teammates**. 3. Type your note and press **Enter** or click **Add** to post it. The note editor stays open after posting, so you can write multiple notes in a row. Press **Escape** or click the **X** button in the header to exit note mode. :::note While in note mode, other toolbar actions like [quick responses](quick-responses.md), file attachments, and emoji are disabled. Exit note mode first to use these features. ::: ## Edit a note To edit a note you previously created: 1. Hover over the note in the conversation timeline. 2. Click the **edit** (pencil) icon that appears. 3. The note editor opens with the existing text. Make your changes and press **Enter** to save. Edited notes display an **(edited)** label next to the timestamp. Only the original author of a note can edit it. ## Delete a note To delete a note you previously created: 1. Hover over the note in the conversation timeline. 2. Click the **delete** (trash) icon that appears. 3. Confirm the deletion in the popover that appears. Once deleted, a note cannot be recovered. Only the original author of a note can delete it. :::note Notes support up to **2,048 characters**. Use **Shift + Enter** to add line breaks within a note. ::: --- ## Live chat overview ## Overview Live chat in Moveo creates a seamless bridge between AI automation and human expertise. When your [AI Agent](../ai-agents/overview.md) encounters complex inquiries or reaches its designed handover points, human agents can step in to provide personalized customer support while maintaining full conversation context. This unified approach ensures customers receive the best possible experience—instant AI responses for routine queries and expert human assistance for complex issues—all within a single, continuous conversation. ### Key capabilities ✅ **Unified conversation management** across all [integrated channels](../integrations/overview.md)\ ✅ **Seamless AI-to-human handover** with full context preservation\ ✅ **Department-based routing** for specialized support teams\ ✅ **Real-time collaboration tools** and productivity features\ ✅ **Queue management** with intelligent wait time estimation\ ✅ **Business hours support** with automatic scheduling --- ## Getting started ### Enable live chat Each [environment](../environments/overview.md) can have live chat enabled or disabled based on your needs: 1. Navigate to your environment settings 2. Toggle the live chat module to **Active** 3. Configure your [human agents](human-agents.md) and [departments](departments.md) ### Essential setup steps 1. **[Add human agents](human-agents.md)** - Invite team members with appropriate roles 2. **[Create departments](departments.md)** - Organize agents by function (Support, Sales, etc.) 3. **[Configure routing](routing-and-queues.md)** - Set up automatic conversation assignment 4. **[Set business hours](../environments/business-hours.md)** - Define when each department is available 5. **[Setup handover triggers](../ai-agents/operations/handover.md)** - Configure when AI escalates to humans --- ## How it works Live agents can view all ongoing conversations in a single view by clicking on the live chat icon at the top of the screen. The live chat page is divided into distinct categories on the left side of the screen: - **`My Inbox`**: Displays all conversations that you are handling. - **`All`**: Displays all conversations from all live agents or AI Agents. - **`Unassigned`**: Displays all conversations that **no** live agent has picked up. These are the conversations in which the end user is waiting for a live agent to take over. - **`Spam`**: Displays all conversations that have been flagged as spam. - **`Trash`**: Displays all conversations that have been deleted. In live chat, you can see the conversations managed by the assistant, as well as the individual conversations handled by each agent. Upon navigating there, you have the option to pin any agents and departments of your choice for easy viewing in the list. ## Actions A live agent can take the following actions: 1. Reply to a conversation after selecting it from the left side of the screen. :::note When you reply to a conversation, you automatically assign it to yourself. For example, if you send a message to a conversation that an AI Agent is handling, then the AI Agent leaves the conversation and the conversation gets assigned to you. ::: 2. Attach a file and send it in a conversation. 3. Create and edit a [quick response](quick-responses.md). 4. Add a private [note](notes.md) to a conversation, visible only to teammates. 5. Send a [template message](template-messages.md) on WhatsApp. 6. Resolve a conversation after you solve the user's request. 7. Assign the conversation to another live agent. 8. Update the user's information (name, email, address, phone number) by using the right section of the screen. 9. Tag a conversation. 10. Flag a conversation as **spam** or delete it. The following demonstration shows how a new conversation appears in **Unassigned** and how a live agent can pick up the conversation and resolve it. --- ## Quick responses '@site/src/components/Img'; Quick responses let live agents reply to users quickly without having to type messages from scratch. They are useful when you frequently need to provide the same answer or handle common questions. ## Create a new quick response To create a new quick response in an open conversation: 1. Click on the **Quick responses** icon in the bottom-left corner of the chat box. 2. Click on **+ Create new response**. 3. Customize your response. 4. Click **Save**. ## Use a quick response A live agent can type / in the chat box to search for existing quick responses. To select a quick response, navigate with the arrow keys and press **Enter**. You can also type keywords to directly locate a particular response. ## Edit a quick response To edit a quick response in an open conversation: 1. Click on the **Quick responses** icon in the bottom-left corner of the chat box. 2. Click **Edit** on the quick response you want to modify. 3. Make your changes, then save. To remove a quick response, click the delete icon 🗑️ next to it. ## Troubleshooting Below are some common questions about using quick responses: 1. **Can I use quick responses across multiple chats at the same time?**\ Yes. Quick responses are accessible in any open conversation, so they can be reused across different chats. 2. **Is there a limit to how many quick responses I can create?**\ While there’s typically no fixed limit, creating too many can make them difficult to manage. 3. **Do all agents see my quick responses, or can I keep them private?**\ This depends on your system settings. Some setups allow personal quick responses, while others share them organization-wide. 4. **Can I edit a quick response while chatting with a customer?**\ Absolutely. You can edit or delete a quick response anytime by clicking the Quick responses icon. 5. **Are changes to quick responses immediate for other agents?**\ If the quick response is shared, changes are available to all agents right after you save. 6. **Is there a faster way to insert a quick response than typing "/"?**\ Currently, typing "/" opens the selector. Check settings or documentation to see if your system offers additional shortcuts. 7. **How can I organize my quick responses so they are easier to find?**\ Use clear, descriptive labels or keywords. This makes searching for them more efficient. 8. **Can I include images or emojis in a quick response?**\ Yes, you can include these elements if your chat supports them. Make sure any images are properly hosted or referenced. 9. **Will quick responses work offline?**\ They rely on the system being online, so a stable connection is typically required for access. 10. **What if I accidentally delete a quick response?**\ Once deleted, a quick response can’t be recovered. Confirm before deleting, or maintain a backup if needed. --- ## Conversation routing and queues Moveo’s **AI Agent** handles most conversations from start to finish. When the AI Agent decides a human is the best next step, the handover—and everything around it, from queueing to assignment to wait time—is automatic and instant. Customers stay informed with clear, real-time wait time estimates throughout. ## A simple way to think about it Imagine a busy office lobby. A skilled receptionist (your AI Agent) greets each visitor, answers most questions on the spot, and only calls a colleague when needed. When a human is invited, the receptionist directs the visitor to the right department and knows in real time who is available and who has room to help. New visitors are served fairly and quickly, while those waiting see honest time estimates. That is how Moveo routes conversations—automatically and instantly. ## How queues keep things organized Most conversations are resolved by the **AI Agent**. When it chooses to involve a human, conversations don’t pile up in one place. Moveo organizes them into department queues so the right people see the right requests. **Departments act as separate queues.** For example, `Sales`, `Technical Support`, and `Billing` each have their own queue, agents, and rules. See [departments](./departments.md). Moveo assigns the right department using configurable routing rules. You define the logic once, and conversations are directed automatically based on context or an **AI Agent** handover action. See [rules](../environments/rules.md) and the [handover action](../ai-agents/operations/handover.md). **Business hours are respected.** Each department can set its own schedule. Outside of those hours, the queue pauses, customers are informed, and routing resumes automatically when the department reopens. See [business hours](../environments/business-hours.md). **Handovers are smooth.** When the **AI Agent** escalates via the [handover action](../ai-agents/operations/handover.md) or an agent transfers a conversation, it enters the correct department queue automatically. ## The smart router: how chats are assigned When a conversation is in an active queue, Moveo immediately looks for the best agent at that moment. It checks three things, in order: 1. **Right department match.** Only agents in the conversation’s department are considered. 2. **Real availability.** The system confirms an agent is truly ready: they are connected and present, their status is **Available** (not **Away** or **Busy**), and they are active at their desk. If an agent is idle for too long, Moveo can mark them **Away** to avoid routing to an empty chair. 3. **Capacity and workload.** Each agent has a maximum number of live conversations they can handle at once (commonly five). Moveo assigns new conversations only to agents who have room, which prevents overload and protects quality. ### Fair and flexible assignment strategies Different organizations prefer different ways to distribute work, and each department can choose what fits best in **Settings → Departments**: **Manual** (assigned by a user with the **Chat Manager** role; see [permissions](../platform/permissions.md)), **Round robin** (distributes evenly, like dealing cards), or **Balanced** (assigns to the available agent with the lightest workload to keep workloads even). ## What your customers see Customers always know what is happening. As soon as someone is assigned, the chat shows the agent’s name and profile, a “joined the conversation” note appears, and messages are clearly labeled. While waiting, customers see clear, real-time estimates that update automatically. If an agent signs off or becomes unavailable, the system immediately finds the next best fit or keeps the customer informed. This experience works across all channels, though the visual presentation may differ by channel, and in some cases there is no visual presentation at all. See the [integrations overview](../integrations/overview.md). :::note This screenshot is from the Web Widget. Other channels may display differently, but routing and wait time behavior are the same. ::: ## A typical customer journey 1. **Customer starts a conversation.** The **AI Agent** answers questions, collects details, and can take actions. When the best next step is a human, it sends the conversation to the right department using your routing rules and the [handover action](../ai-agents/operations/handover.md). See [rules](../environments/rules.md). 2. **Conversation enters the queue.** The correct department queue picks it up. If the department is closed, the customer sees a clear message and a time estimate for when the department reopens. 3. **The human agent department gets to work.** Moveo checks who is truly available and who has capacity. 4. **Assignment happens instantly.** The best agent is assigned. The customer sees the agent’s name and avatar; the agent sees the full history. 5. **If things change, customers stay informed.** If the assigned agent goes unavailable, Moveo re-routes or updates the wait time. 6. **Conversation completes.** Managers can review performance in analytics, including wait times and agent utilization. ## Key settings you can control - **Departments and membership:** Decide who works where and which conversations reach them. See [departments](./departments.md). - **Business hours per department:** Set working schedules and holiday closures. See [business hours](../environments/business-hours.md). - **Routing strategy:** Configure in **Settings → Departments**: **Round robin**, **Balanced**, or **Manual** (assigned by a user with the **Chat Manager** role; see [permissions](../platform/permissions.md)). - **Agent capacity:** Define how many simultaneous conversations each agent can handle (for example, `5` for a standard desk, `2` for a specialized department). - **Analytics & staffing:** Track average and peak wait times, queue length, agent utilization, and traffic patterns to improve staffing and SLAs. See [human agent effectiveness](../analytics/human-agent-effectiveness.md). --- ## Scheduled WhatsApp messages Schedule an approved WhatsApp template to send at a later time, directly from a live chat conversation. Use scheduled messages for follow-ups such as payment reminders, due-date notices, or check-ins, without returning to the conversation to send each one by hand. Scheduling reuses the same approved templates you send today. To learn how to create and send templates, see [WhatsApp template message](./template-messages). ## Requirements Scheduled messages appear in a conversation only when all of these are true: - The scheduled messages feature is enabled for your account. Contact your Moveo representative to enable it. - The conversation channel is WhatsApp. - The conversation is open (not resolved). - An approved WhatsApp template is attached, or the conversation already has pending scheduled messages. ## Schedule a message 1. Open the WhatsApp conversation you want to follow up on. 2. Attach an approved template. Click **Browse** in the banner, select the template, and fill in any parameters. The template attaches to the composer as a draft chip instead of sending. 3. Click the schedule button (the calendar-clock icon) between the microphone and **Send**. 4. Choose when to send: - **Preset** — select **In 30 minutes**, **In 1 hour**, **Tomorrow 9 AM**, or **Next Monday 9 AM**. The message is scheduled immediately. - **Custom** — select **Custom…**, then pick a date, time, and timezone. Click **Schedule message** to confirm. A confirmation appears once the message is scheduled, and the draft chip clears from the composer. :::note Scheduling window You can schedule a message between 30 seconds and 14 days from now. Times outside this range are rejected. ::: ## Timezone The custom picker uses your local timezone by default. Change it if the customer follows a different timezone. The system stores the exact fire time, so the message sends at the moment you picked regardless of who views the conversation. ## View and cancel scheduled messages A green dot on the schedule button indicates that the conversation has pending scheduled messages. Click the button and open the scheduled messages list to review them. Each card shows the template preview and the scheduled send time. To cancel a pending message, click **Cancel** on its card. Cancel a message any time before it starts sending. :::caution Messages already sending cannot be cancelled Once a scheduled message begins sending, it can no longer be cancelled. ::: ## Automatic cancellation If the customer replies before a scheduled message sends, the platform automatically cancels the pending messages for that conversation. This prevents sending a reminder to a customer who has already responded. ## Limits - Each conversation has a limit on the number of pending scheduled messages. When you reach it, cancel a pending message before scheduling another. - You cannot resolve a conversation that has pending scheduled messages. Cancel them first, or wait until they send. --- ## WhatsApp Template Message Send messages to users even after 24 hours have passed since their last message on WhatsApp. First, create and approve a template in your [WhatsApp Business](https://business.facebook.com/wa/manage/message-templates) account. Once approved, you can use it directly in the live chat. ## Create a WhatsApp template 1. Go to your WhatsApp Business account and create a new template. 2. Submit the template for approval. 3. Once approved, the template becomes available for selection in the live chat UI. ## Send a WhatsApp template in live chat 1. Open the conversation you want to continue. 2. Click on the **Browse** button in the banner. 3. Select the approved template from the list. 4. Fill in any parameters (if applicable) and click **Send**. --- ## Business hours Business hours allow you to set a specific time range during which your live chat agents are available. ## Navigate to business hours Click on the profile configuration button inside the profile's dropdown menu, choose your desired environment from the environments menu, and click on the **Business hours** tab. :::note By default, the business hours are set to Weekdays 9:00 AM - 5:00 PM. ::: ## Customize your default business hours - Navigate to the default business hours page by clicking on the button. You can change various settings, such as the timezone, frequency (every day, weekends, weekdays, or specific day), and start and end time. You can also add or remove business hours by clicking the respective buttons. ## Customize your holiday hours Add holidays to your business hours. The days registered as holidays are treated as non-business hours. 1. Click on the Holidays tab and click on the `add holidays` link. 2. Edit the name of the holiday. 3. Edit the start and end date of the holiday. 4. Add or remove holidays at will by clicking on the **+** or **-** buttons respectively. ## Add custom business hours Add custom business hours by clicking the **+ Add business hours** button. The procedure is the same as [the one for the default business hours](#customize-your-default-business-hours), with the addition of an editable name. ## Use business hours in the dialog A simple example that takes advantage of business hours is to use them in the dialog. Upon creating a new condition, you can use the business hours variable, `$sys-business`. View a simple dialog flow below. ## Use business hours in rules Business hours work inside [rules](./rules.md). Create a rule and customize it accordingly. In the following image, an example shows that if the conversation is outside the default business hours, the conversation closes immediately. --- ## Context bundles Context bundles automatically import [variables](../ai-agents/context.md) into the conversation. Access the context bundles menu by selecting an environment. ## Uses of context bundles Context bundles can be very useful in various scenarios, including but not limited to: - Different variable values for different languages - Webhook variables that can be edited at any time without intervening with code - Different information within the same AI Agent, depending on the environment ## Add a context bundle To add a context bundle, go to your environment → Context bundles → **+ Add context bundle**. Enter a name and (optionally) a description. After you create the bundle, add all variable keys and values and save. ## Upload a context bundle Upload your context bundle from a JSON file. Two methods are available: ### Import a new bundle Similar to importing an AI Agent, you can import your context bundle. Select a name, a description, and your JSON file to import your context bundle as new. ### Merge bundle Upload your bundle into an existing one to merge all variables. In case of conflicts, either keep the original variable values or replace them with the new ones. ## Use a context bundle Once you have created a context bundle, you can use it in your Agent as context variables. To do this, you first need to apply the context bundle to the conversation using a rule, and then you can use the variables in a [dialog](../ai-agents/dialogs.md). ### Apply a context bundle 1. Navigate to **Deploy → Rules**. 2. Click on **+ Add rule**. 3. Select the conditions you want to apply the context bundle to. 4. In the **Then** section, select **Apply bundle**. 5. Choose the context bundle you want to apply. 6. Depending on your conditions, you may want to assign an AI Agent too. 7. Activate the rule. 8. Save changes. ### Use the variables In a dialog, you can use the variables from the context bundle by using the `{{$global.bundle.variable_name}}` syntax. For example, if you have a variable `name` in your context bundle, you can use it in a dialog like `{{$global.bundle.name}}`. If you use the variable before applying the context bundle, it will show as `%UNKNOWN` in the conversation, just like any other variable. Every bundle has a preset property `bundle` with its name, so you can use it in your dialog as `{{$global.bundle.bundle}}`. This can be useful to differentiate between different bundles in the same dialog using [conditions](../ai-agents/operations/conditions.md). --- ## Environments A Moveo environment is like a front desk; it receives the first communication from your end user and ensures it reaches your [AI Agents](../ai-agents/overview.md). An environment manages the interfaces with various [channel integrations](../integrations/overview.md) (Web, Facebook Messenger, Viber, etc.) and connects to your AI Agents through [rules](./rules.md). In simple use cases, only one environment is sufficient. For example, you might need one assistant answering FAQs on your website or one assistant handling delivery rescheduling. However, many businesses want to handle more than one use case and hence require multiple assistants. ### Why have more than one environment? Here are some examples: - You can create one environment connected to your landing page to answer FAQs and generate new leads, and another environment connected to your customer portal to support logged-in users. - If your business operates in different markets such as the US and France, you might need to create one environment for the US market and another for the French market. - To handle more complex use cases, you can create a [production and a development environment](../guides/staging-prod-environment.md) to ensure that releases to production are well tested in the development environment first. - If you wish to use live chat and have separate customer support teams for different use cases or languages, you can create separate environments. --- ## Different language, different Agent This example uses the [Web channel](../integrations/web/getting-started.md) to collect the user's language preference and assign an [AI Agent](../ai-agents/overview.md) based on their selection. Other integrations may retrieve the language from the user's configuration settings. ### Setting up the form The first step is to collect the user's language preference. Set up a form that prompts the user to choose their preferred language before starting a conversation. This example uses two AI Agents: one for **English** and another for **Greek**. 1. Navigate to **Deploy → Integrations**. 2. Click on the **Webchat** integration. 3. Go to the **Visitor Information** section. 4. Enable **Collect data before the chat starts**. 5. Click on **+ Add Field** and select **Language** from the dropdown. 6. Add **English** and **Greek** as available language options. 7. Save your changes. ### Assigning the AI agents [Rules](./rules.md) automate actions in conversations based on predefined conditions. This section creates a rule to assign the correct AI Agent based on the user's selected language. #### Greek language rule 1. Navigate to **Deploy → Rules**. 2. Click on **+ Add Rule**. 3. Fill in the required fields and click **Create**. 4. Set the **When** condition to **A customer starts a conversation**. 5. Set the **If** condition to **Language** is **Greek**. 6. Set the **Then** condition to **Assign to Agent**, then select the **Greek** AI Agent. 7. Click **Save**. #### English language rule Follow the same steps as the Greek rule, but: - Set the **If** condition to **Language** is **English**. - Set the **Then** condition to **Assign to Agent**, then select the **English** AI Agent. :::note For the English rule, you can add an additional condition: if the language is not Greek. This ensures that conversations from users with other language settings (such as Spanish on Viber) default to the English AI Agent. ::: --- ## AI Agent routing A very useful feature of [rules](./rules.md) is the ability to perform actions after the conversation has started. This guide shows how to reassign the conversation to a different [AI Agent](../ai-agents/overview.md) using rules and [tags](../ai-agents/operations/tag.md) in a dialog. ## The plan This example continues with the agent created in [Build an AI Agent](../guides/build-an-ai-agent.md). In this example, a gym's **Upsell Agent** handles membership payments. But what happens if the user wants to change their membership plan? You create a rule that assigns the conversation to a different Agent, the **Change plan Agent**, when the user asks to change their membership plan. This Agent is of the **Customer Support** type. To accomplish this, create a new dialog in Agent 1 that triggers when the user asks to change their membership plan. This dialog uses a tag that the rule evaluates. The rule then assigns the conversation to the **Change plan Agent**. :::note To see how to create an AI Agent from scratch, take a look at [this guide](../guides/build-an-ai-agent.md). ::: ## Create the dialog A [dialog](../ai-agents/dialogs.md) is a set of messages that the AI Agent sends to the user. In this case, create a dialog in the **Upsell Agent** that triggers from an [intent](../ai-agents/intents.md) matching when the user asks to change their membership plan. ### Intent 1. Go to **AI Agents**. 2. Click on the **Upsell Agent**. 3. Go to **Conversation > Intents**. 4. Click on **Create intent**. 5. Name the intent **Change plan**. 6. Add some examples of what the user might say when they want to change their membership plan. For example: - I want to change my membership plan. - Can I change my membership plan? - How can I change my membership plan? 7. Click on **Save**. ### Dialog The key point of this dialog is the replay action. This action triggers a message on the user's behalf that the rule evaluates. This message is not visible to the user, but the rule evaluates it and shows it in the logs. 1. Go to **Conversation > Dialogs**. 2. Click on **Create dialog**. 3. Name the dialog **Change plan**. 4. Drag the **Intent** action from the right sidebar to the canvas. 5. Select the **Change plan** intent in the dropdown list. 6. Add a [text response](../ai-agents/responses/text.md) message to the dialog. For example: - Sure! I can help you with that. Let me assign you to our **Customer Support Agent**. 7. Add a [tag](../ai-agents/operations/tag.md) to the dialog. The rule evaluates this tag. For example: `change_plan`. 8. Finally, add a replay action to the dialog. ## Create the rules Now that the dialog is ready, you need a way to connect the Agent to the user. First, create a rule that assigns the conversation to the **Upsell Agent**. This rule triggers when the user starts a conversation. Then, create a second rule that assigns the conversation to the **Change plan Agent** when the tag `change_plan` is evaluated. :::warning This routing **cannot** be tested using the Agent [test](../guides/build-an-ai-agent.md#testing-the-ai-agent) feature. You must test it in a real conversation because that only works for testing the Agent functionality, not rules. ::: ### Assign to Upsell Agent 1. Go to **Deploy > Rules**. 2. Click on **+ Add rule**. 3. Fill out the form and click on **Create**. 4. Set the **When** field to **A customer starts a conversation**. 5. Set the **Then** field to **Assign to Agent** and select the **Upsell Agent**. 6. Activate the rule and click on **Save**. ### Assign to Change plan Agent Follow the same steps as the [previous rule](#assign-to-upsell-agent), but set the **If** field to **Tag** is **change_plan** and the **Then** field to **Assign to Agent** and select the **Change plan Agent**. --- ## Rules '@site/src/components/Img'; Rules let you automate actions in conversations, such as assigning the conversation to a specific AI Agent, tagging a conversation, and much more. Rules help you automate your workflows for optimum efficiency and ensure your customers get the best experience possible. An [environment](./overview.md) can have one or more rules. The following steps demonstrate rule creation: ## Customize your rule ### Create the trigger In the `When` field, set a trigger that determines when the rule executes. The available triggers are: | Trigger | When the rule runs | | ------------------------------------ | ----------------------------------------------------------------------- | | **A customer starts a conversation** | On the first message of a new conversation, before the AI Agent replies | | **A customer responds to a message** | On every customer message, before the AI Agent replies | | **After the AI agent replies** | After the AI Agent has sent its reply | The first two triggers evaluate the rule **before** the message reaches the AI Agent, so the conditions see the conversation as the message arrives. **After the AI agent replies** evaluates the rule **after** the AI Agent has answered, against the conversation state the AI Agent returned in that turn. Use this trigger when a rule needs to react to something the AI Agent did while replying, such as adding a [tag](../ai-agents/operations/tag.md) as it [hands over](../ai-agents/operations/handover.md) the conversation. A rule that runs before the reply cannot see that tag, so it never matches. See [Route a handover to a department](#route-a-handover-to-a-department) for a complete example. #### Rules that run after the AI Agent replies Keep the following in mind before you create a rule with the **After the AI agent replies** trigger, or move an existing rule to it: - **The trigger is the opt-in.** A rule runs after the reply only if it carries this trigger. An existing rule with **A customer responds to a message** does not start running after the reply. - **Replace the trigger instead of adding it.** A rule that has both **A customer responds to a message** and **After the AI agent replies** is evaluated twice in every turn, once before the reply and once after it. If the rule only routes a handover, replace its trigger. If the rule also does other things, leave it unchanged and create a separate rule with the new trigger. - **Conditions see the conversation after the handover.** When the AI Agent hands over, it has already left the conversation by the time the rule runs. A condition such as **AI agent assigned** is **known** matches before the reply but not after it. Review any **Agent assigned** and **AI agent assigned** conditions before you move a rule to this trigger. - **Actions apply to the next message, not to the reply just sent.** The customer already has the reply when the rule runs. **Assign AI Agent**, **Assign knowledge base** and **Apply bundle** change how the next customer message is handled. **Assign department** and **Close conversation** take effect immediately. - **The rule cannot undo a handover.** **Assign AI Agent** is ignored once the conversation has been handed over, so a rule with this trigger cannot return a conversation to the AI Agent after a human agent took it over. - **It runs only after an AI Agent reply.** The trigger does not fire when an agent transfers a conversation manually, when a handover is made through the API, for campaign messages, or in the AI Agent test chat and simulations. It does fire when the AI Agent sends an inactivity reminder, because the reminder is a reply. A rule that closes the conversation on this trigger also closes it after a reminder. ### Apply the condition A condition is optional. If no condition is set, it evaluates as true and triggers the action. Available conditions include: - **Availability** - Business hours - **User** - Name - Email - Phone - Language - Timezone - Country - City - Browser - Platform - **Conversation** - Channel - Message content - Tags - Customer/referral URL - Agent assigned - AI agent assigned - Integration Combine the above conditions with **and**/**or** statements. ### Then Finally, select the **actions** to be applied if the above conditions are met, such as assigning an AI Agent to answer the message, tagging the conversation, etc. List of actions: - Add [tag](../ai-agents/operations/tag.md) - Assign [AI Agent](../ai-agents/overview.md) - Assign [knowledge base](../knowledge-base/overview.md) - Close conversation - [Apply bundle](../environments/context-bundles.md) - Assign [department](../chat/departments.md) Don't forget to make your rule **active** so it starts working. See [our guides](./rules-route-agent.md) for examples of assigning different AI Agents based on [tags](./rules-route-agent.md) and [language](./rules-language.md). ## Route a handover to a department When the AI Agent hands over a conversation, it can add a tag that says which team should take it. Because the AI Agent adds the tag while it replies, the rule that reads the tag must use the **After the AI agent replies** trigger. A rule with **A customer responds to a message** runs before the reply, does not see the tag, and leaves the conversation unassigned. 1. In the dialog that hands over the conversation, add a [tag](../ai-agents/operations/tag.md) action next to the [handover](../ai-agents/operations/handover.md) action. For example: `handover-sales`. 2. Navigate to **Deploy → Rules** and click **+ Add rule**. 3. Set the **When** field to **After the AI agent replies**. 4. Set the **If** field to **Tag** is **handover-sales**. 5. Set the **Then** field to **Assign department** and select the department. For example: **Sales**. 6. Activate the rule and click **Save and close**. The rule assigns the [department](../chat/departments.md) as soon as the AI Agent hands over, and the department distributes the conversation to its agents according to its assignment method. :::warning Rules do not run in the AI Agent [test](../guides/build-an-ai-agent.md#testing-the-ai-agent) chat or in simulations. Test this routing in a real conversation. ::: ## Reorder your rules Reorder rules based on priority. Drag a rule from the icon on the very left of the tile and drop it in your desired spot. Ensure that the highest-priority rule is at the top, and the lowest priority is at the bottom. In the following image, the **English Rule** has the highest priority, so the assistant checks it first. Then, the **Greek Rule** is reordered to have a higher priority than the **Spanish Rule**. --- ## Build your first AI Agent This tutorial guides you through the process of creating, setting up, and testing a simple [AI Agent](../ai-agents/overview.md). Each section provides clear, step-by-step instructions, making it easy to follow. You’ll also find links to more detailed pages if you want to explore specific topics further. Along the way, we explain not just what to do, but why, so you can gain a solid understanding of how AI Agents work. This guide will help you build a functional AI Agent with confidence. ## Create a new AI Agent To begin, create a new AI Agent where you'll define the logic and overall purpose of the Agent. 1. Go to **AI Agents** in the navigation bar. 2. Click **+ Create new AI Agent**. 3. Select an agent type. (For this example, we'll use **Debt Collection**) 4. Choose a name and set the language your Agent will use. ## Configure your AI Agent In the [Setup section](../ai-agents/setup.md), provide details about your company and its goals. This helps the Agent understand its role and who it represents. 1. Enter your company's name. 2. In **AI Agent Goal**, describe what you want your Agent to do. For example: `Guide the user through the process of paying a subscription.` ## Knowledge Provide the AI Agent with knowledge in two ways: - **[Static knowledge](../knowledge-base/overview.md)** (Knowledge bases): This is the information the AI Agent will use to answer questions. - **[Custom guidelines](../ai-agents/knowledge.md#guidelines-prompting)**: These are the instructions the AI Agent will follow when crafting its responses. :::tip Think of **knowledge bases** as **what** the AI Agent should answer, and **custom guidelines** as **how** it should answer. ::: ### Preset guidelines Each AI Agent type includes **preset guidelines** that cannot be deleted. While you can leave them blank, filling them in improves the Agent’s performance. Since we chose the **Debt Collection** Agent, the preset is **Handle Objections**. 1. Identify a possible user objection. 2. Provide an example response for how the Agent should handle it. 3. Click **+ Add objection**. 4. Save your changes. #### Example - **Objection**: `I don't like using my credit card online.` - **Answer**: `💳 **Your payment is secure!** We use **encrypted, PCI-compliant** processing, and your card details aren’t stored. You may also get **bank verification (OTP)** for extra security. Let me know if you need help! 😊` ### Custom guidelines #### Payment process A key guideline for a **Debt Collection** Agent is instructing it on how to collect payments. In this case, the Agent must retrieve the user’s ID number in order to generate a payment link. Follow these steps: 1. Click **+ Add guideline** in the summary card on the right. 2. Provide a relevant name and description—the Agent will consider them. 3. A new card appears below **Handling Objections**. Enter the following instructions in markdown: ```md ## What information should be collected from the user? We must get the user's ID number to generate a payment link. Once this information is provided, send the following link to the user: [Payment Link](https://payment.link/) ``` :::tip\ The Agent can also pass the user's ID as a query parameter in the link.\ ::: #### Business hours In addition to payment handling, you may want the Agent to provide your company’s schedule. Follow the same steps as in [Payment process](#payment-process), but use the following content: ```md ## Business Hours - **Monday – Saturday:** 7:00 AM – 8:00 PM - **Sunday:** 7:00 AM – 12:00 PM ``` ## Testing the AI Agent Once your AI Agent is configured, you can start testing it. Testing allows you to evaluate how the Agent responds and fine-tune its behavior. To test the Agent: 1. Click the **Test** button in the top-right corner. 2. A popup chatbox will appear where you can interact with the Agent and review its responses. 3. In the details section, check the context variables and other runtime information. For example, if you ask the Agent, **"What is your schedule?"**, it should respond with the business hours you provided. However, since the goal is payment collection, you may want the Agent to more actively guide users toward that task. To improve this: 1. Navigate to the **Setup** section. 2. In **AI Agent Goal**, modify the description by adding:\ `"**Always** try to complete this task by prompting the user to continue or subtly encouraging them to proceed."` 3. Save changes. 4. Re-run the test. This change helps create a more persistent Agent that nudges users toward completing a payment. --- ## Connect your agent to knowledge bases Connect your AI Agent to knowledge bases to enable intelligent, knowledge-driven responses. This guide walks you through the connection process. ## Prerequisites Before connecting, ensure you have: 1. An [AI Agent](../ai-agents/overview.md) created in your account 2. A [knowledge base](../knowledge-base/overview.md) with content added ## Connect a knowledge base to your agent 1. Navigate to **AI Agents** 2. Select the AI Agent you want to enhance 3. Open the **Knowledge** tab 4. In the **Knowledge base** section, click the dropdown 5. Select the knowledge base you want to connect 6. Click **Connect** Your agent now uses the connected knowledge base to answer user questions. ## Connect multiple knowledge bases Connect more than one knowledge base to a single agent. This is useful when: - You have content organized by topic (e.g., Products, FAQs, Policies) - Different teams maintain separate knowledge bases - You want to combine internal and external content sources To add additional knowledge bases, repeat the connection steps above. The agent searches across all connected knowledge bases when responding. ## When to use knowledge bases vs dialogs | Use knowledge bases for | Use dialogs for | |------------------------|-----------------| | FAQ-style Q&A | Multi-step processes | | Static information lookup | API integrations | | Document-based responses | Conditional logic flows | | Product information | Collecting user data via forms | :::tip Combine both approaches for the best results. Use knowledge bases for information retrieval and dialogs for structured workflows. ::: ## Troubleshooting ### Agent not using knowledge base content - Verify the knowledge base is connected in the **Knowledge** tab - Check that the knowledge base contains relevant content - Ensure the knowledge base language matches user queries ### Responses are inaccurate - Add more specific content to your knowledge base - Review and refine your [guidelines](../ai-agents/knowledge.md#guidelines-prompting) - Check the [Insights](../analytics/insights.md) tab for improvement suggestions ## Next steps - [Knowledge base overview](../knowledge-base/overview.md) - Learn more about knowledge base features - [Add FAQs](../knowledge-base/faq.md) - Create FAQ entries - [Upload documents](../knowledge-base/documents.md) - Import existing documentation --- ## Conversations In Moveo, conversations between users and an [AI Agent](../ai-agents/overview.md) occur within a structure called a **session**. A session is a temporary container used to store all context needed for an ongoing conversation, including: - Context variables - User information - Metadata Sessions enable contextual and coherent conversations by persisting data throughout the interaction. ## How sessions work Each time a user starts a new conversation, Moveo creates a new session. This session remains active throughout the interaction, allowing the AI Agent to maintain continuity and respond meaningfully. The entire conversation context is preserved for the duration of the session. The session's lifetime is primarily controlled by the **session timeout**. Sessions are automatically closed under the following conditions: - The conversation is resolved either through a [dialog](../ai-agents/operations/resolve.md) action or by a [human agent](../chat/human-agents.md). - The session reaches its maximum lifetime, as defined by the [session timeout](./timeouts.md#session-timeout). It is important to distinguish the `session_timeout` from the `inactivity_timeout` setting on an AI Agent. The `session_timeout` is the primary controller of the conversation's lifespan. The `inactivity_timeout`, while also used for analytics and routing, can in some cases shorten the session's life. For more details, see the [Timeouts](./timeouts.md) documentation. Once closed, sessions cannot be reopened unless they are still within a defined grace period (see [session timeout](./timeouts.md#keep-alive)). Although sessions themselves are ephemeral, the **conversation history is preserved**. This allows you to: - Review and audit past conversations. - Extract insights from analytics. - Improve AI Agent performance over time. ## Session life cycle The session life cycle describes how sessions are created, maintained, and ultimately closed or expired. This process ensures a balance between maintaining continuity during a conversation and releasing unused resources after it ends. ### 1. Creation Sessions are created automatically when a new conversation is initiated. This typically happens: - When a user sends the first message. - When a `session:create` event is received from the websocket API. - When a [broadcast](../campaigns/campaigns) message is sent to the user. At creation, the session is initialized with context data and assigned a unique `session_id`. ### 2. Active state While a conversation is ongoing, the session remains in an active state. During this period: - The user can send and receive messages. - The context can be updated dynamically. - Dialogs and conditions have access to all session context variables. - User metadata and preferences are preserved. ### Renewing a Session A session's Time-To-Live (TTL) is not static; it is renewed each time the **user sends a message**. This means the session's expiration clock is reset, extending the life of the session. However, messages sent by an **AI Agent** or a **human agent** do not renew the session TTL. The session is kept alive by the user's activity, ensuring that conversations expire only when the user has been inactive for the configured duration. | Event | Renews Session TTL? | | :------------------------------ | :------------------ | | **User sends a message** | **Yes** | | **AI Agent sends a message** | **No** | | **Human agent sends a message** | **No** | ### 3. Closure A session can be closed under the following conditions: - A **resolve action** is triggered within a dialog. - A human agent manually resolves the conversation and the user doesn't reopen it within the [keep-alive](./timeouts.md#keep-alive) period. - The client explicitly signals the session should be closed. Closed sessions transition to a recoverable state for a short time. ### 4. Grace period (keep-alive) After a session is closed, it enters a grace period defined by the [**keep_alive**](./timeouts.md#keep-alive) setting. During this time: - The session can be reopened if needed (only if it is not expired). - Context and message history are retained. This allows for short breaks in conversation without losing context. ### 5. Expiration When the [**session_timeout**](./timeouts.md#session-timeout) is reached or the **keep_alive** period ends, the session is permanently expired. Once expired: - The session can no longer be accessed or resumed. - A new session must be created for future interactions. ## Sessions and the user experience Sessions ensure that users receive consistent responses by preserving context across messages. Each session is uniquely identified and can include custom metadata that enriches how conversations are handled and analyzed. Monitor active and past sessions through the **Analytics** section of the platform. While sessions are temporary, the information is stored for future reference and debugging purposes. For information about how sessions behave specifically in the websocket API, including recovery mechanisms and timeout behavior, see the [Session life cycle](/api/websocket/life-cycle) documentation. --- ## Publishing agents to production Deployment is a crucial step when integrating Moveo into your business. It consists of three main components: - Environments - Rules - Integrations Each of these plays an essential role in the implementation of Moveo. Let’s explore each of them in detail. ## Environments Within a single Moveo account, you can create multiple environments. Each environment is an independent instance of your Moveo setup, with its own set of rules and integrations. You can use environments to: - Test new setups in a sandbox environment. - Deploy to different channels using separate environments. - Handle different integrations of the same channel independently. - Test different AI Agent versions. ## Rules Rules are the logic Moveo follows to manage conversations. By defining conditions, you can perform actions such as assigning an AI Agent, routing to a department, setting a tag, and more. Every message in a conversation is evaluated against the same set of rules, regardless of the channel it originates from. If you want to treat different channels in distinct ways, you'll need to set up separate environments. For examples on how to configure rules, refer to these guides: - [How to route an agent using rules](../environments/rules-route-agent) - [How to assign a different agent depending on the language](../environments/rules-language) ## Integrations Integrations connect Moveo to your end users. These are the channels through which users interact with your setup. Moveo provides a web widget that can be embedded into your website. This widget is highly customizable and built on top of an exposed [WebSocket API](/api/websocket/connection). You can use this to build your own custom integrations as well. Besides the web widget, Moveo supports several third-party channels: - [Web](../integrations/web/getting-started) - [Facebook Messenger](../integrations/facebook-messenger) - [Instagram](../integrations/instagram-messenger) - [WhatsApp](../integrations/whatsapp) - [Viber](../integrations/viber) - [Intercom](../integrations/intercom) - [Zendesk Chat](../integrations/zendesk) - [Sunshine Conversations](../integrations/sunco) - [Front](../integrations/front.md) - [Smartlead](../integrations/smartlead.md) - [Infobip-SMS](../integrations/infobip-sms.md) - [Infobip-RCS](../integrations/infobip-rcs.md) - [Email](../integrations/email) --- ## Import an AI Agent In this guide, we will show you how to import an AI Agent to your account. After importing an AI Agent, you can test it out or make any changes you wish. ## Step 1: Login to Moveo.AI 1. Navigate to [https://console.moveo.ai](https://console.moveo.ai/). 2. Select your preferred login method. In this guide, we will continue logging in with **Google**. 3. Select your **Gmail** account and you will be directly logged in. ## Step 2: Creating and Importing an AI Agent 1. Click on **Create AI Agent**. 2. Fill out the information in the pop-up window. 3. Import your saved AI Agent (JSON file). 4. Click **Create**. ## Step 3: Navigate to the AI Agent and preview it 1. Click on the newly created AI Agent named `my_imported_brain` in this example. 2. Click on the **Test** icon in the top right of your screen and start chatting with the new AI Agent! --- ## Guides Follow the guides below to get familiar with Moveo.AI and learn from the examples provided. - [View invitations](../platform/invitations.md) - [Allow desktop notifications](../platform/desktop-notifications.md) - [Build your first AI Agent](../ai-agents/setup.md) - Use **rules** to assign an AI Agent - [AI Agent routing](../ai-agents/message-path.md) - [Assign AI Agent depending on language](../environments/rules-language.md) - [Use staging and production environments](../environments/overview.md) - [Knowledge base guidelines & best practices](../knowledge-base/faq.md) - [Create a webview](../ai-agents/responses/webviews.md) - [Create a survey](./survey) - [Create a webhook](../ai-agents/webhooks.md) - [Add your business hours](../environments/business-hours.md) --- ## Deploy your first AI Agent to production ## **Getting Started with Your AI Agent** This guide walks you through the steps to get your [AI agent](../ai-agents/overview.md) up and running and interacting with your customers. The goal is to get you from zero to a fully functional agent in just a few minutes. **A quick note for new users:** If you've just signed up, you might find that some of these steps are already done! The initial onboarding process guides you through tweaking your first agent and deploying it to a web integration. If you followed that tour, you're ahead of the game. This guide is perfect if you skipped the tour or need a refresher. ### **Step 1: Your AI Agent** Before you can deploy your AI agent, you need to have one! We'll assume you've already created an agent. If you haven't, or if you want to build a more specialized one from scratch, you can follow this handy guide to [build your first AI Agent](../ai-agents/quickstart.md). It's good to know that when you create a new account, a default AI agent is automatically created for you, so you can get started right away. This agent is ready to be customized and taught. You can start with this agent and mold it to fit your brand's voice and needs. A great way to do this is by adding more knowledge using [Knowledge base](../knowledge-base/overview.md). Think of Knowledge base as a library of information that your agent can use to answer questions instantly. For example, you could create a knowledge base of your most frequently asked questions (FAQs) or upload documents with product information. This gives your agent the specific knowledge it needs to be truly helpful to your customers. You can learn more about them [here](../knowledge-base/overview.md). ### **Step 2: Set up the Rules** Next, you need to tell the system when to use your AI agent. This is done with [rules](../environments/rules.md), which are powerful automated workflows. In a new account, a fundamental rule is already set up for you and connected to the default agent, making things even easier. If you're using the default agent and haven't created a new one, you can skip this step entirely. You'll want to set up a rule that says: - **When:** A customer starts a conversation - **Then:** Assign the AI agent This simple but crucial instruction means that whenever a new conversation is started on any of your connected channels, your AI agent will be the first to respond, ensuring your customers get an immediate reply. It acts as the entry point for your automated support. #### **Environments?** You might see the term [Environments](../environments/overview.md) in the platform. Don't worry about this for now. An environment is like a workspace, often used to separate testing from the live, customer-facing setup. For this quick start, all you need to know is that a live environment is automatically created for you, so you don't need to configure anything here to get started. ### **Step 3: Connect to your Channels** Now it's time to connect your agent to the channels your customers use. This is the final step to bring your agent to life and make it accessible! You can connect to one or many channels, depending on where your customers prefer to interact with you. :::note You might see that the web integration is already connected to the default agent. This is because the default agent is automatically created for you when you create a new account. ::: Here are the available integrations and links to their setup guides. Choose the channel you want to start with and follow the instructions. | Integration | Setup Page | | ---------------------- | ----------------------------------------------------------- | | Web | [Web Widget](../integrations/web/getting-started.md) | | Facebook Messenger | [Facebook Messenger](../integrations/facebook-messenger.md) | | Instagram | [Instagram](../integrations/instagram-messenger.md) | | WhatsApp | [WhatsApp](../integrations/whatsapp.md) | | Viber | [Viber](../integrations/viber.md) | | Intercom | [Intercom](../integrations/intercom.md) | | Zendesk Chat | [Zendesk Chat](../integrations/zendesk.md) | | Sunshine Conversations | [Sunshine Conversations](../integrations/sunco.md) | | Front | [Front](../integrations/front.md) | | Smartlead | [Smartlead](../integrations/smartlead.md) | | Infobip-SMS | [Infobip-SMS](../integrations/infobip-sms.md) | | Telnyx Voice | [Telnyx Voice](../integrations/telnyx-voice.md) | | Twilio Voice | [Twilio Voice](../integrations/twilio-voice.md) | | Email | [Email](../integrations/email.md) | ### **And that's it!** Once you've set up your integration, your AI agent is ready to go. Congratulations! Your agent is now live and will begin handling incoming conversations immediately, providing instant support to your customers. Your setup is now production-ready. --- ## Staging and live environments In certain cases, you may need to use two environments for your AI Agent: a **staging** (development) environment and a **live** (production) environment. In the staging environment, you will be able to immediately view the changes you make to the AI Agent, whereas the production environment should contain the assistant that your customers will converse with. Check out the following guide, which demonstrates the full procedure of creating the staging and production environments. ### New environment To create the `dev` environment, follow these steps. This environment is similar to any other environment, but we will set up a rule to route the conversation to a `draft` version of an AI Agent. 1. Click on your avatar and go to the **Profile** section. 2. Click on the **+** button next to the **Environments** tab on the sidebar. 3. Choose a name for your new environment and decide whether you want **Human Chat** enabled or not. ### Routing rules After creating your new environment, you need to set up a routing rule to route the conversation to the `draft` version of the AI Agent. This version reflects the state of your Agent as you see it when editing, without publishing a new version. 1. Go to **Deploy** → **Rules**. 2. Click on the dropdown menu in the subnavigation bar and select the environment you just created. In our case, it would be `Development`. 3. Click on the **+ Create new rule** button. 4. Choose a name for your rule and click on **Create**. 5. Click on **Add action** and select **Assign AI Agent** from the menu. 6. In a production environment, you would select the latest version of the Agent, but in the development environment, you should select the `draft` version. 7. Activate the rule and save changes. --- ## Survey A survey is a set of questions that you can send to your customers to gather feedback about your product or service. You can create a survey using the Moveo platform and send it to your customers. See [Survey Response](../ai-agents/responses/survey.md) for more details. ## Template If you want to jump straight into some template code, go to our [integration-guides repository on GitHub](https://github.com/moveo-ai/integration-guides/tree/main/pages/common). ## How to create your own survey To create your own survey, follow the steps described in the [How to create your own webview](../ai-agents/responses/webviews.md#how-to-create-your-own-webview) guide. The main difference with a regular webview is the data submission, which you should do by making an HTTP POST request to: `https://channels.moveo.ai/v1/survey/${integration_id}`, using the following headers and body: ```ts headers: { Authorization: `Bearer ${signature}`, 'X-Moveo-Session-Id': sessionId, } ``` ```ts body: { session_id: sessionId, timestamp: Date.now(), // unix timestamp, feedback: 'Everything was awesome', rating: 5 } ``` --- ## Timeout Mechanisms in Moveo Moveo uses several timeout mechanisms to manage the lifecycle of conversations. These timeouts serve different purposes and work together to ensure optimal user experience while maintaining system efficiency. This page explains the key timeout mechanisms and how they impact conversations. ## Session timeout The **session timeout** is the default timeout that acts as the baseline lifetime for a conversation. Its value is configured at the integration level and varies depending on the integration (e.g., WhatsApp vs. Zendesk). In the API, it is represented as **session timeout** (in seconds). The default session timeout varies depending on the integration type. The following table shows the default session timeout for each integration type: | Integration Type | Default Session Timeout (seconds) | | ------------------------------------------------------------- | --------------------------------- | | [Facebook-messenger](/docs/integrations/facebook-messenger) | 604800 (7 days) | | [Instagram-messenger](/docs/integrations/instagram-messenger) | 604800 (7 days) | | [Whatsapp](/docs/integrations/whatsapp) | 604800 (7 days) | | [Viber](/docs/integrations/viber) | 604800 (7 days) | | [Intercom](/docs/integrations/intercom) | 86400 (1 day) | | [Zendesk](/docs/integrations/zendesk) | 86400 (1 day) | | [Front](/docs/integrations/front) | 86400 (1 day) | | [Web](/docs/integrations/web) | 3600 (1 hour) | | [Sunco](/docs/integrations/sunco) | 600 (10 minutes) | | [Smartlead](/docs/integrations/smartlead) | 1296000 (15 days) | | [Infobip-sms](/docs/integrations/infobip-sms) | 604800 (7 days) | | Infobip-rcs | 604800 (7 days) | | Telnyx-voice | 300 (5 minutes) | | Twilio-voice | 300 (5 minutes) | | Email | 1296000 (15 days) | This timeout is primarily used in two scenarios: 1. **Initial Conversation Timeout**: When a conversation is first created, such as through a broadcast message, it uses the **session timeout** until the user replies and an AI or human agent is assigned. 2. **Human Agent Conversations**: When a human agent is handling the conversation, the **session timeout** governs the session's maximum duration. The session's expiration time is reset to the **session timeout** value each time the **user** sends a message during a human-handled conversation. :::note The **session timeout** is not configurable from the UI. It can only be set via the API by setting `config.session_timeout` propery when [creating or updating an integration](/api/rest/add-integration). ::: --- ## Inactivity timeout The **inactivity timeout** governs the session's duration when an **AI Agent** is active, taking precedence over the default **session timeout**. When an AI Agent is assigned to a session, the **inactivity timeout** from the agent's configuration defines the session's maximum lifetime. The session will expire if the user does not send a message within this timeframe. This value is represented as **inactivity timeout seconds** in the API. :::tip Subscribe to [event notifications](../platform/event-notifications) to receive notification when a session expires due to inactivity. ::: Configure this timeout in the AI Agent settings under the **Advanced** tab. The session's expiration time is reset to the **inactivity timeout** value each time the **user** sends a message during an AI-handled conversation. ### How to configure inactivity timeout 1. Navigate to your AI Agent. 2. Click on the **Advanced** tab. 3. Choose an option in the **Inactivity timeout** section. ## Dynamic timeout behavior Moveo dynamically manages the session timeout based on the context of the conversation. - If an **AI Agent** is assigned to the conversation, the session's lifetime is determined by the agent's **inactivity timeout**. - If a **human agent** takes over, the timeout switches to the integration's default **session timeout**. This ensures that the session's lifetime is adapted to the context, whether it's automated or handled by a human. For example, if a conversation is started by a campaign, it will remain open until the initial **session timeout** expires. If the user responds and an AI Agent takes over, the session's expiration will now be dictated by the AI Agent's **inactivity timeout**. The session will expire if the user does not send another message within that new timeframe. :::important The session timeout—whether it is the **session timeout** or the **inactivity timeout**—is **only** reset when the **user** sends a message. Messages sent by an AI Agent or a human agent do not extend the session's life. The conversation is kept alive exclusively by the user's interactions. ::: ## Keep alive The **keep alive** timeout specifies the number of seconds to keep a session open after it has been marked as resolved. This allows users to continue the same conversation if they have follow-up questions within a short period. ### Key features: - **Grace Period**: Provides a buffer after a conversation is resolved. - **Measured in Seconds**: The value is configured in seconds (e.g., 300 seconds = 5 minutes). - **API Representation**: Represented as `keep_alive` in the API. ### Use case: Imagine a customer support scenario where an agent has resolved a user's issue and marked the conversation as complete. With a `keep_alive` of 5 minutes: 1. The conversation remains open and accessible for 5 minutes after being resolved. 2. If the user sends another message within this window, it is appended to the same conversation. 3. If the user sends a message after the 5-minute period, a new conversation is created. ### How to configure keep alive timeout 1. Navigate to **Settings**. 2. Select the **Environment** you want to modify. 3. Click on the **Setting** tab. 4. Scroll down to the **Keep alive** section. ### Voice integrations Keep alive does not affect call termination on voice integrations such as [Twilio Voice](../integrations/twilio-voice.md) and [Telnyx Voice](../integrations/telnyx-voice.md). When the AI Agent triggers [`Resolve`](../ai-agents/operations/resolve.md), the platform hangs up the call within a couple of seconds, whatever the keep alive value. Choose the keep alive value for your chat channels alone. The setting applies to the whole environment, so lowering it for a voice reason also shortens the follow-up window of every chat integration on that environment. To keep the caller on the line for longer before the call ends, add a [`Pause`](../ai-agents/operations/pause.md) action before `Resolve`. A pause is the only way to postpone the hangup. --- ## Email(Integrations) ## Overview [Email integration](../integrations/overview.md) enables your [AI Agent](../ai-agents/overview.md) to communicate with customers through email. This channel provides a familiar and widely-used method for customer support, sales inquiries, and engagement through automated email conversations. Moveo's email integration uses enterprise-grade email infrastructure to ensure reliable delivery, secure message handling, and professional presentation of all automated responses. --- ## Prerequisites Before setting up the email [integration](../integrations/overview.md), ensure you have: **Email domain requirements** - A verified domain that you own and can configure DNS records for - Access to your domain's DNS management (via your registrar or DNS provider) - Ability to add DNS records (CNAME records for domain verification) **Email service requirements** - An email service account (Google Workspace, Microsoft 365, or custom mail server) - Access to configure email forwarding rules in your email provider - A dedicated email address for your [AI Agent](../ai-agents/overview.md) (e.g., `support@yourdomain.com`) --- ## How it works The email [integration](../integrations/overview.md) requires two essential setup steps to enable both receiving and sending emails: **Receiving emails (inbound)**: 1. **Customer sends email** to your configured email address. 2. **Email forwarding rule** forwards the message to Moveo's email processing system. 3. **[AI Agent](../ai-agents/overview.md)** receives the message content. --- **Sending emails (outbound)**: 4. **Response is generated** based on your configured knowledge and dialogs. 5. **DNS records authorize** Moveo to send emails on behalf of your domain. 6. **Reply is sent** back to the customer from your domain. 7. **Thread management** maintains conversation context. 8. **Handover available** to human agents when needed via [Live chat](../chat/chat-overview). All emails are processed securely and maintain proper email threading for natural conversation flow. --- ## Connect email in Moveo ### Step 1: Navigate to Connections 1. Log in to your Moveo account. 2. Navigate to **Connections** → **Emails**. 3. Select your desired environment. 4. Click **Add Email** in the top navigation bar. ### Step 2: Enter Sender information 1. In the **Sender information** form, enter the following: - **Sender email**: The email address you want to use for your [AI Agent](../ai-agents/overview.md) (e.g., `support@yourdomain.com`). - **Sender name**: The display name that will appear as the sender of your emails (e.g., "Support Team" or "AI Assistant"). 2. Click **Verify** to proceed. ### Step 3: Complete DNS configuration To send emails on behalf of your domain, you must complete the DNS configuration. This step is **required** for the [integration](../integrations/overview.md) to work. Follow the instructions in the [DNS configuration](#dns-configuration) section below. ### Step 4: Configure email forwarding To receive inbound emails, you must set up email forwarding from your email service to Moveo. This step is **required** for the [integration](../integrations/overview.md) to work. Follow the instructions in the [Forward your emails to Moveo.ai](#forward-your-emails-to-moveoai) section below. --- ## DNS configuration :::important This DNS configuration is **required** to allow Moveo to send emails on behalf of your domain. Without these records, email replies from your [AI Agent](../ai-agents/overview.md) cannot be delivered. ::: To enable Moveo to send emails from your domain, you need to configure DNS records that authorize and authenticate Moveo as a sender. ### Step 1: Get DNS configuration details 1. After entering your sender information and clicking **Verify**, you will see the **DNS status** section. 2. The DNS status section shows all required CNAME records with their verification status. 3. For each record, you can copy the **Host** and **Value** fields using the copy icons next to each field. 4. These values will be used to configure DNS records in your domain provider. ### Step 2: Add CNAME records CNAME records are required for domain verification and tracking. 1. In the DNS Configuration section, you will see three CNAME records provided by Moveo. 2. For each CNAME record: 1. Log in to your domain registrar or DNS provider 2. Navigate to DNS management for your domain 3. Add a new CNAME record with the following: **Type**: CNAME **Name/Host**: The subdomain provided by Moveo (e.g., `em1234`, `s1._domainkey`, etc.) **Value/Target**: The target hostname provided by Moveo **TTL**: `3600` (or default) 3. CNAME records are required for domain verification and must be added before other records can be verified. :::note CNAME records point to subdomains (like `em1234.yourdomain.com`). Make sure you're adding these as subdomain records, not root domain records. Some DNS providers require you to enter just the subdomain prefix in the Name/Host field. ::: ### Step 3: Add DMARC record (Optional but recommended) DMARC (Domain-based Message Authentication, Reporting, and Conformance) helps protect your domain from email spoofing. If you already have a DMARC entry configured you can skip this step. 1. Create a new TXT record. 2. **Name/Host**: `_dmarc`. 3. **Value**: `v=DMARC1; p=none;`. 4. **TTL**: `3600`. ### Step 4: Verify DNS configuration 1. Return to Moveo's Email integration page. 2. Click **Verify** to check the status of your DNS records. 3. Moveo will check each record and show whether each is verified or unverified: **Verified**: DNS record is correctly configured and verified. **Unverified**: DNS record is not found or incorrectly configured. :::tip DNS changes can take anywhere from a few minutes to 48 hours to propagate globally. ::: --- ## Forward your emails to Moveo.ai :::important Required step: Email forwarding is **required** to enable Moveo to receive inbound emails. You must configure forwarding from your email service to Moveo's email processing system. ::: Email forwarding routes incoming emails from your configured email address to Moveo's [AI Agent](../ai-agents/overview.md) processing system. This setup works with any email service (Google Workspace, Microsoft 365, custom mail servers, etc.) and allows you to keep your existing email infrastructure while enabling [AI Agent](../ai-agents/overview.md) responses. ### Step 1: Configure forwarding in your email provider Consult your email provider's documentation for setting up forwarding rules. The general process is: 1. Find forwarding or mail routing settings. 2. Create a rule that forwards emails to Moveo. 3. Forward to the address provided in Moveo's integration configuration. 4. If your email provider sends a verification email, this will be forwarded to Moveo and can be viewed in your [analytics logs](../analytics/logs). ### Step 2: Verify forwarding in Moveo 1. Send a test email to your configured address. 2. Verify the email appears in Moveo's analytics within a few minutes. :::info Verification Emails Some email providers (like Google Workspace or Microsoft 365) may send a verification email to the forwarding address when you set up email forwarding. This verification email will be forwarded to Moveo. You can view this verification email in your [analytics logs](../analytics/logs). ::: --- ## Troubleshooting
DNS records not verifying **Symptoms**: DNS verification is unverified after configuring DNS provider **Solutions**: - Wait 24–48 hours for DNS propagation. - Check for typos in record values (case-sensitive). - Ensure you're using the exact values from Moveo (no extra spaces). - Check if your DNS provider requires a trailing dot (.) in hostnames.
Email forwarding not working **Symptoms**: Inbound emails not reaching Moveo, forwarding rule not triggering **Solutions**: - Verify forwarding rule is active and correctly configured in your email provider. - Test forwarding by sending a test email and checking if it reaches Moveo. - Check email provider logs for forwarding errors. - Ensure forwarding address from Moveo is correct (no typos). - Verify the email address matches exactly between forwarding rule and Moveo configuration. - Review email provider's forwarding limits or restrictions. - Check spam filters aren't blocking forwarded emails. - If your email provider sent a verification email, check your [analytics logs](../analytics/logs) as it may have been forwarded automatically.
Emails going to spam **Symptoms**: Customer emails or [AI Agent](../ai-agents/overview.md) replies end up in spam folders **Solutions**: - Verify CNAME records are properly configured (takes 24–48 hours). - Add DMARC record for better email authentication. - Warm up the email domain gradually if it's new. - Avoid spam trigger words in [AI Agent](../ai-agents/overview.md) responses.
Conversation threads breaking **Symptoms**: Each email appears as a new conversation instead of continuing existing threads **Solutions**: - Check if email client is preserving threading headers. - Test with different email clients (Gmail, Outlook, etc.). - Contact Moveo support at `support@moveo.ai` if threading issues persist.
--- ## Limitations ### Email platform restrictions - **Message size**: Standard email size limits apply (typically 30 MB including attachments). - **File attachments**: Supported, but large attachments may affect delivery speed. - **Email format**: Supports HTML and plain text emails. ### Integration constraints - **One email address per integration**: Each [integration](../integrations/overview.md) handles one email address. - **Thread management**: Requires proper email client support for threading. - **DNS propagation**: Initial setup requires waiting for DNS propagation (up to 48 hours). - **Domain verification**: Domain must be verified before emails can be sent. --- ## Best practices ### Email setup - Use a dedicated email address for your [AI Agent](../ai-agents/overview.md) (e.g., `support@yourdomain.com`, `help@yourdomain.com`). - Configure the DMARC record (optional but recommended) for best deliverability. - Test email delivery thoroughly before going live. - Monitor email deliverability metrics regularly. ### Compliance - Monitor for unauthorized email sending. - Follow email best practices and anti-spam guidelines. - Protect your domain's sender reputation. --- ## Next steps Once your email [integration](../integrations/overview.md) is active: 1. **Test thoroughly** by sending test emails from different addresses. 2. **Monitor initial conversations** to ensure proper threading and responses. 3. **Optimize [AI Agent](../ai-agents/overview.md) responses** for email format and clarity. --- ## Facebook Messenger ## Overview Facebook Messenger integration allows your AI Agent to communicate with customers through your Facebook Page. With billions of active users, Messenger provides a familiar platform where customers already spend time, making it an ideal channel for customer service and engagement. This integration enables: - **Automated responses** to messages on your Facebook Page - **24/7 availability** for customer inquiries - **Rich messaging features** including quick replies, buttons, and carousels - **Seamless handover** to human agents when needed - **Integration with Facebook's ecosystem** including Instagram and WhatsApp --- ## Prerequisites Before setting up the Facebook Messenger integration: ✅ **Facebook Page requirements** - An active Facebook Page for your business - [Admin access](https://www.facebook.com/help/289207354498410) to the Page - Page must be published (not unpublished or restricted) ✅ **Moveo account setup** - An active [AI Agent](../ai-agents/overview.md) configured - An [environment](../environments/overview.md) selected for the integration ✅ **Technical requirements** - Authority to grant app permissions - Access to Page settings and messaging configuration --- ## How it works The Facebook Messenger integration creates a direct connection between your Facebook Page and Moveo AI Agent: 1. **Customer sends message** to your Facebook Page via Messenger 2. **Moveo receives the message** through Facebook's Graph API 3. **AI Agent processes** the message using your configured knowledge and dialogs 4. **Response is sent** back through Messenger to the customer 5. **Handover available** to human agents when needed All conversations happen within Facebook's secure infrastructure and comply with their platform policies. --- ## Setup guide The setup process differs based on whether this is your first Facebook integration or you're adding additional Pages. ### First-time connection Follow these steps if you're connecting a Facebook Page to Moveo for the first time: #### Step 1: Initiate connection 1. Navigate to **Integrations** in your Moveo account 2. Select your desired environment 3. Find Facebook Messenger and click **Connect** 4. You'll be redirected to the Meta Dialog Window #### Step 2: Grant permissions In the Meta Dialog Window: 1. **Select ONE page** you want to connect 2. **Grant ALL permissions** requested by Moveo 3. Click **Continue** :::warning Only select ONE page during initial setup. You can add more pages later using the multi-page process. ::: #### Step 3: Complete setup 1. You'll be redirected back to Moveo 2. Your Page is now connected 3. Proceed to [Configuration](#configuration-options) --- ### Adding additional Pages If you already have Facebook Pages connected to Moveo, follow this process to add more: #### Step 1: Preserve existing connections 1. Click **Connect** to open Meta Dialog Window 2. **Keep ALL previously connected Pages selected** 3. **Add the new Page** to your selection 4. Grant all permissions :::caution You MUST keep previously connected Pages selected. Deselecting them will disconnect those Pages from Moveo. ::: #### Step 2: Complete setup 1. Return to Moveo after authorization 2. All selected Pages are now connected 3. Configure each Page individually --- ## Configuration options After connecting your Facebook Page, configure these settings to optimize your integration: ### Integration status Toggle the integration to **Active** to start receiving and responding to messages. ### Welcome screen setup Configure how new conversations begin with the welcome screen: #### Greeting text A brief description of your Page that appears when users first open Messenger. #### Get Started button The button users click to initiate conversation. Configure: - Button text (default: "Get Started") - Initial message sent when clicked Example configuration: ### Persistent menu Create an always-visible menu with quick access options: 1. **Menu items**: Add up to 3 primary menu items 2. **Actions**: Each item can: - Send a predefined message - Open a URL - Trigger a specific dialog 3. **Nested menus**: Create sub-menus for better organization Benefits: - Quick access to common functions - Improved user navigation - Consistent experience across conversations ### Webview configuration If your AI Agent uses [webview responses](../ai-agents/responses/webview.md): #### Whitelist domains Add trusted domains that can be opened in Messenger's in-app browser: - Your website domain - Payment processor domains - Third-party service domains Example: ``` https://example.com https://payments.example.com https://booking.example.com ``` ### Advanced security #### App Secret validation Enable request signature verification for enhanced security: 1. Enable in Moveo settings 2. Add App Secret from your Facebook App 3. All webhook requests will be validated --- ## Testing your integration ### Test with your account 1. **Send a test message** to your Facebook Page 2. **Verify AI Agent responds** appropriately 3. **Test different scenarios**: - Welcome message - Common questions - Handover triggers - Error cases ### Test with different users 1. Have team members message your Page 2. Test with different user permissions 3. Verify consistent behavior ### Monitor performance Check these metrics in Facebook Page Insights: - Response time - Response rate - Customer satisfaction - Message volume --- ## Common use cases ### Customer support - Answer FAQs instantly - Provide order status updates - Handle returns and refunds - Escalate complex issues to agents ### Lead generation - Qualify leads automatically - Schedule appointments - Collect contact information - Route to sales team ### E-commerce - Product recommendations - Inventory checks - Order placement assistance - Post-purchase support ### Marketing - Contest and promotion management - Event registrations - Newsletter signups - Product launches --- ## Best practices ### Response design - Keep messages concise and scannable - Use quick replies for common options - Include buttons for clear actions - Add images for visual appeal ### Conversation flow - Start with a clear welcome message - Guide users with suggested actions - Provide escape routes (talk to human) - End conversations gracefully ### Compliance - Follow Facebook's Platform Policy - Respect user privacy - Provide opt-out options - Handle data responsibly ### Performance optimization - Monitor response times - Track handover rates - Review failed interactions - Continuously improve responses --- ## Troubleshooting ### Connection issues
Page doesn't appear in selection - Verify you have admin access to the Page - Check Page is published and not restricted - Try logging out and back into Facebook - Clear browser cache and cookies
Permissions not granted properly - Ensure ALL requested permissions are granted - Check no permissions were previously revoked - Review Facebook App settings - Re-authorize if needed
Previously connected Pages disconnected - When adding new Pages, keep old ones selected - If accidentally disconnected, reconnect all Pages - Check each Page's configuration is intact - Contact support if data was lost
### Message delivery
AI Agent not responding - Verify integration is set to Active - Check AI Agent is assigned to environment - Review Facebook Page settings - Ensure webhook is properly configured
Responses are slow or timeout - Check Moveo system status - Review AI Agent complexity - Optimize response generation - Consider implementing typing indicators
Media not displaying correctly - Verify image URLs are publicly accessible - Check file size limits (25MB for images) - Ensure HTTPS URLs are used - Review supported formats
--- ## Limitations ### Platform restrictions - **24-hour messaging window**: Can only send promotional messages within 24 hours of user interaction - **Message tags**: Limited use cases for messages outside 24-hour window - **Rate limits**: Subject to Facebook's rate limiting policies - **Content policies**: Must comply with Facebook Community Standards ### Feature limitations - **File attachments**: Limited file types supported - **Message length**: Maximum 2000 characters per message - **Quick replies**: Maximum 13 options - **Persistent menu**: Maximum 3 top-level items --- ## Resources ### Documentation - [Facebook Messenger Platform](https://developers.facebook.com/docs/messenger-platform) - [Platform Policies](https://developers.facebook.com/docs/messenger-platform/policy) - [Best Practices](https://developers.facebook.com/docs/messenger-platform/introduction/general-best-practices) ### Tools - [Facebook Page Insights](https://www.facebook.com/help/794890670645072) - [Meta Business Suite](https://business.facebook.com) - [Graph API Explorer](https://developers.facebook.com/tools/explorer/) ### Support - [Facebook Business Help](https://www.facebook.com/business/help) - Moveo support: support@moveo.ai --- ## Next steps Once your Messenger integration is active: 1. **Customize your welcome screen** to match your brand 2. **Configure the persistent menu** for easy navigation 3. **Test thoroughly** with different user scenarios 4. **Monitor analytics** to optimize performance 5. **Set up handover rules** for human agent escalation --- ## Front ## Overview Front integration transforms your shared inbox into an intelligent customer communication hub. By connecting Moveo with Front, your AI Agent works alongside your team to handle customer inquiries across multiple channels, from email and SMS to chat and social media, all within your existing Front workspace. This integration enables: - **Unified inbox management** with AI and human agents collaborating - **Multi-channel support** across email, SMS, chat, and social platforms - **Intelligent conversation routing** based on tags and inbox rules - **Seamless handover** between AI and human agents - **Complete conversation history** maintained in Front - **Flexible deployment modes** (System or Agent mode) --- ## Prerequisites Before setting up the Front integration, ensure you have: ✅ **Front account requirements** - Active Front workspace - **Company admin** role in your Front account - Access to integration and bot settings ✅ **Channel setup** - Configured inboxes for the channels you want to automate - Appropriate tags for conversation routing (optional) - Team permissions configured for handover scenarios ✅ **Moveo account setup** - An active [AI Agent](../ai-agents/overview.md) configured - An [environment](../environments/overview.md) selected for the integration :::note Company admin access is required both for initial setup and for Agent mode operation. ::: --- ## How it works Front integration operates through two distinct modes, each with different conversation handling approaches: ### System Mode (Recommended) 1. **Customer message arrives** in configured Front inbox 2. **Unassigned conversations** are detected by Moveo 3. **AI Agent responds** as a separate system (no teammate seat required) 4. **Conversation remains unassigned** until human intervention needed 5. **Handover adds tag** ("Moveo Handover") for human agent pickup ### Agent Mode 1. **Customer message arrives** in configured Front inbox 2. **AI Agent acts as specified teammate** in your Front workspace 3. **Conversation is assigned** to the AI Agent teammate 4. **AI handles responses** until handover is triggered 5. **Conversation is unassigned** for human agent takeover Both modes support tag-based filtering for precise conversation routing. --- ## Setup guide ### Step 1: Connect with Front To connect Moveo with Front, the process is straightforward. First, create a Front integration inside Moveo and click the **Connect** button. When you are redirected to Front, log in to your account if you haven't already, and click **Authorize**. Lastly, configure the [Inboxes](#inbox-configuration) in which you want Moveo to handle conversations. --- ## Configuration options ### Integration mode Choose between two operational modes: #### System Mode (Recommended) - AI Agent operates as a separate system - No teammate seat required - Supports most Front channels (except Intercom) - Conversations remain unassigned - Best for high-volume automation #### Agent Mode - AI Agent acts as specified teammate - Requires Company admin teammate - Full channel support including Intercom - Conversations are assigned/unassigned - Best for personalized interactions ### Inbox configuration Select which inboxes Moveo should monitor: - Choose specific inboxes for AI Agent engagement - AI Agent handles **unassigned conversations only** - Configure per-inbox routing rules as needed ### Tag-based routing Optional tag filtering for precise control: - Specify tags for AI Agent to engage with - Leave empty to handle all unassigned conversations - Combine with inbox selection for advanced routing - Use for department-specific automation ### Advanced settings #### Response behavior by mode **System Integration:** - AI Agent operates as separate system - Responses appear from "Moveo System" - No teammate seat consumed - Most channels supported (except Intercom) - Conversations always remain unassigned **Agent Integration:** - AI Agent impersonates specified teammate - Responses appear from chosen teammate - Requires Company admin teammate - All channels supported (including Intercom) - Conversations assigned to AI Agent teammate #### Handover behavior by mode **System Handover:** 1. Customer requests human assistance 2. AI Agent acknowledges and responds 3. **"Moveo Handover"** tag is added 4. Conversation remains unassigned 5. Human agents can pick up tagged conversations **Agent Handover:** 1. Customer requests human assistance 2. AI Agent acknowledges and responds 3. Conversation is **unassigned** from AI Agent 4. Human agents can take over immediately 5. Full context preserved in conversation history --- ## Testing your integration ### Initial testing 1. **Send test messages** to configured inboxes 2. **Verify AI Agent engagement** based on your settings 3. **Test both modes** if considering Agent mode 4. **Validate tag-based routing** if configured 5. **Test handover scenarios** thoroughly ### Test scenarios ✓ **Unassigned conversation handling** ✓ **Tag-based conversation filtering** ✓ **Multi-channel message processing** ✓ **Handover tag application (System mode)** ✓ **Conversation reassignment (Agent mode)** ✓ **Response format compatibility** ### Monitoring - **Front inbox activity** for AI Agent responses - **Handover success rate** and human pickup time - **Tag application** accuracy - **Response quality** across different channels --- ## Common use cases ### Customer support automation - Automate first-line support across all channels - Handle common inquiries instantly - Escalate complex issues with context preservation - Maintain 24/7 availability ### Multi-channel management - Unified handling of email, SMS, chat, and social - Consistent responses across all platforms - Centralized conversation history - Team-wide visibility and collaboration ### Department-specific routing - Use tags to route conversations by department - Specialized AI Agents for different teams - Automated triage and categorization - Efficient resource allocation ### High-volume inbox management - Process large volumes of routine inquiries - Reduce human agent workload - Maintain response time standards - Scale support without additional headcount --- ## Best practices ### Mode selection - **Use System mode** for high-volume automation - **Use Agent mode** when personalization matters - Consider channel requirements (Intercom needs Agent mode) - Plan for teammate seat allocation in Agent mode ### Inbox organization - Start with specific inboxes, expand gradually - Configure clear inbox naming conventions - Set up proper team access permissions - Document inbox purposes for team clarity ### Tag strategy - Use descriptive, consistent tag naming - Create tags for different conversation types - Document tag usage for team alignment - Regular tag cleanup and optimization ### Handover optimization - Train AI Agent on clear handover triggers - Set expectations for human response times - Monitor handover rates and reasons - Continuously refine handover criteria --- ## Troubleshooting
AI Agent not responding to messages - Verify integration is Active in Moveo - Check that conversations are unassigned in Front - Confirm inbox is selected in integration settings - Verify tag requirements are met (if configured) - Check AI Agent is properly assigned to environment
Handover not working properly **System Mode:** - Check if "Moveo Handover" tag is being applied - Verify human agents can see tagged conversations - Ensure tag permissions are properly configured **Agent Mode:** - Confirm conversation is being unassigned - Check teammate permissions and availability - Verify AI Agent teammate has Company admin role
Agent mode teammate issues - Ensure selected teammate has Company admin role - Verify teammate is active in Front workspace - Check that teammate isn't already handling conversations - Confirm proper integration permissions
Channel not supported errors - Intercom channel requires Agent mode - Verify channel is properly connected in Front - Check if channel supports programmatic responses - Review Front channel configuration
Conversation not being created Check this section: [Tags](#tags).
--- ## Limitations ### Response type restrictions - **[Carousels](../ai-agents/responses/carousel.md)**: Not supported - **[Webviews](../ai-agents/responses/webview.md)**: Not supported - **[Options](../ai-agents/responses/text.md#options)**: Partially supported - Text responses and basic formatting fully supported ### Integration constraints - **System mode**: Cannot access Intercom channel - **Agent mode**: Requires Company admin teammate - **Unassigned conversations only**: AI Agent won't engage with assigned conversations - **Tag dependencies**: Tag-based routing requires proper tag management ### Platform requirements - Company admin role required for setup and Agent mode - Front workspace must support integrations - Channel-specific limitations may apply ### Tags Tags from Front are automatically forwarded to Moveo. However, Moveo supports a maximum of 25 tags per conversation. If a Front conversation has more than 25 tags (for example, tags automatically applied by Front rules), the handoff to Moveo will fail. In this case, the Moveo conversation will never be created, and the assignment won't go through. **How to avoid this issue:** Make sure that Front conversations have no more than 25 tags before they are passed to Moveo. Review your Front rules to ensure they don't assign more than 25 tags at once. --- ## Resources ### Documentation - [Front Help Center](https://help.front.com) - [Front Integrations Guide](https://help.front.com/t/72n9vk/integrations) - [Front API Documentation](https://dev.front.com) ### Support - [Front Community](https://community.front.com) - [Front Support](https://help.front.com/t/x6k9z2/contact-support) - Moveo support: support@moveo.ai --- ## Next steps Once your Front integration is active: 1. **Choose optimal integration mode** based on your needs 2. **Configure inbox and tag settings** for precise routing 3. **Test thoroughly** across all your channels 4. **Train your team** on handover procedures 5. **Monitor performance** and optimize AI Agent responses --- ## Infobip RCS ## Overview Moveo supports Rich Communication Services (RCS) conversations between your AI Agent and end-users by integrating with Infobip, a global messaging platform. RCS is the next generation of SMS that offers rich media capabilities including images, videos, carousels, quick replies, and interactive buttons. This integration enables your AI Agent to deliver engaging, interactive messaging experiences that go beyond traditional text-based SMS. Your AI Agent can send outbound RCS messages with rich content and respond to inbound RCS messages using a registered RCS sender, fully managed through your Infobip account. :::tip Recommended reading Review the [Infobip documentation](https://www.infobip.com/docs) to understand platform capabilities and regional requirements. ::: ## Create and Configure an Infobip Account To use Infobip RCS with Moveo, you need an active Infobip account and a registered RCS sender. Follow these steps: 1. Go to [infobip.com](https://www.infobip.com/) and select **Start free** or **Create account**. 2. Complete the sign-up process by entering your business details and verifying your email address. 3. After logging in, [add funds](https://www.infobip.com/docs/essentials/manage-my-account/payments#add-funds) to your Infobip account to enable messaging services. 4. Request an **RCS sender**: - Review Infobip Resources to understand senders and identifiers: [Resources](https://www.infobip.com/docs/resources). - Submit a request via [My Requests](https://www.infobip.com/docs/myrequests/submit-myrequests). Choose the RCS channel and request a branded RCS sender. 5. Complete any required verification and launch steps coordinated by Infobip and mobile network operators (MNOs) after your sender request is submitted. :::important RCS is not available in all countries and requires carrier support. Contact your Infobip account manager for more information. ::: ### Understanding RCS Capabilities RCS offers several advantages over traditional SMS: - **Rich Media**: Send images, videos, and audio files - **Interactive Elements**: Include quick reply buttons, suggested actions, and carousels - **Branded Messaging**: Display your business name and logo - **Read Receipts**: Know when messages are delivered and read To use Moveo, your Infobip account must have an approved **RCS sender**. Traditional SMS-only numbers are not used for this integration. --- ## Connect the Infobip RCS Sender With Moveo Once your RCS sender is available for testing or approved, connect it to Moveo by following these steps. ### Gather Required Information You need the following details from your Infobip account: #### 1. API key You need to check these permissions in your API key: - `rcs:manage` - `subscriptions:manage` :::tip Use the **default API key** visible on the Infobip homepage after logging in. ::: #### 2. Base URL The **Base URL** of your Infobip environment (for example, `https://xyz.api.infobip.com`). #### 3. Sender Name The **Sender Name** of your registered RCS sender. In the Infobip web interface, navigate to **Channels and Numbers → Channels → RCS Business Messaging → Senders**. From the list of senders, find the one you want to connect with Moveo and copy the name. ### Complete the Setup in Moveo To set up the Infobip RCS integration, go to the Moveo platform and fill the fields with the information gathered in the previous step. 1. In the Moveo platform, go to **Integrations → Infobip RCS → Connect**. 2. Enter the required fields using the details from your Infobip account. 3. Click **Save** to complete the setup. Your AI Agent can now send and receive RCS messages using the connected RCS sender, enabling rich, interactive conversations with your users. --- ## Test and Launch Your Sender After you complete your sender registration though Infobip and and the connection in Moveo, to go live with RCS Business Messaging follow the steps described on [Infobip](https://www.infobip.com/docs/rcs/get-started). ### Test Connection Once the sender status is **In testing**, you can add test devices and send test messages. 1. Prepare a test device with RCS enabled (Android with Google Messages, or iPhone with iOS 18+ and RCS enabled in Settings). 2. Add safelisted test device numbers under your sender’s **Test devices** tab. Accept the invitation for testing the sender sent by Infobip. 3. Send a campaign message to the safelisted test device using [Campaigns](../campaigns/campaigns.md) and selecting the RCS sender. ### Verification and Launch Provide brand, opt‑in, and usage details for launch approval. Mobile network operators may require additional checks. After approval, the sender is live and you can send production traffic without additional testing. :::caution To ensure compliance with RCS requirements, follow Infobip's official guidance. See [Compliance and guidelines](https://www.infobip.com/docs/rcs/guidelines-and-compliance). Non-compliance may result in suspension or blocking. ::: --- ## Frequently Asked Questions **Do I need a phone number for RCS with Infobip?** No. Infobip uses **RCS senders** (brand identities) rather than phone numbers for RCS. You need to register an RCS sender via [My Requests](https://www.infobip.com/docs/myrequests/submit-myrequests) or follow the process described [here](https://www.infobip.com/docs/rcs/get-started#registration). **What if RCS is not available in my target country?** RCS availability depends on carrier support. If RCS is not available, consider using [Infobip SMS](infobip-sms.md) as an alternative. **Do I need to configure anything on Infobip to receive RCS messages?** You just need to register and launch your RCS sender. After that, once you connect the RCS sender with Moveo, Moveo receives inbound RCS messages automatically by creating a [subscription](https://www.infobip.com/docs/cpaas-x/subscriptions-management). **What types of rich content can I send via RCS?** RCS supports images, videos, audio files, carousels, buttons, and more. The exact capabilities depend on the recipient's device and carrier support. You can find a list of supported features per carrier [here](https://www.infobip.com/docs/rcs/feature-parity). --- ## Limitations ### Platform constraints - **Carrier dependency** - RCS availability depends on mobile network operator support in each country - **Device requirements** - Recipients need RCS-enabled devices (Android with Google Messages or iPhone with iOS 18+) and a carrier that supports RCS - **Fallback behavior** - Messages may not have SMS fallback; consider using [Infobip SMS](./infobip-sms.md) for broader reach ### Content limitations - **File size limits** - Media files are subject to carrier-specific size restrictions - **Feature parity** - Not all RCS features are supported by all carriers - **Brand verification** - Sender registration and brand verification required before going live --- ## Next steps - [Infobip SMS](./infobip-sms.md) - Set up SMS as a fallback channel - [Campaigns](../campaigns/campaigns.md) - Send outbound RCS campaigns - [AI Agents overview](../ai-agents/overview.md) - Configure your agent for RCS conversations - [Analytics](../analytics/overview.md) - Monitor RCS message performance --- ## Infobip SMS ## Overview Infobip SMS integration transforms your AI Agent into a powerful SMS communication tool, enabling two-way conversations with customers through one of the world's leading cloud communication platforms. Infobip connects your business to mobile carriers globally, eliminating the need for direct telecom agreements while providing reliable, scalable SMS messaging. This integration enables: - **Two-way SMS conversations** with automated AI Agent responses - **Global reach** through Infobip's carrier network coverage - **Dedicated phone numbers** for your business messaging - **Enterprise-grade reliability** with high delivery rates - **Compliance support** for regional SMS regulations - **Seamless handover** to human agents when needed :::tip Recommended reading Review the [Infobip documentation](https://www.infobip.com/docs) to understand platform capabilities and regional requirements. ::: --- ## Prerequisites Before setting up the Infobip SMS integration, ensure you have: ✅ **Business requirements** - Active business with legitimate SMS use case - Business registration and contact information - Funds available for SMS messaging costs ✅ **Infobip account setup** - Active Infobip account with verified business details - SMS-capable phone number purchased through Infobip - API key with required permissions ✅ **Regional compliance** - Understanding of local SMS regulations - Required registrations (e.g., 10DLC for US) - Sender ID registration if applicable ✅ **Moveo account setup** - An active [AI Agent](../ai-agents/overview.md) configured - An [environment](../environments/overview.md) selected for the integration :::important US Requirements For United States messaging, 10DLC registration is mandatory. See the [10DLC registration guide](https://www.infobip.com/docs/10dlc/10dlc-registration). ::: --- ## How it works The Infobip SMS integration creates a seamless bridge between SMS messages and your AI Agent: 1. **Customer sends SMS** to your dedicated Infobip number 2. **Infobip receives message** and forwards to Moveo via webhook 3. **AI Agent processes** the message using your configured knowledge 4. **Response is generated** based on customer inquiry 5. **SMS is sent back** through Infobip's delivery network 6. **Conversation continues** with full context maintained 7. **Handover available** to human agents when AI cannot assist All messages are processed through Infobip's secure infrastructure with real-time delivery tracking and comprehensive analytics. --- ## Setup guide ### Step 1: Create and configure Infobip account To use Infobip with Moveo, you need an active Infobip account and a number that supports two-way SMS. Follow these steps: 1. Go to [infobip.com](https://www.infobip.com/) and select **Start free** or **Create account**. 2. Complete the sign-up process by entering your business details and verifying your email address. 3. After logging in, [add funds](https://www.infobip.com/docs/essentials/manage-my-account/payments#add-funds) to your Infobip account to enable messaging services. 4. In the **Numbers** section, [purchase a number](https://www.infobip.com/docs/numbers/getting-started#numbers-over-web-interface) with **SMS capability**. 5. Select a number that supports your target region. Depending on the country, Infobip may require additional **sender ID registration** or **number activation**. 6. Complete any required verification steps based on your region and use case. :::important For United States 10DLC numbers, number registration is mandatory. See the [10DLC registration guide](https://www.infobip.com/docs/10dlc/10dlc-registration) for more information. ::: #### Choosing the right number type Infobip offers several types of numbers depending on your region and use case. For the United States, see [10DLC vs. short codes vs. toll-free numbers](https://www.infobip.com/blog/10dlc-vs-short-codes-vs-toll-free-numbers) for a detailed comparison. To use Moveo, your number must support **two-way SMS**. One-way messaging or voice-only numbers are not supported. ### Step 2: Connect with Moveo Once your number is active, connect it to Moveo by following these steps. #### Gather required information You need the following details from your Infobip account: #### 1. API key You need to check these permissions in your API key: - `sms:manage` - `subscriptions:manage` - `numbers:manage` :::tip You can use the **default API key** visible on the Infobip homepage after logging in. ::: #### 2. Base URL **Base URL** of your Infobip environment (for example, `https://xyz.api.infobip.com`). #### 3. Number ID **Number ID** of your purchased phone number. To find this, go to the **Numbers** tab in Infobip, click your number, and copy the **ID** field. #### Complete Moveo setup Now to set up our Infobip SMS integration, we need to go to the Moveo platform and fill the fields with the information we gathered in the previous step. 1. In the Moveo platform, go to **Integrations → SMS**. 2. Click **Add Integration** and select **Infobip**. 3. Enter the required fields using the details from your Infobip account. 4. Click **Save** to complete the setup. Your AI Agent can now send and receive SMS messages using the connected number. --- ## Configuration options ### Number management - **Dedicated numbers**: Assign specific numbers to different AI Agents or use cases - **Sender ID**: Configure custom sender identification where supported - **Regional compliance**: Ensure proper registration for target markets - **Number pooling**: Use multiple numbers for high-volume messaging ### Message settings - **Character limits**: Configure message length and splitting behavior - **Delivery reports**: Enable tracking for message delivery status - **Retry logic**: Set up automatic retry for failed messages - **Rate limiting**: Configure sending frequency per regulations ### Security and authentication - **API key management**: Secure key storage and rotation - **Webhook validation**: Verify incoming message authenticity - **IP whitelisting**: Restrict API access to specific addresses - **SSL/TLS encryption**: Ensure secure message transmission --- ## Testing your integration ### Initial testing 1. **Send test SMS** to your Infobip number from a mobile phone 2. **Verify AI Agent response** arrives correctly 3. **Test message delivery** and timing 4. **Check character encoding** for special characters and emojis 5. **Validate handover scenarios** if configured ### Test scenarios ✓ **Basic conversation flow** ✓ **Long message handling** (concatenated SMS) ✓ **Special character support** ✓ **International number testing** ✓ **Error handling and fallbacks** ✓ **Delivery report processing** ### Monitoring and analytics - **Message delivery rates** through Infobip dashboard - **Response time metrics** for AI Agent processing - **Cost tracking** for SMS usage and optimization - **Conversation completion rates** and user satisfaction --- ## Common use cases ### Customer support via SMS - Handle support requests through familiar SMS interface - Provide instant answers to common questions - Collect customer information efficiently - Escalate to human agents when needed ### Appointment and booking management - Send appointment confirmations and reminders - Handle booking modifications and cancellations - Provide location and timing information - Collect feedback after appointments ### Order and delivery notifications - Send order confirmations and updates - Provide tracking information - Handle delivery scheduling - Process returns and refund requests ### Marketing and engagement - Send promotional messages (with consent) - Conduct surveys and collect feedback - Share product information and offers - Build customer relationships through conversation --- ## Best practices ### Message optimization - Keep messages concise and clear - Use plain text for maximum compatibility - Structure information logically - Provide clear next steps or options ### Compliance and regulations - Obtain proper consent for marketing messages - Provide easy opt-out mechanisms - Follow regional SMS regulations - Register numbers appropriately ### User experience - Set clear expectations about response times - Provide help commands and instructions - Handle errors gracefully with helpful messages - Maintain conversation context effectively ### Cost optimization - Monitor message length to avoid concatenation - Use message templates for common responses - Implement smart routing to reduce costs - Track and analyze usage patterns --- ## Troubleshooting
Messages not being delivered - Check Infobip account balance and funding - Verify API key permissions and validity - Confirm number is properly registered and active - Review delivery reports in Infobip dashboard - Test with different mobile carriers
AI Agent not responding - Verify integration is Active in Moveo - Check webhook connectivity and configuration - Confirm AI Agent is assigned to environment - Test with simple messages first - Review message format and encoding
Number registration issues - Review regional registration requirements - For US: Complete 10DLC registration process - Provide all required business documentation - Allow sufficient time for approval process - Contact Infobip support for status updates
High message costs - Review message length and concatenation - Optimize AI Agent responses for brevity - Check routing and carrier selection - Monitor usage patterns and peak times - Consider number type optimization
Character encoding problems - Test with different character sets - Verify Unicode support configuration - Check emoji and special character handling - Review message encoding settings - Test across different mobile devices
--- ## Limitations ### Platform restrictions - **Two-way SMS required**: Voice-only numbers not supported - **Character limits**: SMS length restrictions apply - **Regional availability**: Some countries have limited support - **Carrier dependencies**: Delivery rates vary by mobile operator ### Integration constraints - **Funding required**: Must maintain positive account balance - **Rate limiting**: Subject to carrier and regulatory limits - **Registration requirements**: Business verification needed for some regions - **Number provisioning**: Availability varies by region --- ## Frequently asked questions
Can I use an existing Infobip number? Yes, if the number supports **two-way SMS** and meets local compliance requirements.
What about US messaging requirements? You must register your 10DLC number or use a short code or toll-free number. See the [10DLC registration guide](https://www.infobip.com/docs/10dlc/10dlc-registration).
Can I use the service without adding credit? No. You must add credit to your Infobip account before sending SMS messages.
Is voice capability required for the number? No. Only **SMS capability** is required for this integration.
Do I need to configure webhooks in Infobip? No. Once integrated, Moveo handles inbound message processing automatically.
--- ## Resources ### Documentation - [Infobip SMS API](https://www.infobip.com/docs/sms) - [10DLC Registration Guide](https://www.infobip.com/docs/10dlc/10dlc-registration) - [Number Types Comparison](https://www.infobip.com/blog/10dlc-vs-short-codes-vs-toll-free-numbers) ### Tools - [Infobip Developer Portal](https://dev.infobip.com) - [Message Testing Tools](https://www.infobip.com/docs/essentials/test-your-integration) - [Delivery Reports Dashboard](https://www.infobip.com/docs/sms/reports) ### Support - [Infobip Support Center](https://help.infobip.com) - [Infobip Community](https://community.infobip.com) - Moveo support: support@moveo.ai --- ## Next steps Once your Infobip SMS integration is active: 1. **Complete number registration** for all target markets 2. **Optimize AI Agent responses** for SMS format constraints 3. **Set up monitoring** for delivery rates and costs 4. **Test thoroughly** across different carriers and regions 5. **Scale gradually** while monitoring performance and compliance --- --- ## Instagram Moveo.AI provides an out-of-the-box integration with Instagram, enabling your AI Agent to handle customer conversations through Instagram Direct Messages. ## How it works When you connect your Instagram account to Moveo: 1. Users send messages to your Instagram business profile 2. Moveo receives messages via the Meta (Facebook) API 3. Your AI Agent processes the message and generates a response 4. The response appears in the user's Instagram Direct Messages This integration uses Meta's Messenger Platform, which is why you need a Facebook Page linked to your Instagram account. ## Connect your Page ### Before you begin - Make sure that you have an [Instagram **professional** account](https://www.facebook.com/help/instagram/138925576505882). - You need to have a Facebook Page [**linked with your Instagram account**](https://www.facebook.com/business/help/connect-instagram-to-page). - Make sure that you have [Admin](https://www.facebook.com/help/289207354498410) access in the Facebook Page that is connected to your Instagram account. - Select an [environment](../environments/overview.md) in which you wish to connect your Instagram account. Depending on whether you have connected Facebook or Instagram to Moveo before, follow the corresponding guides outlined below: - [**First time** connecting an Instagram account](facebook-messenger.md#first-time-connection) - [Connecting **more than one** Instagram accounts](facebook-messenger.md#adding-additional-pages) ## First time connecting an Instagram account Follow the steps outlined below: 1. Click **Connect** to redirect to the _Meta Dialog Window_. 2. In the _Meta Dialog Window_, select **only one** Instagram account **and** its connected Facebook Page and grant **all** permissions to Moveo. 3. Once you complete the process in the _Meta Dialog Window_, you will be redirected back to Moveo, where you can [configure your integration](#configure-your-integration). ## Connecting more than one Instagram accounts If you have already connected an Instagram account to Moveo, then you **must keep your previously connected Instagram accounts and their linked Facebook Pages selected** in the _Meta Dialog Window_ to preserve an active connection. Follow the steps outlined below: 1. Click **Connect** to redirect to the _Meta Dialog Window_. 2. In the _Meta Dialog Window_, select **the new** Instagram account and its linked Facebook Page, while **keeping the old one(s) selected**. Grant **all** permissions to Moveo. 3. Once you complete the process in the _Meta Dialog Window_, you will be redirected back to Moveo, where you can [configure your integration](#configure-your-integration). --- ## Configure your integration Now that you have successfully connected your Instagram account to Moveo, it's time to configure it to meet your needs. Unlike Facebook Messenger, there are not many configuration options yet. ### Status To start receiving messages, you need to make your integration `Active`. ### Advanced security settings In some cases, the webview may need to exchange context with the AI Agent. To ensure that the data is secure, you need to create a pair of RS256 private/public keys. Add your public key in your integration in PEM format. --- ## Troubleshooting
Not Page Admin error You need Admin access to the Facebook Page linked to your Instagram account: - Check your role in Facebook Page settings - Request Admin access from current Page admin - Ensure Page is properly linked to Instagram account - Verify you're using the correct Facebook account
Permission errors All requested permissions must be granted in the Meta Dialog Window: - Review each permission carefully - Ensure all checkboxes are selected - Don't skip any permission requests - Re-authenticate if permissions were denied
Multiple account connection issues When connecting additional accounts: - Keep ALL previously connected accounts selected - Add only ONE new Instagram account - Select the corresponding Facebook Page - Don't deselect existing connections
Messages not being received - Verify integration is set to Active in Moveo - Check Instagram account is properly linked to Facebook Page - Ensure webhook permissions are granted - Confirm AI Agent is assigned to the environment
Responses not sending - Check Instagram account status and restrictions - Verify Facebook Page is published and active - Review Meta app permissions and status - Ensure no rate limits are being hit
--- ## Limitations ### Platform restrictions - **Professional account required**: Cannot use personal Instagram accounts - **Facebook Page dependency**: Must maintain active Facebook Page connection - **Meta's policies**: Subject to Instagram and Facebook business policies - **Message types**: Limited to text and basic media formats ### Integration constraints - **One account per environment**: Each Moveo environment supports one Instagram connection - **Admin access required**: Must maintain Admin role on connected Facebook Page - **Page connection**: Instagram account must remain linked to Facebook Page - **Business verification**: Some features require Meta Business verification --- ## Resources ### Documentation - [Instagram Business Guide](https://business.instagram.com/getting-started) - [Facebook Page Management](https://www.facebook.com/business/help/389645064451355) - [Meta Business Platform](https://developers.facebook.com/docs/instagram-basic-display-api/) ### Tools - [Instagram Professional Dashboard](https://www.facebook.com/business/tools/instagram-business) - [Facebook Page Settings](https://www.facebook.com/help/289207354498410) - [Meta Business Manager](https://business.facebook.com) ### Support - [Instagram Business Help](https://help.instagram.com/business) - [Meta Business Help](https://www.facebook.com/business/help) - Moveo support: support@moveo.ai --- ## Next steps Once your Instagram integration is active: 1. **Optimize your business profile** for customer engagement 2. **Test thoroughly** with different message types 3. **Configure handover rules** for complex inquiries 4. **Monitor Instagram insights** to track performance 5. **Train your team** on Instagram-specific workflows --- ## Intercom ## Overview Intercom has partnered with Moveo.AI to create a powerful integration that adds an intelligent AI Agent to your customer support team. This partnership enables seamless collaboration between AI and human agents, providing customers with instant, accurate responses while maintaining the personal touch of human support when needed. This integration enables: - **AI-powered teammate** that works alongside your human agents - **Seamless conversation handover** between AI and human agents - **24/7 customer support** with intelligent automation - **Unified inbox management** with all conversations in Intercom - **Custom workflows** for routing and escalation --- ## Prerequisites Before setting up the Intercom integration, ensure you have: ✅ **Intercom requirements** - Active Intercom workspace with admin access - Ability to add new teammates to your workspace - Access to conversation rules and workflows ✅ **Email account for AI Agent** - Dedicated, functional email address for your AI Agent - Access to receive and respond to invitation emails - Unique email not used for any other Intercom teammate ✅ **Moveo account setup** - An active [AI Agent](../ai-agents/overview.md) configured - An [environment](../environments/overview.md) selected for the integration --- ## How it works The Intercom integration treats your AI Agent as a teammate in your Intercom workspace: 1. **Customer sends message** through Intercom Messenger 2. **Workflow rules** assign conversation to AI Agent 3. **AI Agent processes** and responds based on your configuration 4. **Conversation continues** with AI handling routine inquiries 5. **Handover triggers** when human assistance is needed 6. **Unassigned inbox** receives escalated conversations 7. **Human agents** pick up seamlessly with full context All interactions are initiated through and managed by Intercom, maintaining your existing workflows. --- ## Video tutorial [![Intercom Example](https://img.youtube.com/vi/JDiz4OhMO_0/0.jpg)](https://www.youtube.com/watch?v=JDiz4OhMO_0) --- ## Setup guide ### Part 1: Intercom configuration 1. Create a functional email account for your assistant. Each assistant must have a valid, unique email address before it can be added to a team in Intercom. 2. From your Intercom workspace, add the assistant to your team as a new agent. Go to the teammate settings page in your Intercom workspace, and invite the assistant as a new agent by adding the email you created in the previous step to the invite field. 3. From the assistant email account you created earlier, find the invitation from Intercom. Click the link in the email to join the team. Sign up using the assistant's functional email address, and then join the team. 4. Optional: Update the profile for your assistant. You can edit the name and profile picture for your assistant. This profile represents the assistant in private agent communications within your workspace, and in public interactions with customers through your Intercom apps. Create a profile that reflects your brand. ### Part 2: Moveo configuration 1. Create an [AI Agent](../ai-agents/overview.md). 2. Create an [environment](../environments/overview.md) and connect the above AI Agent to it. 3. Add an Intercom Integration by redirecting to Intercom. :::caution In your Intercom app, you need to log in from the account of your assistant. ::: --- ## Configuration options ### Workflow configuration To test your integration, you need to modify your Intercom rules in order to assign the Moveo AI Agent to the conversations you wish. The following image shows an example where logged-in users are handled by Moveo, while logged-out users are shown the prompt to log in or sign up. When a handover is taking place, the assistant transfers the conversation to the `Unassigned` Inbox, in order for other live agents to take over the conversation. ### Custom attributes #### Automatic response tracking Moveo offers a specialized attribute designed to notify Intercom when the assistant has responded **more than** once. This feature can be valuable in scenarios where you intend to present a survey or pose a question to the user. To enable and use the custom attribute, follow the instructions below: 1. In your Intercom account, go to the **Conversation data** and select **Create a new conversation attribute**. Set the format to **boolean** and assign the name as follows: `Moveo AI: Replied twice` Include a description and save the attribute. 2. Initialize the attribute. In the trigger rule, you initialize the conversation. Set the default value of the attribute to `false`. 3. Create your feedback rule, enabling it to only trigger if the attribute is `true`. Here are some screenshots to help you understand how to set up this custom attribute. It's designed to trigger a survey for users who have asked at least two questions to Moveo but haven't responded afterwards. ### Media handling Moveo's AI Agent processes media uploads as text with URLs: #### How media upload works 1. User or agent uploads a file in Intercom messenger 2. Moveo converts it to text containing the attachment URL 3. AI Agent processes based on configured intents and dialogs #### Configuration for media handling Create an [intent](../ai-agents/intents.md) with these training phrases: `Visitor uploaded media URL: ` `Visitor uploaded media URL: https://downloads.intercomcdn.com/i/o/871967244/4b5102e0e8add69b54dbc896/example_attachment.jpg` Then create a [dialog](../ai-agents/dialogs.md) to define how your AI Agent responds to media uploads. --- ## Testing your integration ### Initial testing 1. **Send test message** as a customer to your Intercom messenger 2. **Verify AI Agent assignment** through your workflow rules 3. **Check response quality** and timing 4. **Test handover** by triggering escalation scenarios ### Test scenarios ✓ **Basic conversation flow** ✓ **Multiple question exchanges** ✓ **Media upload handling** ✓ **Handover to human agents** ✓ **Custom attribute triggers** ✓ **After-hours responses** --- ## Common use cases ### Customer support automation - Answer frequently asked questions instantly - Guide users through troubleshooting steps - Collect information before human handover - Provide 24/7 first-line support ### Lead qualification - Engage website visitors immediately - Qualify leads with targeted questions - Route qualified leads to sales team - Capture contact information automatically ### User onboarding - Welcome new users with personalized messages - Guide through initial setup steps - Answer product questions in real-time - Schedule demos or training sessions ### Survey and feedback collection - Trigger surveys after AI Agent interactions - Collect NPS scores automatically - Gather product feedback - Route feedback to appropriate teams --- ## Best practices ### AI Agent profile setup - Use a clear, recognizable name for your AI Agent - Add a professional profile picture - Write a description that sets expectations - Configure appropriate working hours ### Workflow optimization - Start with simple routing rules - Test thoroughly before complex workflows - Use custom attributes for advanced routing - Monitor and adjust based on performance ### Conversation management - Set clear handover criteria - Configure appropriate response times - Use the Unassigned inbox for escalations - Maintain conversation context during handovers ### Performance monitoring - Track AI Agent response metrics - Monitor handover rates - Review conversation quality regularly - Collect customer feedback on AI interactions --- ## Troubleshooting
AI Agent not receiving messages - Verify AI Agent is logged into Intercom - Check workflow rules are properly configured - Ensure integration is set to Active in Moveo - Confirm AI Agent has proper permissions
Handover not working properly - Check that Unassigned inbox is configured - Verify human agents are available - Review handover triggers in dialogs - Ensure proper workflow rules for escalation
Custom attribute not triggering - Verify attribute name matches exactly: "Moveo AI: Replied twice" - Check attribute is initialized to `false` in trigger rule - Ensure feedback rule checks for `true` value - Test with multiple message exchanges
Media uploads not processed - Verify intent is configured with proper training phrases - Check dialog handles media URL patterns - Test with different file types - Review URL format in received messages
--- ## Limitations ### Platform constraints - AI Agent requires dedicated email address - Cannot use same email for multiple workspaces - Limited to text-based interactions - Media files converted to URL references ### Integration requirements - Must maintain AI Agent as active teammate - Workflow rules required for proper routing - Custom attributes need exact naming - Handover requires Unassigned inbox setup --- ## Resources ### Documentation - [Intercom Teammates Guide](https://www.intercom.com/help/en/articles/179-add-remove-and-manage-teammates) - [Workflow Automation](https://www.intercom.com/help/en/articles/2806696-workflows-automate-repetitive-tasks) - [Custom Attributes](https://www.intercom.com/help/en/articles/179-create-and-manage-custom-data-attributes) ### Support - [Intercom Help Center](https://www.intercom.com/help) - Moveo support: support@moveo.ai --- ## Next steps Once your Intercom integration is active: 1. **Customize AI Agent profile** to match your brand 2. **Configure workflow rules** for optimal routing 3. **Set up custom attributes** for advanced features 4. **Train your team** on AI Agent capabilities 5. **Monitor performance** and optimize responses --- ## Integrations overview Integrations connect your AI Agent to the communication channels your customers already use. Once connected, your agent receives messages, processes them, and responds automatically—whether through web chat, messaging apps, SMS, email, or voice. In the Moveo platform UI, integrations are also called **Connections**. ## Web chat Embed your AI Agent directly on your website or application. | Channel | Description | |---------|-------------| | [Web](./web/getting-started.md) | Customizable chat widget for websites and web applications | ## Messaging apps Meet customers on the messaging platforms they use daily. | Channel | Description | |---------|-------------| | [WhatsApp](./whatsapp) | Reach customers on the world's most popular messaging app | | [Facebook Messenger](./facebook-messenger) | Connect through Facebook Pages | | [Instagram](./instagram-messenger) | Handle Direct Messages from your business profile | | [Viber](./viber) | Engage users on Viber | ## SMS & RCS Send and receive text messages with your customers. | Channel | Description | |---------|-------------| | [Infobip SMS](./infobip-sms.md) | SMS messaging via Infobip | | [Infobip RCS](./infobip-rcs.md) | Rich messaging with images, buttons, and carousels | | Twilio SMS | SMS messaging via Twilio *(coming soon)* | | Telnyx SMS | SMS messaging via Telnyx *(coming soon)* | ## Email Handle customer inquiries through email conversations. | Channel | Description | |---------|-------------| | [Email](./email) | Email-based customer conversations | ## Help desk platforms Integrate with your existing customer support tools. | Platform | Description | |----------|-------------| | [Intercom](./intercom) | Customer messaging and support | | [Zendesk Chat](./zendesk) | Zendesk live chat | | [Sunshine Conversations](./sunco) | Zendesk omnichannel messaging | | [Front](./front.md) | Shared inbox for teams | ## Sales & outreach Automate customer engagement in your sales workflows. | Platform | Description | |----------|-------------| | [Smartlead](./smartlead.md) | Sales automation and outreach | ## Voice Enable phone-based interactions with your AI Agent. | Channel | Description | |---------|-------------| | [Telnyx Voice](./telnyx-voice.md) | Phone call handling via Telnyx | | [Twilio Voice](./twilio-voice.md) | Phone call handling via Twilio | ## Team collaboration Deploy your AI Agent in internal communication tools. | Platform | Description | |----------|-------------| | [Slack](./slack.md) | Slack workspace integration | ## Custom integrations Build custom connections using the REST API. | Channel | Description | |---------|-------------| | [Custom](/api/custom-integration/custom-integration-overview) | Connect any system via REST API and webhooks | ## Next steps - [Web chat setup](./web/getting-started.md) - Get started with the most common integration - [WhatsApp setup](./whatsapp) - Connect to WhatsApp Business - [Environments](../environments/overview.md) - Understand how integrations work with environments - [AI Agents](../ai-agents/overview.md) - Configure the agent that powers your integrations --- ## Slack ## Overview Slack integration enables your AI Agent to communicate with team members and customers directly within Slack workspaces. As one of the most widely used workplace communication platforms, Slack provides a familiar environment where your AI Agent can handle inquiries, automate workflows, and provide instant support through direct messages and channel mentions. This integration enables: - **Direct message support** through the Messages tab in your bot's App Home - **Channel mentions** to trigger AI Agent responses with @mentions - **Rich message formatting** with Slack's native message capabilities - **File sharing** for sending and receiving documents - **Interactive components** including buttons and shortcuts --- ## Prerequisites Before setting up the Slack integration, ensure you have: ✅ **Slack requirements** - Slack workspace with administrative access - Permission to install apps to your workspace - [Slack API](https://api.slack.com/apps) account access ✅ **Moveo account setup** - An active [AI Agent](../ai-agents/overview.md) configured - An [environment](../environments/overview.md) selected for the integration --- ## How it works The Slack integration operates through Slack's Events API and Bot User functionality: 1. **User messages bot** via direct message or @mention in a channel 2. **Slack sends event** to Moveo via webhook 3. **AI Agent processes** the message and generates a response 4. **Response is delivered** back through Slack's messaging API 5. **Interactive elements** can trigger additional AI Agent flows 6. **Handover possible** to human agents when needed All messages are processed securely with Slack's signing secret verification ensuring message authenticity. --- ## Setup guide The integration requires configuration in both the Slack API platform and Moveo. ### Step 1: Create a Slack app 1. Navigate to [api.slack.com/apps](https://api.slack.com/apps) 2. Click **Create New App** 3. Select **From scratch** 4. Enter your app name and select the workspace to develop in 5. Click **Create App** ### Step 2: Customize your app 1. In the **Basic Information** section, customize your app's display settings 2. Add an app icon and description 3. Configure the app's color scheme to match your brand ### Step 3: Configure OAuth permissions 1. Navigate to **OAuth & Permissions** in the sidebar 2. Scroll to **Scopes** section 3. Under **Bot Token Scopes**, add the following permissions: | Permission | Description | | ---------------------- | ----------------------------------------------- | | `app_mentions:read` | View messages that directly mention your bot | | `channels:history` | View messages in public channels | | `chat:write` | Send messages as the bot | | `chat:write.customize` | Send messages with a custom username and avatar | | `files:read` | View files shared in channels and conversations | | `files:write` | Upload, edit, and delete files | | `groups:history` | View messages in private channels | | `im:history` | View messages in direct messages | | `im:write` | Start direct messages with users | | `mpim:history` | View messages in group direct messages | | `users:read` | View users in the workspace | | `users:read.email` | View email addresses of users | | `users:write` | Set user presence | ### Step 4: Install app to workspace 1. Scroll to the top of the **OAuth & Permissions** page 2. Click **Install to Workspace** 3. Review the permissions and click **Allow** 4. Copy the **Bot User OAuth Token** that appears after installation ### Step 5: Copy credentials 1. Navigate to **Basic Information** in the sidebar 2. Under **App Credentials**, locate the **Signing Secret** 3. Click **Show** and copy the signing secret 4. Keep both the signing secret and bot OAuth token ready for the next step ### Step 6: Configure App Home 1. Navigate to **App Home** in the sidebar 2. Enable **Always Show My Bot as Online** 3. Under **Show Tabs**, enable **Messages Tab** 4. Check **Allow users to send Slash commands and messages from the messages tab** --- ## Connect with Moveo ### Step 1: Create the integration 1. In Moveo, navigate to **Connections** 2. Locate and select **Slack** 3. Click **Connect** ### Step 2: Configure credentials 1. Paste the **Signing Secret** from your Slack app 2. Paste the **Bot User OAuth Token** 3. Configure additional settings as needed 4. Click **Save** 5. Copy the **Callback URL** provided by Moveo ### Step 3: Activate the integration Toggle the integration status to **Active**. --- ## Enable event subscriptions Return to your Slack app configuration to complete the webhook setup. ### Step 1: Configure Event Subscriptions 1. Navigate to **Event Subscriptions** in the sidebar 2. Toggle **Enable Events** to On 3. Paste the Moveo callback URL into the **Request URL** field 4. Wait for Slack to verify the URL (shows "Verified" checkmark) ### Step 2: Subscribe to bot events Under **Subscribe to bot events**, add the following events: | Event Name | Description | Required Scope | | ------------------ | ----------------------------------------------------------------- | ------------------- | | `app_mention` | Subscribe to only the message events that mention your app or bot | `app_mentions:read` | | `message.channels` | A message was posted to a channel | `channels:history` | | `message.groups` | A message was posted to a private channel | `groups:history` | | `message.im` | A message was posted in a direct message channel | `im:history` | | `message.mpim` | A message was posted in a multiparty direct message channel | `mpim:history` | Click **Save Changes** after adding all events. ### Step 3: Enable Interactivity 1. Navigate to **Interactivity & Shortcuts** in the sidebar 2. Toggle **Interactivity** to On 3. Paste the same Moveo callback URL into the **Request URL** field 4. Click **Save Changes** Your AI Agent is now ready to respond to messages in Slack. --- ## Configuration options ### Bot profile settings - **Bot name**: Display name shown to users in Slack - **Avatar**: Profile image for your bot - **Status**: Always online visibility setting ### Message configuration - **Autostart message**: Initial greeting when users open a DM - **Response formatting**: Slack markdown and block kit support - **File handling**: Configure file upload and sharing behavior ### Channel settings - **Direct messages**: Enable DM conversations with users - **Channel mentions**: Respond when @mentioned in channels - **Private channels**: Access to private channel messages (requires invitation) --- ## Testing your integration ### Initial testing 1. **Open Slack** and navigate to your workspace 2. **Find your bot** in the Apps section 3. **Send a direct message** to test basic functionality 4. **@mention your bot** in a channel to test mentions 5. **Verify responses** are accurate and timely ### Test scenarios - Direct message conversations - Channel @mentions and responses - Multi-turn conversations - Interactive button responses - Error handling and fallbacks --- ## Common use cases ### Internal helpdesk - Answer employee questions about policies and procedures - Provide instant IT support for common issues - Guide employees through HR processes - Automate onboarding information delivery ### Customer support in shared channels - Engage with customers in Slack Connect channels - Provide instant answers to product questions - Escalate complex issues to human agents - Maintain support presence outside business hours ### Workflow automation - Trigger automated processes through conversation - Collect information for form submissions - Provide status updates on requests - Integrate with other business systems --- ## Best practices ### Bot configuration - Use a clear, recognizable bot name and avatar - Set the bot to always appear online for availability - Configure helpful initial messages - Maintain consistent brand voice ### Message optimization - Keep responses concise for the Slack format - Use Slack formatting (bold, lists, code blocks) effectively - Provide clear action buttons when appropriate - Include helpful links and resources ### Channel management - Add the bot to relevant channels proactively - Set clear expectations about bot capabilities - Provide easy access to human support - Monitor bot performance across channels --- ## Troubleshooting
Bot not responding to messages - Verify the signing secret and OAuth token are correct - Check that the integration is set to Active in Moveo - Confirm event subscriptions are enabled and verified - Ensure the bot has been added to the channel (for channel messages) - Check that required scopes are properly configured
URL verification failing - Ensure you're using the exact callback URL from Moveo - Check that the Moveo integration is saved before verification - Verify there are no extra spaces in the URL - Try refreshing the Slack app settings page
Bot not appearing online - Verify "Always Show My Bot as Online" is enabled in App Home - Check that the bot OAuth token is valid - Reinstall the app to the workspace if needed
Missing messages from channels - Ensure the bot has been invited to the channel - Verify `channels:history` or `groups:history` scopes are added - Check that `message.channels` or `message.groups` events are subscribed - For private channels, confirm bot membership
Cannot send direct messages - Verify `im:write` scope is configured - Check that the Messages Tab is enabled in App Home - Ensure "Allow users to send Slash commands and messages" is checked
--- ## Limitations ### Platform constraints - **Workspace access required** - Users must be members of the Slack workspace to interact with your bot - **Rate limits** - Slack enforces API rate limits; high-volume deployments may require optimization - **Message history** - Bot cannot access messages sent before it was added to a channel - **Threading** - Responses in threads require specific handling for consistent experience ### Integration constraints - **One workspace per integration** - Each Moveo integration connects to a single Slack workspace - **Bot permissions** - Capabilities are limited to granted OAuth scopes - **Private channels** - Bot must be explicitly invited to access private channels - **Enterprise Grid** - May require additional configuration for multi-workspace deployments --- ## Resources ### Documentation - [Slack API Documentation](https://api.slack.com/docs) - [Bot Users Guide](https://api.slack.com/bot-users) - [Events API Reference](https://api.slack.com/events-api) ### Support - [Slack Help Center](https://slack.com/help) - Moveo support: support@moveo.ai --- ## Next steps Once your Slack integration is active: 1. **Invite the bot** to relevant channels in your workspace 2. **Test conversations** across DMs and channel mentions 3. **Configure welcome messages** for optimal first impressions 4. **Train your team** on how to interact with the AI Agent 5. **Monitor usage** and optimize responses based on feedback --- ## Smartlead Smartlead is a supported channel in Moveo that enables you to send cold emails to your leads and handle replies seamlessly. Moveo connects to your Smartlead account and leverages [AI Agents](../ai-agents/overview.md) to manage incoming responses from leads. ## Getting started Before proceeding, ensure you have a Smartlead account with a **PRO** plan. This is necessary because it is the only plan that supports API and webhook usage. ### API key To allow Moveo to use the Smartlead API, you must first obtain an API key. 1. Log in to your Smartlead account. 2. Go to the **Settings** page. 3. In the **Your profile** section, scroll down to the **API** settings. 4. Copy the **API key**. ### Moveo setup Once you have the API key, set up the integration in Moveo. 1. Navigate to **Deploy** → **Integrations**. 2. Click on the **Smartlead** integration. 3. Enter the API key you copied earlier. 4. Click the **Save** button. 5. Copy the **Webhook URL**. ### Configure webhook The final step is to configure the webhook in Smartlead. Webhooks can be set at multiple levels, and Smartlead offers different types for each. In this example, we’ll configure it at the account level. Regardless of the level, the event type that Moveo listens for is **Email Reply**. You can learn more about this in the [Smartlead documentation - Webhooks](https://helpcenter.smartlead.ai/en/articles/35-webhook-guide). 1. In your Smartlead account, go to **Settings** → **Webhooks**. 2. Click the **Add Webhook** button. 3. Enter the **Webhook URL** you copied earlier. 4. Select **Email Reply** as the event type. 5. Click the **Save** button. ## Using the integration :::note Sending email campaigns from Moveo is not yet supported. ::: Campaigns must be created and sent directly from Smartlead. When a potential lead replies to an email, the webhook is triggered and Moveo receives the reply. You can use [rules](../environments/rules.md) to route the reply to an [AI Agent](../ai-agents/overview.md), or assign a [department](../chat/departments.md) if you prefer a [human agent](../chat/overview.md) to handle the response. :::info Rule configuration The first email sent by the campaign is included in the conversation. When creating rules for Smartlead, use **A customer responds to a message** as the trigger in the `When` clause. Using "A customer starts a conversation" will not match Smartlead sessions. ::: --- ## Configuration options ### Webhook configuration levels Smartlead offers webhook configuration at multiple levels. Choose based on your organizational needs: - **Account level**: Apply to all campaigns across your account - **Campaign level**: Specific to individual campaigns - **Client level**: For agency accounts managing multiple clients ### Event type selection For Moveo integration, always select **Email Reply** as the event type. This ensures all lead responses are captured and processed by your AI Agent. ### Response routing Configure how lead responses are handled: - **[Departments](../chat/departments.md)**: Direct qualified leads to specific human teams - **Mixed approach**: Use AI for initial qualification, humans for closing - **[Rules](../environments/rules.md)**: Automatically route replies to appropriate AI Agents --- ## Testing your integration ### Initial testing 1. **Send test campaign** to a controlled email address 2. **Reply to the test email** with various types of responses 3. **Verify webhook delivery** in Moveo event logs 4. **Check AI Agent responses** for accuracy and context 5. **Confirm email thread continuity** in Smartlead inbox ### Test scenarios ✓ **Positive lead responses** (interested prospects) ✓ **Objection handling** (price, timing, need concerns) ✓ **Information requests** (product details, demos) ✓ **Unsubscribe requests** (compliance handling) ✓ **Out-of-office responses** (automated reply detection) ✓ **Handover scenarios** (qualified lead routing) ### Monitoring - **Webhook delivery success** in Smartlead dashboard - **Response quality and relevance** from AI Agent - **Lead progression tracking** through conversation stages - **Conversion rates** from reply to qualified lead --- ## Common use cases ### Lead qualification automation - Automatically qualify inbound responses based on criteria - Ask qualifying questions to determine fit - Score leads based on responses and behavior - Route qualified leads to appropriate sales teams ### Objection handling at scale - Address common objections automatically - Provide relevant case studies and social proof - Offer alternatives and compromises - Schedule follow-ups for objection resolution ### Demo and meeting scheduling - Respond to meeting requests instantly - Integrate with calendar systems for availability - Send meeting confirmations and reminders - Handle rescheduling requests automatically ### Product information delivery - Answer product questions with detailed information - Share relevant case studies and testimonials - Provide pricing information when appropriate - Offer free trials or demos --- ## Best practices ### AI Agent training - Train on common sales objections and responses - Include product knowledge and competitive positioning - Configure appropriate handover triggers - Maintain consistent brand voice and messaging ### Campaign design - Design campaigns that encourage responses - Include clear value propositions - Use compelling subject lines and CTAs - Segment audiences for personalized approaches ### Response optimization - Keep initial AI responses concise and valuable - Ask one question at a time to maintain engagement - Provide clear next steps in every interaction - Use personalization tokens when possible ### Integration management - Monitor webhook health and delivery rates - Regularly review and update AI Agent responses - Track lead progression and conversion metrics - Maintain proper email deliverability practices --- ## Operational workflow ### Campaign execution :::note Campaign management Email campaigns must be created and sent directly from Smartlead. Moveo handles only the response management. ::: 1. **Create and launch campaigns** in Smartlead 2. **Leads receive emails** from your campaigns 3. **Replies trigger webhooks** to Moveo automatically 4. **AI Agent processes** and responds appropriately 5. **Qualified leads** are routed to human agents 6. **Follow-up sequences** continue based on engagement ### Response processing When leads reply: 1. **Webhook delivers** reply content to Moveo 2. **AI Agent analyzes** reply intent and context 3. **Response is generated** based on configured knowledge 4. **Reply is sent** back through Smartlead API 5. **Email thread** continues seamlessly 6. **Context is maintained** for subsequent interactions --- ## Troubleshooting :::warning Delivery timing Before troubleshooting, confirm that the reply has arrived in the Smartlead inbox. Due to Smartlead's deliverability algorithms and email provider delays, replies might be delayed up to 2 hours (especially with Outlook). Once the reply reaches Smartlead, the webhook should trigger. :::
Webhook not receiving events - Ensure webhook URL matches exactly between Smartlead and Moveo - Verify only one webhook is configured per level (account/campaign/client) - Check webhook URL is accessible and returns proper response codes - Review [Smartlead webhooks troubleshooting](https://helpcenter.smartlead.ai/en/articles/229-webhook-not-sending-triggers) - Test webhook manually using Smartlead's testing tools
AI Agent not responding to leads - Verify integration is Active in Moveo - Check AI Agent is properly assigned to environment - Confirm rules or departments are configured correctly - Review webhook event logs for delivery confirmation - Test with simple email replies first
Responses not appearing in email thread - Verify API key has proper permissions - Check API rate limits and quotas - Ensure email thread ID is being preserved - Review Smartlead inbox for delivery status - Test API connectivity manually
Poor AI response quality - Review and improve AI Agent training data - Configure more specific conversation rules - Adjust response templates and knowledge base - Monitor lead feedback and iterate - Consider human agent handover thresholds
High volume processing issues - Check webhook processing capacity - Monitor API rate limits on both platforms - Consider implementing message queuing - Scale AI Agent processing resources - Review and optimize response generation time
--- ## Limitations ### Platform restrictions - **PRO plan required**: API and webhook access limited to PRO plans - **Campaign management**: Must create campaigns in Smartlead (not Moveo) - **Email provider delays**: Response timing dependent on email infrastructure - **Webhook limitations**: Single webhook per configuration level ### Integration constraints - **Outbound campaigns**: Moveo cannot send initial cold emails - **Email formatting**: Limited to text-based responses - **Thread dependency**: Requires proper email thread maintenance - **Deliverability**: Subject to email provider and domain reputation --- ## Resources ### Documentation - [Smartlead API Documentation](https://smartlead.ai/api-docs) - [Smartlead Webhook Guide](https://helpcenter.smartlead.ai/en/articles/35-webhook-guide) - [Smartlead Help Center](https://helpcenter.smartlead.ai) ### Tools - [Smartlead Dashboard](https://smartlead.ai/dashboard) - [Webhook Testing Tools](https://helpcenter.smartlead.ai/en/articles/229-webhook-not-sending-triggers) - [API Rate Limit Monitor](https://smartlead.ai/api-docs#rate-limits) ### Support - [Smartlead Support](https://smartlead.ai/support) - [Smartlead Community](https://community.smartlead.ai) - Moveo support: support@moveo.ai --- ## Next steps Once your Smartlead integration is active: 1. **Launch test campaigns** to validate response handling 2. **Train your AI Agent** on sales conversations and objections 3. **Configure qualification rules** for lead routing 4. **Monitor response quality** and iterate on AI Agent training 5. **Scale campaigns gradually** while monitoring performance and deliverability --- ## Sunshine Conversations ## Overview Sunshine Conversations (formerly Smooch) integration brings conversational AI directly into Zendesk's messaging platform, creating a unified customer experience across multiple messaging channels. Through Zendesk's Bot Marketplace, your AI Agent operates as an intelligent bot that can handle conversations while seamlessly integrating with your support team's workflow. This integration enables: - **Multi-channel messaging support** through Zendesk's unified platform - **Bot Marketplace integration** with official Moveo bot - **Seamless handover** with automatic ticket creation - **Unified agent dashboard** for AI and human conversation management - **Context preservation** across bot and agent interactions - **Enterprise messaging features** including web widget and mobile SDK --- ## Prerequisites Before setting up the Sunshine Conversations integration, ensure you have: ✅ **Zendesk requirements** - **Zendesk Pro plan** or higher (required for Sunshine Conversations) - Administrator access to Zendesk Admin Center - Sunshine Conversations enabled in your account ✅ **Messaging setup** - Zendesk messaging channels configured - Web Widget or mobile messaging active - Understanding of your customer communication channels ✅ **Moveo account setup** - An active [AI Agent](../ai-agents/overview.md) configured - An [environment](../environments/overview.md) selected for the integration :::note Plan requirement Sunshine Conversations requires Zendesk Pro plan or higher. Basic and Team plans do not include messaging capabilities. ::: --- ## How it works The Sunshine Conversations integration operates through Zendesk's Bot Marketplace with direct AI Agent connectivity: 1. **Customer initiates conversation** through any connected messaging channel 2. **Zendesk receives message** and routes to configured channels 3. **Moveo bot engages** based on routing rules and availability 4. **AI Agent processes** message and responds through bot interface 5. **Conversation continues** with AI handling inquiries automatically 6. **Handover triggers** when human assistance is needed 7. **Ticket is created** automatically for human agent follow-up 8. **Context is preserved** throughout the conversation lifecycle All interactions are managed within Zendesk's unified platform while leveraging Moveo's AI capabilities. --- ## Setup guide The integration involves configuration in both Moveo and Zendesk platforms: ### Step 1: Configure Moveo integration 1. Go to your **Integrations** and select **Configure** on Sunshine Conversations. 2. Select **Connect**. 3. Fill in your Zendesk subdomain to sign in. 4. Authorize Moveo to access your account. 5. Configure your settings, such as the name of the assistant, the autostart message, and the avatar. ### Step 2: Set up Zendesk bot connection 1. Go to your Zendesk Admin Center. 2. Navigate to **Channels > Bots & automation > Bots**. Locate the Moveo bot under Marketplace bots and click the **Connect** button. 3. Navigate to **Channels > Messaging & social > Messaging** and configure your customer-facing integrations. --- ## Configuration options ### Bot settings - **Assistant name**: Display name for your AI Agent in conversations - **Autostart message**: Initial message sent when conversations begin - **Avatar**: Visual representation of your AI Agent - **Response behavior**: Configure how the bot interacts with customers ### Channel configuration - **Web Widget**: Configure appearance and behavior in web chat - **Mobile messaging**: Set up in-app or SDK-based messaging - **Third-party channels**: Connect external messaging platforms - **Routing rules**: Define when and how the bot should engage ### Handover management - **Trigger conditions**: Configure when to escalate to human agents - **Ticket creation**: Automatic support ticket generation - **Agent assignment**: Route tickets to appropriate teams - **Context transfer**: Preserve conversation history during handover --- ## Testing your integration ### Initial testing 1. **Send test messages** through your configured messaging channels 2. **Verify bot engagement** and response quality 3. **Test handover scenarios** to ensure smooth transitions 4. **Check ticket creation** in Zendesk Support 5. **Validate conversation history** preservation ### Test scenarios ✓ **Multi-channel messaging** (web, mobile, third-party) ✓ **AI Agent conversation flow** ✓ **Handover trigger activation** ✓ **Ticket creation and assignment** ✓ **Agent takeover experience** ✓ **Conversation history continuity** ### Performance monitoring - **Bot engagement rates** across different channels - **Handover frequency** and success rates - **Ticket resolution times** after handover - **Customer satisfaction** with bot interactions --- ## Common use cases ### Multi-channel customer support - Provide consistent AI support across web, mobile, and messaging platforms - Handle routine inquiries automatically - Escalate complex issues with full context - Maintain unified conversation history ### Lead qualification and routing - Engage website visitors through messaging widget - Qualify leads through conversational AI - Route qualified prospects to sales teams - Create tickets for follow-up actions ### After-hours support - Provide 24/7 AI support when agents unavailable - Handle urgent inquiries automatically - Create tickets for next business day follow-up - Maintain service level standards ### Self-service automation - Guide customers through common processes - Provide instant answers to FAQs - Collect information for support requests - Reduce agent workload through automation --- ## Best practices ### Bot configuration - Use clear, professional bot name and avatar - Configure engaging autostart messages - Set appropriate response expectations - Maintain consistent brand voice ### Handover optimization - Define clear escalation criteria - Configure appropriate triggers for complex issues - Ensure smooth context transfer to agents - Monitor handover success rates ### Channel management - Configure channels based on customer preferences - Maintain consistent experience across platforms - Monitor channel-specific performance - Optimize routing rules for efficiency ### Team coordination - Train agents on bot capabilities and limitations - Establish clear handover procedures - Regular review of bot performance - Continuous improvement of AI responses --- ## Advanced configuration ### Automatic ticket closure Any time a conversation gets handed over by Moveo, Sunshine Conversations automatically creates a ticket in Zendesk that your support team can handle. Note that the control of the conversation is returned to Moveo when a ticket is **Closed**. However, when an agent **solves** a conversation, the conversation does not close automatically. To achieve this, you need to create a trigger in Zendesk: 1. Navigate to **Admin Center > Objects and rules > Business rules > Triggers**. 2. Add a new trigger to specify the conditions under which a conversation is considered resolved and should be closed. The trigger below ensures that when a ticket's status is changed to **Solved**, if the conversation is on messaging channels (or any other channels you use in Zendesk), the status should become **Closed**. --- ## Troubleshooting
Bot not responding in channels - Verify Moveo bot is connected in Zendesk Bot Marketplace - Check messaging channels are properly configured - Confirm integration is Active in Moveo - Review bot routing rules and conditions - Test with different messaging channels
Handover not creating tickets - Verify handover triggers are properly configured - Check Zendesk Support integration is active - Confirm agent permissions for ticket access - Review trigger conditions and rules - Test handover scenarios manually
Tickets not closing automatically - Implement the ticket closure trigger as described above - Verify trigger conditions match your workflow - Check that agents are marking tickets as "Solved" - Test trigger activation with sample tickets - Review Zendesk trigger logs for errors
Conversation context lost during handover - Check conversation history preservation settings - Verify ticket creation includes full context - Review agent dashboard for conversation details - Test context transfer with sample conversations - Ensure proper integration configuration
Authorization issues - Verify Zendesk subdomain is correct - Check administrator permissions in Zendesk - Re-authorize Moveo access if needed - Review OAuth connection status - Test with different administrator account
--- ## Limitations ### Platform requirements - **Pro plan minimum**: Zendesk Pro plan or higher required - **Sunshine Conversations**: Must be enabled in your Zendesk account - **Bot marketplace**: Limited to official Moveo bot from marketplace - **Channel dependencies**: Subject to Zendesk messaging channel availability ### Integration constraints - **Ticket dependency**: Handover requires ticket creation - **Agent availability**: Human handover depends on agent status - **Channel limitations**: Some third-party channels may have restrictions - **Context format**: Conversation history format determined by Zendesk --- ## Disconnection procedure To safely disconnect your Sunshine Conversations integration: ### Step 1: Zendesk cleanup 1. Navigate to **Admin Center > Channels > Bots & automation > Bots** 2. Locate Moveo bot under Marketplace bots 3. Select **Uninstall** to remove bot connection 4. Confirm removal in Zendesk interface ### Step 2: Moveo cleanup 1. Go to your Moveo integration settings 2. Locate Sunshine Conversations integration 3. Select the **Delete** button (only available after Zendesk disconnection) 4. Confirm removal to complete disconnection :::caution Always uninstall the bot from Zendesk first, then delete the integration in Moveo to avoid orphaned connections. ::: --- ## Resources ### Documentation - [Sunshine Conversations Documentation](https://support.zendesk.com/hc/en-us/sections/360012725594) - [Zendesk Messaging Guide](https://support.zendesk.com/hc/en-us/categories/360002176374) - [Bot Marketplace](https://support.zendesk.com/hc/en-us/articles/4408886469146) ### Tools - [Zendesk Admin Center](https://support.zendesk.com/hc/en-us/articles/4408843597850) - [Messaging Configuration](https://support.zendesk.com/hc/en-us/categories/360002176374) - [Trigger Management](https://support.zendesk.com/hc/en-us/articles/203662156) ### Support - [Zendesk Support](https://support.zendesk.com) - [Sunshine Conversations Help](https://support.zendesk.com/hc/en-us/sections/360012725594) - Moveo support: support@moveo.ai --- ## Next steps Once your Sunshine Conversations integration is active: 1. **Configure messaging channels** for optimal customer reach 2. **Set up ticket closure automation** for efficient workflow 3. **Train your team** on bot handover procedures 4. **Monitor performance metrics** across channels 5. **Optimize AI responses** based on conversation analytics --- ## Telnyx Voice ## Overview The Telnyx Voice integration enables your AI Agent to handle voice conversations over phone calls. By connecting your Telnyx account to Moveo, you can provide automated voice support that combines the power of AI with natural speech interaction. This integration supports automated phone support through your Telnyx phone numbers, outbound calling through campaigns, natural voice interactions with text-to-speech and speech-to-text capabilities, and flexible configuration to optimize voice quality and recognition accuracy. --- ## Prerequisites Before setting up the Telnyx Voice integration, you'll need to configure both your Telnyx account and your Moveo setup. ### Telnyx account You'll need an active Telnyx account with voice capabilities enabled and sufficient balance to cover voice call costs. All Telnyx-side values are collected from the [Mission Control Portal](https://portal.telnyx.com). #### API key Moveo uses a Telnyx API v2 key to place calls, control them, and provision the voice resources described in [What Moveo configures in your Telnyx account](#what-moveo-configures-in-your-telnyx-account). [Create the key](https://developers.telnyx.com/development/api-fundamentals/create-api-keys) in the Telnyx portal under **API Keys**. :::warning Copy the API key when it's created. Telnyx shows the value only once. The key also cannot be changed after you save the integration: to use a different key, delete the integration and create a new one. ::: #### Public key Telnyx [signs every webhook](https://developers.telnyx.com/development/api-fundamentals/webhooks/receiving-webhooks#webhook-signing) it sends to Moveo, and Moveo verifies that signature before acting on the call. Copy the public key from the **Public Key** page, in the same **API Keys** section of the Telnyx portal. Telnyx exposes a single public key for your organization. :::warning Moveo checks your API key when you enter it, but it cannot check the public key. If the public key is wrong, the integration still saves, and Moveo then rejects every webhook Telnyx sends, so calls are never answered. Copy it exactly. ::: #### Account level Telnyx applies limits per [account level](https://developers.telnyx.com/docs/account-setup/account-upgrade), and the lower levels are not usable for production voice. An account belongs to either the Pretrial to Verified ladder or the Level 1 and Level 2 framework, never both: - **Pretrial** accounts have no access to Call Control Applications, which this integration requires. Upgrade before configuring the integration. - **Trial** accounts are limited to a single outbound voice profile, restrict calls to a verified phone number, cap call duration at 10 minutes, and allow 2 concurrent outbound calls. See [trial limitations](https://developers.telnyx.com/docs/account-setup/levels-and-capabilities/trial). - **Paid** accounts allow 5 concurrent outbound calls. Reaching 10 requires completing verification, and higher limits are available from Telnyx on request. See [concurrent call limits](https://developers.telnyx.com/docs/voice/sip-trunking/configuration/concurrent-limits). - **Level 1** accounts cap outbound calling at 100 calls per day and 10 calls per hour, which is not enough for a campaign. See [L1 restrictions](https://developers.telnyx.com/docs/voice/programmable-voice/l1-accounts-restirctions). :::warning Verify your Telnyx account before going live Below the **Verified** level, Telnyx prepends an automated-call announcement to machine-generated speech, so your callers hear a Telnyx fraud notice before the AI Agent. This applies to paid accounts too, not only trials. Completing verification also lifts the concurrency and destination limits. ::: #### Phone number Connect a [Telnyx number, or a number you've ported to Telnyx](https://developers.telnyx.com/docs/numbers/phone-numbers/getting-started), to receive incoming calls and to place campaign calls. A Telnyx number can only be assigned to one connection at a time, so numbers already in use elsewhere in your Telnyx account cannot be selected in Moveo. :::warning Without a phone number the integration cannot answer incoming calls or place campaign calls. Leave **Phone** set to **None** only if you plan to add the number later. ::: ### Moveo account The configuration steps for connecting your AI Agent to Telnyx are handled through Moveo's platform. For a complete walkthrough of the Moveo-side setup including AI Agent selection, environment configuration, and rule creation, see the [quick deployment guide](../guides/quick-start.md). --- ## How it works The Telnyx Voice integration creates a bridge between callers and your Moveo AI Agent. When someone dials your Telnyx phone number, Telnyx notifies Moveo, Moveo answers the call, and Telnyx starts streaming the call audio. The speech-to-text engine converts spoken words into text, which your AI Agent processes to generate an appropriate response. That response is then converted back to natural voice through text-to-speech and streamed to the caller in real-time. For outbound calls the flow is similar. A campaign asks Telnyx to dial the customer, and when the customer answers, the same speech processing and response cycle occurs. The conversation continues until the caller hangs up, or the AI Agent decides that the conversation has been resolved. ### What Moveo configures in your Telnyx account Once you save the integration with valid credentials, Moveo creates the Telnyx resources the AI Agent needs and keeps them in sync: - An [**outbound voice profile**](https://developers.telnyx.com/docs/voice/sip-trunking/configuration/outbound-voice-profiles) that authorizes outbound calling. - A [**voice API application**](https://developers.telnyx.com/docs/voice/programmable-voice/voice-api-fundamentals) whose webhook points at Moveo, so Telnyx notifies Moveo about incoming calls and call events. - The **connection resources** used for call control. - The **phone number assignment** that binds the number you selected to that application. Moveo re-checks these resources periodically and removes them when you delete the integration. :::warning Don't rename, delete, or repoint the Telnyx resources that Moveo creates. The integration stops working until the expected configuration is restored, so if one of them was changed, delete and save the integration again to have Moveo recreate it. ::: The outbound voice profile that Moveo creates covers the common destination countries. If your campaign targets a country that isn't enabled, contact Moveo support. Telnyx also gates many destinations behind account verification, so verify your Telnyx account before dialing outside the United States and Canada. ### Reaching your AI Agent Once the integration is configured, users can reach your AI Agent in two ways: **Inbound calls**: Customers can call your Telnyx phone number directly to start a conversation with your AI Agent. This is particularly useful for customer support hotlines or IVR systems where users initiate contact. **Outbound calls**: Your AI Agent can also call customers as part of a [campaign](../campaigns/campaigns.md). This enables proactive outreach for appointment reminders, notifications, surveys, or follow-ups, with the AI Agent handling the conversation when the customer answers. --- ## Call termination and handover Apart from the caller hanging up, a call ends in one of two ways, both controlled from the AI Agent's workflow. When the AI Agent resolves the conversation, the platform hangs up the call within a couple of seconds. - **Resolve**: the [`Resolve`](../ai-agents/operations/resolve.md) action marks the conversation as completed. The call leg closes within a couple of seconds, whatever the environment's [Keep alive](../guides/timeouts.md#keep-alive) value. - **Handover**: the [`Handover`](../ai-agents/operations/handover.md) action transfers the active call to a phone number or SIP URI, via a **Standard transfer** (Moveo stays on the call) or **SIP REFER** (Moveo hands off to your SIP system and drops off). Optional custom SIP headers can be attached for SIP destinations. See [Voice call transfer](./voice-call-transfer.md). To make voice calls behave predictably at the end of a conversation, apply the following checklist to every voice-enabled environment: - Leave **Keep alive** as it is. It does not affect voice call termination. See [Keep alive for voice integrations](../guides/timeouts.md#voice-integrations). - Add a [`Pause`](../ai-agents/operations/pause.md) action of **1–2 seconds** immediately before any `Resolve` or `Handover` action so the AI Agent's final sentence is not clipped. --- ## Setup guide ### Step 1: Prepare your Telnyx credentials 1. Log in to the [Mission Control Portal](https://portal.telnyx.com) and open [**API Keys**](https://portal.telnyx.com/#/app/api-keys). 2. On the **API Keys** page, click **Create API Key** and copy the key immediately. 3. Open **Public Key** in the same section and copy the public key. Keep both values handy for the next step. ### Step 2: Configure the integration in Moveo Navigate to **Connections** in your Moveo account, select your environment, find the **Telnyx Voice** integration card, and click **Configure**. ### Step 3: Enter your Telnyx account details Enter your credentials in the **Account** section of the configuration panel: **API Key**: the Telnyx API v2 key from the previous step. Moveo checks the key as you type and reports whether Telnyx accepts it. **Public Key**: the public key of the same Telnyx account, used to verify webhook signatures. Moveo cannot validate this one, so copy it exactly. Once the API key is verified, a **Phone** field appears so you can connect a number to the AI Agent. Numbers are grouped to show what you can pick: | Group | Meaning | |-------|---------| | **Available** | Telnyx numbers in your account that aren't attached to another connection | | **Verified caller ID** | Numbers you own elsewhere and have verified in Telnyx, usable for outbound calls only | | **In use** | Already taken, so they can't be selected: a Telnyx number attached to another connection, or a verified caller ID used by another Moveo integration | Only numbers that are **active** in Telnyx are listed, up to the first 250. Select a number to let the integration answer incoming calls to it and place campaign calls from it. A verified caller ID is the exception, since it works for outbound calls only, so read [Choose the caller ID for outbound calls](#step-4-choose-the-caller-id-for-outbound-calls) before picking one. ### Step 4: Choose the caller ID for outbound calls Which number your customers see on outbound campaign calls depends on the kind of number you selected: **A Telnyx number** is the recommended option, because it handles incoming and outgoing calls. For calls to the United States and Canada, Telnyx also signs numbers you own at the highest [STIR/SHAKEN attestation](https://developers.telnyx.com/docs/voice/stir-shaken/attestation-behavior) level, **A**, which lowers the chance that carriers block or label the call. **A verified caller ID** is a number you own with another provider and have registered under [**Numbers** → **Verified numbers**](https://support.telnyx.com/en/articles/6988813-verified-numbers) in the Telnyx portal. Keep two constraints in mind: - It works for outbound campaigns only. Incoming calls to that number keep routing through your original provider. - Some destination carriers screen calls that present a local number arriving from another carrier's network, and in-country calls to mobile numbers are the common failure case. Telnyx also signs these calls at attestation **B** rather than **A**. Prefer a Telnyx number for the market you dial most. **Your own SIP gateway** is an optional advanced setup. Selecting a verified caller ID reveals a **SIP gateway** field in the **Account** section: enter a host there and Moveo sends outbound calls to that gateway, so your own carrier places the call to the recipient. Enter the host without a `sip:` prefix, for example `sbc.example.com:5060`. If the gateway authenticates, enter its credentials in **SIP auth username** and **SIP auth password**. :::note SIP gateway routing This setup requires your own SIP infrastructure and a carrier contract that allows presenting those numbers. Contact Moveo support to plan it. ::: ### Step 5: Optimize voice settings The integration includes default settings for **text-to-speech** (TTS) and **speech-to-text** (STT) that work well for most use cases. However, you can adjust these settings to better fit your specific needs. They sit below the **Account** section in the configuration panel; see [Voice settings](#voice-settings) for what each group controls. ### Step 6: Activate the integration Review your configuration, turn on the toggle in the **Telnyx Voice** card at the top of the panel, and click **Save** to apply your changes. The **Account** section reports **Active** once the integration is live. ### Step 7: Route calls to an AI Agent The integration is now connected to Telnyx, but calls still need an AI Agent to answer them. Create a rule for this integration as described in the [quick deployment guide](../guides/quick-start.md), then place a test call. --- ## Configuration options ### Voice settings The configuration panel groups the voice behavior into three sections: **Preferences** controls whether voice conversations are stored as call recordings on your account, and whether the AI Agent starts the conversation with the initial welcome message instead of waiting for the caller to speak first. **Configuration** holds the language of the conversation and a preset that applies recommended settings for that language. Changing any individual setting switches the preset to **Custom**. Click **Show advanced** to expose the pipeline itself, including **Noise Suppression**, **Speech to text** (transcription model and turn detection), and **Text to speech** (voice, model, and delivery parameters such as speed). The defaults are a good starting point, so change the advanced settings only when testing shows a reason to. #### Noise suppression Noise suppression reduces background noise in the caller's audio, which improves transcription accuracy at the cost of a little extra latency. It's off by default. Turn on **Enabled**, then choose where it runs: - **Moveo.AI** applies noise suppression inside the Moveo voice pipeline, and is available on every voice integration. This is the default when you enable the feature. - **Telnyx Noise Suppression** applies it on the Telnyx leg, before the audio reaches Moveo, and is available on Telnyx Voice only. Telnyx bills this separately, per direction of audio. Selecting a provider also lets you pick an **Engine**. **Denoiser** suits most calls; the others target speaker isolation, WebRTC audio, far-field microphones, or speech-recognition accuracy, and each option in the list shows what it's best for. The engine names combine Telnyx's engines with their sub-models, so they don't map one to one onto the names in Telnyx's [noise suppression guide](https://developers.telnyx.com/docs/voice/programmable-voice/noise-suppression). ### Voice quality optimization To ensure the best voice experience, structure your AI Agent's responses using clear, concise language without complex formatting. Avoid special characters and symbols that don't translate well to speech, and use natural spoken language patterns. Consider adding pauses with punctuation for better pacing. ### AI Agent guidelines for voice Voice conversations have unique characteristics compared to text-based chat. To improve your AI Agent's performance in voice interactions, you can add specific guidelines that optimize for the auditory experience. These include using shorter, more conversational responses, avoiding lists or complex structures that are hard to follow audibly, confirming understanding of user input before proceeding, using verbal cues for transitions between topics, and providing clear call-to-action statements. --- ## Testing your integration ### Test phone calls Dial your Telnyx phone number and wait for the AI Agent greeting. Test various conversation scenarios, verify proper call handling and termination, and check call quality and response timing. ### Test outbound calls If you plan to run campaigns, and especially if you configured a verified caller ID, run a [campaign](../campaigns/campaigns.md) with a single contact to a phone you control. Confirm that the call connects and that the caller ID the recipient sees is the number you expect. ### Key test scenarios Make sure to validate call initiation and greeting, clear speech recognition, natural-sounding responses, handling of unclear input or silence, proper call termination, and transcription mismatches. --- ## Troubleshooting ### Connection issues **The integration doesn't verify**: Confirm the API key is still active in the Telnyx portal, that the public key belongs to the same account, and that the account is funded and has voice enabled. Pretrial accounts cannot create the Call Control Application the integration needs, so the integration cannot be configured on one. See [Account level](#account-level). **You need to change the API key**: This isn't supported after the integration is saved. Delete the integration and create a new one with the new key. **Your number isn't in the list**: The number must be in the Telnyx account that owns the API key and must be **active** in Telnyx, and only the first 250 active numbers are listed. Numbers shown under **In use** are already taken: detach a Telnyx number from its other connection in the Telnyx portal, or remove a verified caller ID from the other Moveo integration that holds it. **The Verified caller ID group is missing**: Moveo lists Telnyx-owned numbers only when it cannot read your verified numbers from Telnyx. Confirm the numbers are verified in the Telnyx portal, then reopen the configuration panel. ### Call handling issues **Calls aren't being answered**: Verify the integration is active, review the call in the Telnyx portal to confirm it reached Telnyx, and check that the public key in Moveo matches the one in your Telnyx account, since a mismatch makes Moveo reject every webhook. If the voice API application Moveo created was renamed or repointed, delete and save the integration again so Moveo recreates it. **Outbound campaign calls fail to connect**: This is the common symptom of dialing in-country mobile numbers from a verified caller ID, where the destination carrier screens the call. Use a Telnyx number in that market, or route the calls through your own SIP gateway. See [Choose the caller ID for outbound calls](#step-4-choose-the-caller-id-for-outbound-calls). **Outbound calls are rejected because of the caller ID**: The number must be in E.164 format (the international format, for example `+12025551234`), and a number you own elsewhere must be registered as a verified number in Telnyx before it can be presented. **AI Agent not responding correctly**: Test the AI Agent in text mode first to verify logic, review voice-specific guidelines and adjust accordingly, check for speech recognition errors in logs, verify intent recognition is working properly, and consider adding confirmation steps for critical information. ### Audio quality issues **Speech recognition is inaccurate**: Adjust STT language settings to match the caller's language, enable noise suppression for better accuracy, and review the recognition sensitivity settings. **Voice responses sound unnatural**: Review your AI Agent's response formatting, remove special characters and formatting that don't translate to speech, adjust the TTS voice model or speaking rate, simplify complex responses for better verbal delivery, and add punctuation for natural pauses and pacing. **Audio delays or lag**: Review [Telnyx's service status](https://status.telnyx.com) for any issues, and check whether the callers reporting the delay are in a region far from your Moveo deployment. --- ## Limitations ### Platform limitations Call duration and concurrency limits are determined by your Telnyx account level and plan, and which destination countries you can dial depends on that level too. Audio format constraints are defined by the codecs supported by Telnyx. Accounts below the **Verified** level are capped and prepend an automated-call announcement, so they can't be used for production traffic. ### Integration constraints Each integration configuration supports one phone number, and that number is assigned to the connection Moveo creates while the integration exists. Verified caller IDs work for outbound calls only. Voice quality depends on the caller's connection and device, STT accuracy varies with accents and background noise, and complex multi-turn conversations may require optimization. ### Best practices Monitor call duration and implement time limits if needed for cost control. Provide clear voice prompts for better recognition. Have fallback options for unclear or failed recognition. Regularly review and optimize based on call analytics. --- ## Resources ### Telnyx documentation - [Voice API overview](https://developers.telnyx.com/docs/voice/programmable-voice/get-started) - [Mission Control Portal](https://portal.telnyx.com) - [API reference](https://developers.telnyx.com/api-reference/overview) - [Voice API pricing](https://telnyx.com/pricing/voice-api) - [Account levels and upgrades](https://developers.telnyx.com/docs/account-setup/account-upgrade) - [Telnyx status](https://status.telnyx.com) ### Moveo resources - [Quick deployment guide](../guides/quick-start.md) - [Campaigns](../campaigns/campaigns.md) - [Voice call transfer](./voice-call-transfer.md) - [Twilio Voice integration](./twilio-voice.md) ### Support - [Telnyx support](https://support.telnyx.com/) - Moveo support: support@moveo.ai --- ## Next steps Once your Telnyx Voice integration is active, optimize your AI Agent with voice-specific guidelines, test thoroughly with various scenarios and voice configuration, monitor call analytics to identify improvement areas, adjust TTS/STT settings based on user feedback, configure fallback options for complex queries, and train your team on monitoring and handling escalations. --- ## Twilio Voice ## Overview The Twilio Voice integration enables your AI Agent to handle voice conversations through phone calls and web-based calling. By connecting your Twilio account to Moveo, you can provide automated voice support that combines the power of AI with natural speech interaction. This integration supports automated phone support through your Twilio phone numbers, web-based calling for browser-to-AI conversations, natural voice interactions with text-to-speech and speech-to-text capabilities, and flexible configuration to optimize voice quality and recognition accuracy. --- ## Prerequisites Before setting up the Twilio Voice integration, you'll need to configure both your Twilio account and your Moveo setup. ### Twilio account You'll need an active Twilio account with voice capabilities enabled and sufficient balance to cover voice call costs. #### Subaccount (optional) If you want to keep your Moveo voice usage separate from other Twilio services, you can create a [subaccount](https://help.twilio.com/articles/223136587-What-is-a-subaccount-). This is useful to isolate Moveo voice costs, phone numbers, and call logs from your other Twilio services. Each subaccount gets its own Account SID and Auth Token. For instructions on creating a subaccount, see [Twilio's subaccount guide](https://help.twilio.com/articles/360011348693-View-and-Create-New-Twilio-Subaccounts). :::tip If you have a dedicated Twilio account with no other services using it, you can use the main account directly; a subaccount is not required. ::: #### Account SID and Auth Token (region-specific) Your Twilio credentials must come from the [Twilio region](https://www.twilio.com/docs/global-infrastructure/understanding-twilio-regions) that matches your Moveo deployment: | Moveo deployment | Twilio region | |------------------|---------------| | Europe (EU) | Ireland (IE1) | | United States (US) | US1 | :::warning Make sure you select the correct Twilio region. Using credentials from the wrong region will result in connectivity issues with Moveo. ::: #### Trial account limitations Twilio trial accounts are restricted to the **US1** region (see [Twilio's free trial limitations](https://help.twilio.com/articles/360036052753-Twilio-Free-Trial-Limitations)). This affects customers whose Moveo deployment is in **Europe (EU)**, which uses the Ireland (IE1) Twilio region: - A trial account cannot connect to a Moveo deployment in the EU, because the IE1 region only becomes available after upgrading to a paid Twilio account. - Trial accounts are also limited to a single Twilio phone number. - The region of an existing trial account cannot be changed by re-routing or re-purchasing a number. :::warning If your Moveo deployment is in the EU, upgrade your Twilio account to a paid plan **before** configuring the integration. There is no workaround on a trial account. ::: #### Phone number (optional) You can use a Twilio-provided number or a number you've ported to Twilio. If you don't configure a phone number, the integration will be limited to web-based calls. :::warning A phone number is not required if you only plan to handle web calls. It becomes required when supporting incoming phone calls or when using the integration to call customers through campaigns. ::: ### Moveo account The configuration steps for connecting your AI Agent to Twilio are handled through Moveo's platform. For a complete walkthrough of the Moveo-side setup including AI Agent selection, environment configuration, and rule creation, see the [quick deployment guide](../guides/quick-start.md). --- ## How it works The Twilio Voice integration creates a bridge between callers and your Moveo AI Agent. When a user initiates a call through your web application, Twilio establishes the connection and begins streaming audio. The speech-to-text engine converts spoken words into text, which your AI Agent processes to generate an appropriate response. That response is then converted back to natural voice through text-to-speech and streamed to the caller in real-time. For phone calls, the flow is similar. When someone dials your Twilio phone number, Twilio routes the call to Moveo where the same speech processing and response cycle occurs. The conversation continues until the caller hangs up, or the AI Agent decides that the conversation has been resolved. When the AI Agent resolves the conversation, the platform hangs up the call within a couple of seconds. ### Reaching your AI Agent Once the integration is configured, users can reach your AI Agent in two ways: **Inbound calls**: Customers can call your Twilio phone number directly to start a conversation with your AI Agent. This is particularly useful for customer support hotlines or IVR systems where users initiate contact. **Outbound calls**: Your AI Agent can also call customers as part of a [campaign](../campaigns/campaigns.md). This enables proactive outreach for appointment reminders, notifications, surveys, or follow-ups, with the AI Agent handling the conversation when the customer answers. --- ## Call termination and handover A call ends in one of two ways, both controlled from the AI Agent's workflow: - **Resolve**: the [`Resolve`](../ai-agents/operations/resolve.md) action marks the conversation as completed. The call leg closes within a couple of seconds, whatever the environment's [Keep alive](../guides/timeouts.md#keep-alive) value. - **Handover**: the [`Handover`](../ai-agents/operations/handover.md) action transfers the active call to a phone number or SIP URI, via a **Standard transfer** (Moveo stays on the call) or **SIP REFER** (Moveo hands off to your SIP system and drops off). Optional custom SIP headers can be attached for SIP destinations. See [Voice call transfer](./voice-call-transfer.md). To make voice calls behave predictably at the end of a conversation, apply the following checklist to every voice-enabled environment: - Leave **Keep alive** as it is. It does not affect voice call termination. See [Keep alive for voice integrations](../guides/timeouts.md#voice-integrations). - Add a [`Pause`](../ai-agents/operations/pause.md) action of **1–2 seconds** immediately before any `Resolve` or `Handover` action so the AI Agent's final sentence is not clipped. - Gate the `Handover` action on call type if your AI Agent can also be reached through browser-based (Web) voice calls — handover is not supported for browser calls. --- ## Setup guide ### Step 1: Prepare your Twilio credentials 1. Log in to your [Twilio Console](https://console.twilio.com/). If you are using a subaccount, make sure you have switched to it. 2. Navigate to **Account** > **Keys & Credentials** > **API keys & tokens**. 3. From the region dropdown, select the Twilio region that matches your Moveo deployment (see the [region table above](#account-sid-and-auth-token-region-specific)). 4. Copy the **Account SID** and **Auth Token** displayed for that region. Keep these credentials handy for the next step. ### Step 2: Configure the integration in Moveo Navigate to **Connections** in your Moveo account, select your environment, find the **Twilio Voice** integration card, and click **Configure**. ### Step 3: Enter your Twilio account details In the configuration panel, you'll see a **Twilio Account** section where you'll enter your credentials and optionally select a phone number: **Account SID**: Your Twilio Account SID from the previous step (make sure these are the region-specific credentials) **Auth Token**: Your Twilio Auth Token **Phone Number**: Select a phone number from the dropdown to enable phone calls, or leave it set to "None" for web calls only When no phone number is selected, the integration works exclusively for web calls. When you select a phone number, the integration handles both web calls and incoming phone calls to that number. ### Step 4: Optimize voice settings The integration includes default settings for **text-to-speech** (TTS) and **speech-to-text** (STT) that work well for most use cases. However, you can adjust these settings to better fit your specific needs. The TTS settings let you select the voice model, speaking rate, pitch adjustments, language, and accent. The STT settings allow you to configure the recognition model, language, profanity filtering, and punctuation preferences. These settings can be found below the Twilio Account section in the configuration panel and adjusted based on your testing results. See [Voice settings](#voice-settings) for what each group of settings controls. ### Step 5: Activate the integration Review your configuration, turn on the toggle in the **Twilio Voice** card at the top of the panel, and click **Save** to apply your changes. The **Account** section reports **Active** once the integration is live. --- ## Configuration options ### Voice settings The configuration panel groups the voice behavior into three sections: **Preferences** controls whether voice conversations are stored as call recordings on your account, and whether the AI Agent starts the conversation with the initial welcome message instead of waiting for the caller to speak first. **Configuration** holds the language of the conversation and a preset that applies recommended settings for that language. Changing any individual setting switches the preset to **Custom**. Click **Show advanced** to expose the pipeline itself, including **Noise Suppression**, which is off by default and reduces background noise in the caller's audio to improve transcription accuracy at the cost of a little extra latency, **Speech to text** for the transcription model and turn detection, and **Text to speech** for the voice, the model, and delivery parameters such as speed. The defaults are a good starting point, so change the advanced settings only when testing shows a reason to. ### Voice quality optimization To ensure the best voice experience, structure your AI Agent's responses using clear, concise language without complex formatting. Avoid special characters and symbols that don't translate well to speech, and use natural spoken language patterns. Consider adding pauses with punctuation for better pacing. ### AI Agent guidelines for voice Voice conversations have unique characteristics compared to text-based chat. To improve your AI Agent's performance in voice interactions, you can add specific guidelines that optimize for the auditory experience. These include using shorter, more conversational responses, avoiding lists or complex structures that are hard to follow audibly, confirming understanding of user input before proceeding, using verbal cues for transitions between topics, and providing clear call-to-action statements. :::tip Check this documentation page to learn more about this: https://elevenlabs.io/docs/best-practices/prompting/normalization#putting-it-all-together ::: --- ## Testing your integration ### Test phone calls If you configured a phone number, dial your Twilio phone number and wait for the AI Agent greeting. Test various conversation scenarios, verify proper call handling and termination, and check call quality and response timing. ### Key test scenarios Make sure to validate call initiation and greeting, clear speech recognition, natural-sounding responses, handling of unclear input or silence, proper call termination, and transcription mismatches. ## Troubleshooting ### Connection issues **Integration fails to connect to Twilio**: Verify your Account SID and Auth Token are correct, check that your Twilio account is active and funded, ensure you have voice capabilities enabled, and review Twilio account status for any restrictions. **Phone number not working**: Confirm the phone number is active in your Twilio account, check that the number has voice capabilities enabled, verify the number is properly configured in Moveo, and test the number directly in Twilio Console. **Phone number cannot be re-routed to the EU region**: If the "Re-route" button is grayed out in the Twilio console, or the integration rejects a number that otherwise looks correctly configured, your Twilio account is likely a trial account. Trial accounts are locked to the US1 region and cannot be used with an EU Moveo deployment — upgrade to a paid Twilio account and retry. See [Trial account limitations](#trial-account-limitations). ### Audio quality issues **Speech recognition is inaccurate**: Adjust STT language settings to match the caller's language, enable noise suppression for better accuracy, check microphone quality and audio input levels, consider environment noise factors, and review recognition sensitivity settings. **Voice responses sound unnatural**: Review your AI Agent's response formatting, remove special characters and formatting that don't translate to speech, adjust the TTS voice model or speaking rate, simplify complex responses for better verbal delivery, and add punctuation for natural pauses and pacing. **Audio delays or lag**: Check your internet connection stability, review Twilio's service status for any issues, verify your server response times are optimal, consider geographic latency factors, and check for webhook processing delays. ### Call handling issues **Calls not being answered**: Verify the integration is set to **Active**, check Twilio webhook configuration, review call logs in Twilio Console, confirm your environment is properly configured, and check for any error messages in Moveo logs. **AI Agent not responding correctly**: Test the AI Agent in text mode first to verify logic, review voice-specific guidelines and adjust accordingly, check for speech recognition errors in logs, verify intent recognition is working properly, and consider adding confirmation steps for critical information. ## Phone issues If the issue seems that the call is not connecting to Moveo at all, ensure that the phone number is set up correctly in Twilio console. --- ## Limitations ### Platform limitations Call duration limits are based on your Twilio plan and pricing. Concurrent call limits are determined by your Twilio account tier. Voice availability varies by region due to geographic restrictions. Audio format constraints are defined by the specific codecs supported by Twilio. Trial Twilio accounts cannot be used with EU Moveo deployments; see [Trial account limitations](#trial-account-limitations). ### Integration constraints Each integration configuration supports one phone number. Voice quality depends on the caller's connection and device. STT accuracy varies with accents and background noise. Complex multi-turn conversations may require optimization. ### Best practices Monitor call duration and implement time limits if needed for cost control. Set up call queuing for high-volume scenarios. Provide clear voice prompts for better recognition. Have fallback options for unclear or failed recognition. Regularly review and optimize based on call analytics. --- ## Resources ### Twilio documentation - [Twilio Voice Overview](https://www.twilio.com/docs/voice) - [Twilio Console](https://console.twilio.com/) - [Voice Pricing](https://www.twilio.com/voice/pricing) - [Voice API Reference](https://www.twilio.com/docs/voice/api) ### Moveo resources - [Quick deployment guide](../guides/quick-start.md) - [Campaigns](../campaigns/campaigns.md) - [Voice call transfer](./voice-call-transfer.md) - [Telnyx Voice integration](./telnyx-voice.md) ### Support - [Twilio Support](https://support.twilio.com/) - Moveo support: support@moveo.ai --- ## Next steps Once your Twilio Voice integration is active, optimize your AI Agent with voice-specific guidelines, test thoroughly with various scenarios and voice configuration, monitor call analytics to identify improvement areas, adjust TTS/STT settings based on user feedback, configure fallback options for complex queries, and train your team on monitoring and handling escalations. --- ## Viber ## Overview Viber integration enables your AI Agent to communicate with customers through one of the world's most popular messaging platforms. With over 1 billion users globally, Viber provides a secure, feature-rich messaging environment where businesses can engage customers through automated conversations, rich media, and interactive elements. This integration enables: - **Automated customer support** through Viber Business Messages - **Rich messaging features** including carousels, buttons, and media - **Global reach** with strong presence in Eastern Europe, Asia, and Middle East - **Secure communication** with end-to-end encryption - **Bot-managed interactions** with seamless handover capabilities --- ## Prerequisites Before setting up the Viber integration, ensure you have: ✅ **Business requirements** - Active business with legitimate use case for messaging - Company registration documents - Business website with contact information - Valid business email address ✅ **Viber Bot Account** - Approved Viber bot account (handled by Moveo) - Access token provided by Moveo - Bot name and avatar prepared ✅ **Moveo account setup** - An active [AI Agent](../ai-agents/overview.md) configured - An [environment](../environments/overview.md) selected for the integration :::info As of February 2024, Viber updated their bot creation process. Moveo handles bot account creation on your behalf to ensure compliance with their new commercial model. ::: --- ## How it works Viber integration operates through Viber's bot platform with Moveo managing the technical setup: 1. **Moveo creates bot** on your behalf through Viber's application process 2. **Customer starts conversation** by messaging your Viber bot 3. **AI Agent receives message** and processes using your configuration 4. **Response is sent** through Viber's messaging API 5. **Rich interactions** available through carousels, buttons, and media 6. **Handover possible** to human agents when needed All messages are processed through Viber's secure infrastructure with full conversation history maintained. --- ## Setup guide Viber bot setup involves two main pathways depending on whether you have an existing bot or need a new one. ### Bot account creation #### Option 1: Existing Viber bot If you already have a Viber bot account: 1. Locate your existing bot access token 2. Ensure bot is active and properly configured 3. Proceed directly to [Connect with Moveo](#step-2-connect-with-moveo) #### Option 2: Request new Viber bot For new bot account creation through Moveo: 1. **Contact Moveo support** at [support@moveo.ai](mailto:support@moveo.ai) 2. **Request Viber bot creation** with your business details 3. **Receive application form** from Moveo with Viber's requirements 4. **Complete form thoroughly** with: - Company information and registration details - Business website and contact information - Bot purpose and expected usage - Brand assets (logo, description) 5. **Submit to Moveo** for Viber application processing 6. **Await approval** (typically 5-10 business days) 7. **Receive access token** from Moveo once approved :::info Bot commercial model Viber's updated commercial model requires business verification and approved use cases. Learn more in their [official documentation](https://help.viber.com/hc/en-us/articles/15247629658525-Bot-commercial-model). ::: ### Step 2: Connect with Moveo Once you have your bot access token, configure the integration: 1. **Navigate to Integrations** in your Moveo platform 2. **Select your environment** for the Viber integration 3. **Click Connect** under the Viber integration card 4. **Configure connection settings**: - Enter your bot access token - Set your AI Agent name (visible to users) - Configure bot avatar/profile image 5. **Customize messaging**: - Set autostart message (sent when users begin conversation) - Configure welcome message and initial flow 6. **Optional configurations**: - Set up user authentication if required - Configure additional security settings 7. **Activate integration**: - Set status to **ACTIVE** - Save all configuration changes --- ## Configuration options ### Bot profile settings - **Bot name**: Display name shown to users - **Avatar**: Profile image representing your bot - **Description**: Brief description of bot capabilities - **Welcome message**: Initial message when conversation starts ### Message configuration - **Autostart message**: Triggers AI Agent when user initiates chat - **Response templates**: Configure standard response formats - **Rich media settings**: Enable images, buttons, and carousels - **Handover messages**: Configure human agent transition ### Security settings - **User authentication**: Optional identity verification - **Webhook security**: Token validation for message delivery - **Rate limiting**: Configure message frequency limits --- ## Testing your integration ### Initial testing 1. **Send test message** to your Viber bot number 2. **Verify autostart message** triggers correctly 3. **Test AI Agent responses** across different scenarios 4. **Check rich media delivery** (images, buttons, carousels) 5. **Validate handover scenarios** if applicable ### Test scenarios ✓ **Welcome message flow** ✓ **FAQ responses and accuracy** ✓ **Rich media rendering** (carousels work well on Viber) ✓ **Multi-turn conversations** ✓ **Error handling and fallbacks** ✓ **Handover to human agents** ### Performance monitoring - **Message delivery rates** - **Response accuracy and relevance** - **User engagement with rich elements** - **Conversation completion rates** --- ## Common use cases ### Customer service automation - Handle customer inquiries 24/7 - Provide instant answers to FAQs - Process orders and booking requests - Escalate complex issues to human agents ### Marketing and engagement - Send promotional messages and offers - Share product catalogs through carousels - Conduct surveys and collect feedback - Build customer relationships ### E-commerce support - Product recommendations and information - Order status and tracking updates - Payment assistance and support - Returns and refund processing ### Regional market penetration - Target Eastern European markets effectively - Reach users in Middle East and Asia - Leverage Viber's strong regional presence - Provide localized customer support --- ## Best practices ### Bot design - Use clear, recognizable bot name and avatar - Start conversations with engaging carousels (recommended) - Provide clear navigation options - Maintain consistent brand voice ### Message optimization - Keep messages concise and scannable - Use rich media effectively for engagement - Implement quick reply options - Provide clear call-to-action buttons ### User experience - Set clear expectations about bot capabilities - Offer easy access to human support - Provide help commands and navigation - Handle errors gracefully ### Compliance and etiquette - Follow Viber's Terms of Service - Respect user privacy and preferences - Provide opt-out options - Maintain professional communication --- ## Troubleshooting
Bot not responding to messages - Verify access token is correct and active - Check integration status is set to ACTIVE - Ensure AI Agent is properly configured - Confirm webhook connectivity with Viber - Test with simple text messages first
Rich media not displaying - Verify image URLs are publicly accessible - Check file size limits (Viber has specific requirements) - Ensure proper HTTPS URLs - Test carousel configuration syntax - Validate media format compatibility
Bot creation issues - Ensure business information is complete and accurate - Verify website has proper business contact information - Check application status with Moveo support - Provide additional documentation if requested - Allow sufficient time for Viber approval process
Authentication problems - Check user authentication configuration - Verify webhook token validation - Ensure proper SSL certificate on your domain - Test authentication flow thoroughly - Review security settings in integration
--- ## Limitations ### Platform restrictions - **Initial message limit**: First conversation message restricted to one [response](../ai-agents/dialogs.md#responses) - **Message frequency**: Rate limiting applied by Viber - **Business verification**: Requires approved business use case - **Geographic restrictions**: Some regions have limited support ### Integration constraints - **Bot approval required**: All bots must be approved by Viber - **Commercial model**: Subject to Viber's business messaging fees - **Rich media limits**: File size and format restrictions apply - **Authentication**: Optional but recommended for business use :::tip Start conversations with a carousel to maximize engagement within the single response limitation. ::: --- ## Resources ### Documentation - [Viber Bot Platform](https://developers.viber.com/docs/bots/) - [Viber Business Messages](https://www.viber.com/business/) - [Bot Commercial Model](https://help.viber.com/hc/en-us/articles/15247629658525-Bot-commercial-model) ### Tools - [Viber Developer Portal](https://partners.viber.com/) - [Bot Testing Tools](https://developers.viber.com/docs/tools-and-resources/) ### Support - [Viber Support Center](https://help.viber.com) - Moveo support: support@moveo.ai --- ## Next steps Once your Viber integration is active: 1. **Optimize your bot profile** with engaging avatar and description 2. **Design effective carousel flows** for maximum engagement 3. **Test across different devices** and Viber versions 4. **Monitor user interactions** and optimize responses 5. **Scale gradually** as you learn user preferences --- ## Voice call transfer When a voice AI Agent hands a call to a human agent or to your phone system, the call is transferred with one of two **transfer methods**: a **Standard transfer** or a **SIP REFER**. You pick the method on the [`Handover`](../ai-agents/operations/handover.md) action; this page explains how each one works, how they differ, and when to use which. ## New to SIP? A few terms used on this page, in plain language: - **SIP** — the signaling protocol that sets up, changes, and ends voice calls. It carries the call control messages; the audio itself flows separately. - **SIP INVITE** — the message that *starts* a call to a destination. - **SIP REFER** — a SIP message that asks the other party to *transfer* the call to a third destination on its own, so the original party can leave. - **SIP URI** — a SIP address, like `sip:agent@example.com` (the SIP equivalent of a phone number). - **PBX / phone system** — the system on your side that receives the transferred call (for example a contact center or office phone system). - **Bridge** — keeping both call legs connected through Moveo, so Moveo stays in the call. ## Standard transfer Moveo dials the destination and **bridges** the two calls: the caller and the destination are connected *through Moveo*, which stays on the call for its full duration. It works with a **phone number** (E.164) or a **SIP destination**. Because both legs stay open through Moveo, **recording continues** through the transfer and **both legs are billed** while connected. ## SIP REFER Moveo asks the provider to **hand the call directly to your destination**, then **drops off** the call entirely. Moveo is no longer in the path; the caller talks to your system directly. It requires a **SIP destination** (a `sip:` URI), and the incoming call must have **arrived over SIP** — a caller who reached you over a phone line can't be transferred this way (use a Standard transfer instead). Once Moveo drops off, its **recording stops at the handoff** (recording continues on your side). ## Which one to use | | Standard transfer | SIP REFER | | --- | --- | --- | | Moveo stays in the call | Yes | No (drops off) | | Moveo-side recording after transfer | Continues | Stops at handoff | | Destination type | Phone number or SIP | SIP only | | Incoming call must be over SIP | No | Yes, see [Provider notes](#provider-notes) | | If the transfer fails | Call drops | Call drops | ```mermaid flowchart LR subgraph standard [Standard transfer: Moveo stays in the path] direction LR c1[Caller] <--> m1[Moveo] <--> a1[Agent / phone system] end subgraph refer [SIP REFER: Moveo hands off and drops off] direction LR c2[Caller] <--> a2[Agent / phone system] m2[Moveo] -. drops off .-> c2 end ``` Use **SIP REFER** when the destination is a SIP system (a PBX or contact center) reached by an inbound SIP call and you want Moveo fully out of the path after the handoff — no second billed leg, and no Moveo-side recording of the agent conversation. Use a **Standard transfer** for phone destinations, or whenever the incoming call did not arrive over SIP. ## Provider notes ### Twilio SIP REFER is only supported on SIP call legs. A call that reaches Moveo over a phone (PSTN) number or a browser (web) call cannot be transferred with SIP REFER; use a Standard transfer for those. See Twilio's [`` documentation](https://www.twilio.com/docs/voice/twiml/refer). ### Telnyx SIP REFER needs a SIP destination. If the handover destination is a phone number, Moveo falls back to a Standard transfer, so the transfer still completes. For calls that reached Moveo over a phone (PSTN) number, whether the carrier passes the REFER on is outside Moveo's control. Use a Standard transfer for those calls. ## See also - [`Handover` action](../ai-agents/operations/handover.md) — configuring the transfer, including custom SIP headers. - [Twilio Voice integration](./twilio-voice.md). - [Telnyx Voice integration](./telnyx-voice.md). --- ## Web channel configuration ## Configuration overview The web channel offers extensive customization options to match your brand and user experience requirements. You can configure these settings through the Moveo platform UI or override them programmatically during initialization. ## Launcher appearance Customize how the chat launcher button appears on your website. ### Launcher styles Choose between different launcher styles: - **Circle** (default): Circular button with icon - **Box**: Rectangular button with text ### Teaser message Add a teaser message next to the launcher to encourage interaction. ### Additional options - **Focus trap**: Prevent users from browsing while conversing - **Auto open**: Automatically open the widget when page loads ## Chat window appearance Customize the visual design of the chat window. ### Theme customization | Element | Default | Description | | ------------- | ----------------- | ----------------------- | | Primary color | `#1B66D6` | Main brand color | | Text color | `#FFFFFF` | Text on primary color | | Header title | Your AI Assistant | Chat window header text | | Avatar | Default bot icon | AI Agent profile image | ## Start behavior Configure how conversations begin when users open the chat. ### Available options 1. **User input**: User must type first message 2. **Autostart**: AI sends welcome message automatically 3. **Welcome screen**: Display options and FAQs ## Positioning Control where and how the web channel appears on your page. ### Position options - **Livechat** (default): Bottom-right floating widget - **Embed**: Renders within page content - **Pop-up**: Center of screen modal ### Widget alignment For livechat mode, use the `widget_alignment` option to control which corner of the screen the launcher and chat window appear in. | Value | Description | | -------------- | ------------------------------------ | | `bottom-right` | Bottom-right corner (default) | | `bottom-left` | Bottom-left corner | | `top-right` | Top-right corner, chat opens downward | | `top-left` | Top-left corner, chat opens downward | | `right` | Legacy alias for `bottom-right` | | `left` | Legacy alias for `bottom-left` | ```javascript MoveoAI.init({ integrationId: "YOUR-INTEGRATION-ID", widget_alignment: "top-left", }); ``` ### Custom positioning For fine-grained control beyond `widget_alignment`, you can override positioning with CSS: ```css /* Custom offset from bottom */ .web-client-container { bottom: 100px; } ``` :::tip Use `widget_alignment` to position the launcher in a corner. Reserve CSS overrides for fine-tuning offsets. When positioning the launcher on the left, consider removing the teaser message for better visual balance. ::: ## Visitor information collection Gather user information before or during the conversation. ### Pre-chat form fields Enable collection of user data before chat starts: | Field | Variable | Description | | -------- | ---------------------------------- | -------------------- | | Email | `user.email` | User's email address | | Name | `user.display_name` | Display name | | Phone | `user.phone` | Phone number | | Address | `user.address` | Physical address | | Language | `user.language` | Preferred language | | Location | `user.location.latitude/longitude` | GPS coordinates | ### Additional options - **Data policy disclaimer**: Require acceptance of terms - **Location permission**: Request browser location access - **Required fields**: Make specific fields mandatory ## Advanced settings ### File upload Enable users to share files in the conversation: - Maximum file size: 5MB - Maximum files per message: 4 - Supported formats: Images, PDFs, documents ### Conversation history Maintain chat history across page refreshes and navigation: - Conversations persist for returning users - History cleared after session timeout (1 hour default) ### Satisfaction survey Collect feedback after conversations: - Star ratings or thumbs up/down - Optional comment field - Triggered on conversation end ### Language settings Override browser language detection: - Set default language for all users - Available languages include English, Spanish, French, German, and more ## Programmatic configuration Override any setting during initialization: ```javascript MoveoAI.init({ integrationId: "YOUR-INTEGRATION-ID", version: "v2", // Appearance accent_color: "#FF5733", background_color: "#2C3E50", header_title: "Support Chat", download_conversation: true, avatar: "https://example.com/avatar.png", bubble_image: "https://example.com/launcher.png", font_family: "Roboto Mono", // Behavior auto_open: true, focus_trap: false, welcome_message: "How can I help?", welcome_trigger_message: "Hello!", virtual_agent_name: "Alex", // Window settings chatWindow: { width: "400px", height: "600px", }, // Positioning widget_alignment: "bottom-right", // "bottom-right" | "bottom-left" | "top-right" | "top-left" // Launcher settings launcher: { size: "60px", show: true, // Set false to hide launcher }, show_close_icon: true, // Show/hide launcher close icon // Language language: "en", // Session behavior close_session_if_empty: false, // Accessibility webchat_aria_label: "Chat with support", enableAccessibilityWidget: true, }) .then((instance) => { console.log("Chat configured and connected"); }) .catch((error) => console.error(error)); ``` ## CSS customization Use the `setCSSVariables()` method for advanced runtime styling. This enables per-customer theming without code changes. ```javascript instance.setCSSVariables({ "--moveo-header-text-color": "#10038C", "--color-options-background": "#CCF3FD", }); ``` ### Available CSS variables #### General | Variable | Description | | -------- | ----------- | | `--color-chat-background` | Chat container background | #### Launcher | Variable | Description | | -------- | ----------- | | `--color-launcher-background` | Launcher button background | | `--color-launcher-foreground` | Launcher button icon color | | `--color-opening-message-background` | Teaser message background | | `--color-opening-message-foreground` | Teaser message text color | #### Header | Variable | Description | | -------- | ----------- | | `--moveo-header-background` | Header background color | | `--moveo-header-text-color` | Header text and icon color | #### Messages | Variable | Description | | -------- | ----------- | | `--color-message-user-background` | User message bubble background | | `--font-size-brain-message` | AI message text size (`small`, `medium`, or `large`) | #### Quick replies (Options) | Variable | Description | | -------- | ----------- | | `--color-options-background` | Quick reply button background | | `--color-options-foreground` | Quick reply button text | | `--color-options-border` | Quick reply button border | #### System messages (Swimmlanes) | Variable | Description | | -------- | ----------- | | `--color-swimmlane-background` | System message background | | `--color-swimmlane-foreground` | System message text | #### Carousel cards | Variable | Description | | -------- | ----------- | | `--color-carousel-card-background` | Carousel card background | | `--color-carousel-card-foreground` | Carousel card text | | `--color-carousel-card-border` | Carousel card border | ### Example: Complete branded theme ```javascript instance.setCSSVariables({ // Header "--moveo-header-text-color": "#10038C", // Quick replies "--color-options-background": "#CCF3FD", "--color-options-foreground": "#10038C", "--color-options-border": "#CCF3FD", // System messages "--color-swimmlane-background": "#F2EBE7", "--color-swimmlane-foreground": "#1E222D", }); ``` ## Language and localization ### Default language hierarchy Language selection follows this priority: 1. User selection in visitor form 2. Configuration default 3. Browser language 4. English fallback ### Available languages | Code | Language | | ------- | ---------------------- | | `de` | 🇩🇪 German | | `el` | 🇬🇷 Greek | | `en` | 🇺🇸 English | | `es` | 🇪🇸 Spanish | | `fr` | 🇫🇷 French | | `it` | 🇮🇹 Italian | | `pt-br` | 🇧🇷 Portuguese (Brazil) | | `nl` | 🇳🇱 Dutch | | `zh` | 🇨🇳 Chinese | | `ar` | 🇸🇦 Arabic | | `ja` | 🇯🇵 Japanese | | `tr` | 🇹🇷 Turkish | ### Dynamic language switching Change language programmatically: ```javascript instance.setLocale("es"); // Switch to Spanish ``` ## Configuration best practices 1. **Brand consistency**: Match your website's colors and fonts 2. **Mobile optimization**: Test positioning on different screen sizes 3. **Performance**: Load custom assets from CDN 4. **Accessibility**: Provide ARIA labels and high contrast options 5. **User privacy**: Only collect necessary information 6. **Testing**: Preview changes before going live ## Trusted domains Secure your integration by specifying allowed domains: - Add all production domains - Include staging/test environments - Supports wildcards: `*.example.com` - Blocks unauthorized usage ## Next steps - [Implement methods and events](./developer-guide) - [Troubleshoot integration issues](./troubleshooting) --- ## Web channel developer guide ## Instance methods The web channel exposes methods to control behavior and interact with the chat programmatically. ```javascript MoveoAI.init({ integrationId: "YOUR-INTEGRATION-ID", version: "v2", }).then((instance) => { // Use instance methods here }); ``` ### Window control #### openWindow() Opens the chat window if currently closed. ```javascript instance.openWindow(); ``` #### closeWindow() Closes the chat window if currently open. ```javascript instance.closeWindow(); ``` ### Messaging #### sendMessage() Programmatically send a message to the AI Agent. ```javascript instance.sendMessage({ text: "Hello, I need help" }); // Open window after sending instance.sendMessage({ text: "Start conversation" }); instance.openWindow(); ``` **Behavior:** - If conversation exists: sends immediately - No conversation: overrides welcome message - With visitor form: sends after form completion ### User context #### updateContext() Update user information or session data dynamically. ```javascript instance.updateContext({ user: { display_name: "John Doe", email: "john@example.com", }, customer_id: "12345", account_type: "premium", }); ``` ### Session management #### destroy() End the conversation and hide the web channel completely. ```javascript // End session when user logs out if (userLoggedOut) { instance.destroy(); } ``` :::note After calling `destroy()`, you can reinitialize the web channel with `MoveoAI.init()`. ::: ### Styling #### setCSSVariables() Dynamically customize the web channel appearance at runtime using CSS variables. This enables per-customer theming without code changes. ```javascript instance.setCSSVariables({ "--moveo-header-text-color": "#10038C", "--color-options-background": "#CCF3FD", "--color-options-foreground": "#10038C", }); ``` **Available CSS variables:** | Variable | Purpose | |----------|---------| | `--color-launcher-background` | Launcher button background | | `--color-launcher-foreground` | Launcher button icon color | | `--color-opening-message-background` | Teaser message background | | `--color-opening-message-foreground` | Teaser message text color | | `--color-options-background` | Quick reply button background | | `--color-options-foreground` | Quick reply button text | | `--color-options-border` | Quick reply button border | | `--color-swimmlane-background` | System message background | | `--color-swimmlane-foreground` | System message text | | `--color-carousel-card-background` | Carousel card background | | `--color-carousel-card-foreground` | Carousel card text | | `--color-carousel-card-border` | Carousel card border | | `--color-chat-background` | Chat container background | | `--color-message-user-background` | User message bubble background | | `--moveo-header-background` | Header background color | | `--moveo-header-text-color` | Header text and icon color | | `--font-size-brain-message` | AI message text size (`small`, `medium`, or `large`) | **Example: Custom branded theme** ```javascript instance.setCSSVariables({ "--moveo-header-text-color": "#10038C", "--color-options-background": "#CCF3FD", "--color-options-foreground": "#10038C", "--color-options-border": "#CCF3FD", "--color-swimmlane-background": "#F2EBE7", "--color-swimmlane-foreground": "#1E222D", }); ``` **Example: Launcher customization** ```javascript instance.setCSSVariables({ "--color-launcher-background": "#10b981", "--color-launcher-foreground": "#ffffff", "--color-opening-message-background": "#10b981", "--color-opening-message-foreground": "#ffffff", }); ``` **Example: Header customization** ```javascript instance.setCSSVariables({ "--moveo-header-background": "#11366b", "--moveo-header-text-color": "#ffffff", }); ``` ### Localization #### setLocale() Change the web channel language dynamically. ```javascript instance.setLocale("es"); // Switch to Spanish ``` ## Event listeners Subscribe to web channel events to track user interactions and session changes. ### Session events #### onSessionCreated Fired when a new conversation starts. ```javascript instance.onSessionCreated(() => { console.log("New session started"); // Track in analytics analytics.track("Chat Started"); // Set initial context instance.updateContext({ page_url: window.location.href, timestamp: new Date().toISOString(), }); }); ``` #### onSessionReconnected Fired when reconnecting to existing session (with history enabled). ```javascript instance.onSessionReconnected(() => { console.log("Reconnected to existing session"); // Update context with new page info instance.updateContext({ returned_user: true, return_page: window.location.pathname, }); }); ``` #### onSessionClosed Fired when the chat session terminates. ```javascript instance.onSessionClosed(() => { console.log("Session terminated"); // Clean up or redirect if (shouldRedirect) { window.location.href = "/thank-you"; } }); ``` ### Live chat events #### onConversationClosed Fired when live chat conversation is resolved/closed. ```javascript instance.onConversationClosed(() => { console.log("Live chat ended"); // Show feedback form showCustomFeedbackModal(); }); ``` #### onMemberLeave Fired when an agent leaves the conversation. ```javascript instance.onMemberLeave(() => { console.log("Agent left the conversation"); // Notify user showNotification("Agent has disconnected"); }); ``` ### Window events #### onWebchatOpened Fired when chat window opens. ```javascript instance.onWebchatOpened(() => { // Pause video when chat opens videoPlayer.pause(); // Track engagement analytics.track("Chat Opened"); }); ``` #### onWebchatClosed Fired when chat window closes. ```javascript instance.onWebchatClosed(() => { // Resume video when chat closes videoPlayer.play(); // Save draft message if any saveDraftMessage(); }); ``` ### Activity tracking #### onUserActivity Fired on any user activity in the chat. ```javascript let inactivityTimer; instance.onUserActivity(() => { // Reset inactivity timer clearTimeout(inactivityTimer); inactivityTimer = setTimeout(() => { console.log("User inactive for 5 minutes"); }, 300000); }); ``` ## Analytics events Track detailed user interactions with analytics events. ### Setup ```javascript instance.onAnalyticsEvent((eventData) => { const { event, properties, timestamp } = eventData; // Send to your analytics platform analytics.track(event, { ...properties, chat_session_id: properties.session_id, timestamp: timestamp, }); }); ``` ### Available events #### Interaction events - `launcher_clicked` - User clicks launcher - `chat_expanded` - Chat window opens - `minimize_icon_clicked` - Minimize button clicked - `close_icon_clicked` - Close button clicked - `message_click` - Message bubble clicked #### Session events - `session_start` - New session begins - `session_end` - Session ends - `welcome_form_submitted` - Pre-chat form completed #### Engagement events - `rating_clicked` - User selects rating - `rating_submitted` - Rating confirmed - `download_conversation_clicked` - Export chat #### Popover events - `popover_inactivity_end_chat_clicked` - End inactive chat - `popover_inactivity_continue_clicked` - Continue after inactivity - `resolved_popover_continue_clicked` - Continue resolved chat ### Event data structure ```javascript { "timestamp": "2025-01-20T10:30:45.123Z", "event": "launcher_clicked", "properties": { "session_id": "uuid-here", "page_url": "https://example.com/products", "user_id": "user-123" // If authenticated } } ``` ## Advanced integration patterns ### Custom launcher Hide default launcher and use custom button: ```javascript MoveoAI.init({ integrationId: "YOUR-INTEGRATION-ID", version: "v2", launcher: { show: false }, // Hide default launcher }).then((instance) => { // Custom button opens chat document.getElementById("custom-chat-btn").addEventListener("click", () => { instance.openWindow(); }); }); ``` ### Contextual messaging Send different messages based on page: ```javascript const pageMessages = { "/products": "Looking for product information?", "/pricing": "Need help choosing a plan?", "/support": "How can we assist you today?", }; instance.sendMessage({ text: pageMessages[window.location.pathname] || "Hello!", }); ``` ### User authentication flow ```javascript // After user logs in async function onUserLogin(user) { // Get fresh JWT from server const token = await fetchUserToken(user.id); // Destroy old session if (window.chatInstance) { window.chatInstance.destroy(); } // Initialize authenticated session window.chatInstance = await MoveoAI.init({ integrationId: "YOUR-INTEGRATION-ID", identityToken: token, version: "v2", }); // Set user context window.chatInstance.updateContext({ user: { display_name: user.name, email: user.email, }, }); } ``` ### Analytics integration ```javascript // Google Analytics 4 instance.onAnalyticsEvent((eventData) => { gtag("event", eventData.event, { chat_session_id: eventData.properties.session_id, engagement_time_msec: 100, }); }); // Segment instance.onAnalyticsEvent((eventData) => { analytics.track(eventData.event, eventData.properties); }); // Mixpanel instance.onAnalyticsEvent((eventData) => { mixpanel.track(eventData.event, eventData.properties); }); ``` ### Error handling ```javascript MoveoAI.init({ integrationId: "YOUR-INTEGRATION-ID", version: "v2", }) .then((instance) => { window.chatInstance = instance; }) .catch((error) => { console.error("Chat initialization failed:", error); // Show fallback contact options document.getElementById("fallback-contact").style.display = "block"; // Report to monitoring errorReporting.log(error); }); ``` ### Multi-language support ```javascript // Detect user language preference const userLang = localStorage.getItem("language") || navigator.language.substring(0, 2); // Initialize with user's language MoveoAI.init({ integrationId: "YOUR-INTEGRATION-ID", language: userLang, version: "v2", }).then((instance) => { // Allow language switching document.getElementById("lang-selector").addEventListener("change", (e) => { instance.setLocale(e.target.value); localStorage.setItem("language", e.target.value); }); }); ``` ## Testing and debugging ### Development mode ```javascript const isDev = window.location.hostname === "localhost"; MoveoAI.init({ integrationId: isDev ? "DEV-INTEGRATION-ID" : "PROD-INTEGRATION-ID", version: "v2", }).then((instance) => { if (isDev) { // Expose instance for debugging window.debugChat = instance; // Log all events instance.onAnalyticsEvent(console.log); } }); ``` ### Event monitoring ```javascript // Monitor all chat events const events = [ "onSessionCreated", "onSessionReconnected", "onSessionClosed", "onWebchatOpened", "onWebchatClosed", ]; events.forEach((eventName) => { instance[eventName](() => { console.log(`Event fired: ${eventName}`, new Date()); }); }); ``` ## Performance optimization ### Lazy loading ```javascript // Load chat only when needed function loadChat() { const script = document.createElement("script"); script.src = "https://web.moveo.ai/web-client.min.js"; script.onload = () => { MoveoAI.init({ integrationId: "YOUR-INTEGRATION-ID", version: "v2", }); }; document.body.appendChild(script); } // Load on user interaction document .getElementById("chat-trigger") .addEventListener("click", loadChat, { once: true }); ``` ### Resource cleanup ```javascript // Clean up on page unload window.addEventListener("beforeunload", () => { if (window.chatInstance) { // Save conversation state if needed localStorage.setItem( "chatState", JSON.stringify({ timestamp: Date.now(), page: window.location.href, }) ); } }); ``` ## Security considerations 1. **Never expose sensitive data** in client-side code 2. **Validate tokens** server-side before passing to web channel 3. **Use HTTPS** for all communications 4. **Implement rate limiting** for API calls 5. **Sanitize user input** before passing to context 6. **Monitor for abuse** using analytics events ## Next steps - [Platform-specific integration guides](./troubleshooting) - [Configuration options](./configuration) --- ## Getting started with 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 can be styled to match your brand and configured 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**. ::: ## Quick start To add the web channel to your website: 1. Go to **Integrations** in your Moveo account 2. Select your environment 3. Click **Connect** below the **Web** integration 4. Copy the generated snippet and add it before the `` tag: ```html ``` 5. Add your domain to the trusted domains list 6. Set the web channel state to **Active** That's it! Your web channel is now ready to receive messages. ## Installation options ### Standard installation The standard installation loads the web channel on every page: ```html ``` ### Embed mode Render the chat within your page content instead of as a floating widget: ```html ``` ### Delayed initialization Wait for page load or user interaction before initializing: ```html ``` ## 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**: ```bash # 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 ``` 2. **Add public key to Moveo**: - Go to **Integrations** → **Web** → **Advanced security settings** - Enable **Activate end-to-end encryption** - Paste your public key 3. **Generate JWT on your server**: ```js 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', // Max 5 minutes }); } ``` ```go "crypto/x509" "encoding/pem" "github.com/golang-jwt/jwt" "time" ) func generateToken(userId string) (string, error) { token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{ "sub": userId, // Required "iss": "yourdomain.com", // Required "exp": time.Now().Add(5 * time.Minute).Unix(), }) // Sign with private key privateKey := loadPrivateKey() return token.SignedString(privateKey) } ``` 4. **Initialize with authentication**: ```html ``` ### Passing encrypted user data To securely pass sensitive user information (e.g., 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**: :::warning 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 shown below). ::: ```js 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 encrypted context is available in your AI Agent for personalization but never sent back to the client, ensuring sensitive data remains secure. ### Authentication flow ```mermaid sequenceDiagram participant S as Your Server participant W as Web Client participant M as Moveo.AI S->>W: Generate JWT (signed with private key) W->>M: Send JWT as identity token M->>M: Verify signature with public key M->>M: Check expiration claim alt Token Valid M->>W: Session created W->>M: User sends message M->>W: AI responds else Token Invalid M->>W: JWT rejected W->>S: Request new token S->>W: Generate fresh JWT W->>M: Retry with new token end ``` ## Security best practices 1. **Keep private keys secure** - Never expose them in client-side code 2. **Use short expiration times** - Max 5 minutes for JWT tokens 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: ```html ``` Then embed this page in your mobile app's WebView component. ## Next steps - [Configure appearance and behavior](./configuration) - [Use methods and events](./developer-guide) - [Troubleshoot common issues](./troubleshooting) --- ## Web channel troubleshooting ## Platform-specific integrations ### WordPress WordPress and other CMS platforms may add attributes that interfere with script loading. #### Issue: Script defer attribute WordPress may add `defer` attribute to scripts, causing initialization to fail. #### Solution: Wait for DOM to be ready before initializing: ```html ``` #### WordPress plugin approach For better integration, add to your theme's `functions.php`: ```html function add_moveo_chat() { ?> ``` 4. Select the "Moveo Chat Trigger" you created 5. Save and publish :::caution Google Tag Manager doesn't support ES6 features. Use function syntax instead of arrow functions. ::: ### Magento Magento uses RequireJS which can conflict with standard script loading. #### Solution with RequireJS: ```html ``` #### Alternative: Add to Magento layout XML: ```xml ``` ### Shopify Add the web channel to your Shopify store. #### Option 1: Theme editor 1. Go to Online Store → Themes 2. Click "Actions" → "Edit code" 3. Open `layout/theme.liquid` 4. Add before ``: ```html {% if customer %} {% else %} {% endif %} ``` #### Option 2: Script tag API Use Shopify's Script Tag API for dynamic installation: ```javascript POST /admin/api/2024-01/script_tags.json { "script_tag": { "event": "onload", "src": "https://your-server.com/moveo-shopify-integration.js" } } ``` ### React applications Integrate with React using hooks. #### React hook implementation: ```jsx function useMoveoChat(config) { const [instance, setInstance] = useState(null); const [error, setError] = useState(null); useEffect(() => { // Load script dynamically const script = document.createElement("script"); script.src = "https://web.moveo.ai/web-client.min.js"; script.onload = () => { window.MoveoAI.init(config).then(setInstance).catch(setError); }; script.onerror = () => setError(new Error("Failed to load Moveo script")); document.body.appendChild(script); // Cleanup return () => { if (instance) { instance.destroy(); } document.body.removeChild(script); }; }, []); return { instance, error }; } // Usage function App() { const { instance, error } = useMoveoChat({ integrationId: "YOUR-INTEGRATION-ID", }); useEffect(() => { if (instance) { // Use instance methods instance.updateContext({ page: "home" }); } }, [instance]); return Your app content; } ``` ### Vue.js applications Vue.js plugin for web channel integration. ```javascript // moveo-chat-plugin.js export default { install(app, options) { const script = document.createElement('script'); script.src = 'https://web.moveo.ai/web-client.min.js'; script.onload = () => { window.MoveoAI.init(options) .then((instance) => { app.config.globalProperties.$moveoChat = instance; }) .catch(console.error); }; document.body.appendChild(script); } }; // main.js app.use(MoveoChat, { integrationId: 'YOUR-INTEGRATION-ID', }); // Component usage export default { mounted() { if (this.$moveoChat) { this.$moveoChat.openWindow(); } } }; ``` ## Common issues and solutions ### Issue: Chat not appearing **Symptoms:** Script loads but web channel doesn't appear **Solutions:** 1. **Check trusted domains:** - Verify your domain is in the trusted domains list - Include both www and non-www versions - Check for typos in domain configuration 2. **Verify integration ID:** ```javascript // Check console for errors console.log("Integration ID:", "YOUR-INTEGRATION-ID"); ``` 3. **Check browser console:** - Look for CORS errors - Check for JavaScript errors - Verify network requests succeed ### Issue: CORS errors **Error:** `Access to script has been blocked by CORS policy` **Solutions:** 1. Use the CDN URL exactly as provided 2. Don't modify script headers 3. Ensure HTTPS is used 4. Check firewall/proxy settings ### Issue: Multiple instances **Symptoms:** Chat initializes multiple times **Solution:** ```javascript // Prevent multiple initializations if (!window.moveoChatInitialized) { MoveoAI.init({ integrationId: "YOUR-INTEGRATION-ID", version: "v2", }).then((instance) => { window.moveoChatInstance = instance; window.moveoChatInitialized = true; }); } ``` ### Issue: Local development **Error:** Chat doesn't load on `localhost` **Solution:** Use `127.0.0.1` instead of `localhost`: ```javascript // Development configuration const isDev = window.location.hostname === "127.0.0.1"; const integrationId = isDev ? "DEV-ID" : "PROD-ID"; MoveoAI.init({ integrationId, version: "v2", }); ``` ### Issue: Authentication failures **Symptoms:** JWT rejected, session creation errors **Solutions:** 1. **Check token expiration:** ```javascript // Token must expire within 5 minutes const payload = { sub: userId, iss: domain, exp: Math.floor(Date.now() / 1000) + 300, // 5 minutes }; ``` 2. **Verify RSA keys match:** - Public key in Moveo must match private key on server - Re-generate keys if unsure 3. **Test token generation:** ```javascript // Debug token const token = generateToken(); console.log("Token:", token); // Decode to check claims const decoded = jwt.decode(token); console.log("Claims:", decoded); ``` ### Issue: Messages not sending **Symptoms:** User types but messages don't send **Possible causes:** 1. **Session expired:** Reinitialize chat 2. **Network issues:** Check connectivity 3. **Rate limiting:** Implement throttling 4. **Integration paused:** Check Moveo dashboard ### Issue: Style conflicts **Symptoms:** Chat looks broken or unstyled **Solutions:** 1. **CSS specificity:** ```css /* Increase specificity if needed */ body .web-client-container { z-index: 999999 !important; } ``` 2. **Reset conflicting styles:** ```css .web-client-container * { box-sizing: border-box; } ``` 3. **Use shadow DOM isolation** (if supported) ## Mobile-specific issues ### iOS Safari **Issue:** Viewport sizing problems ```html ``` ### Android WebView **Issue:** File upload not working Enable file access in WebView: ```java webView.getSettings().setAllowFileAccess(true); webView.getSettings().setAllowFileAccessFromFileURLs(true); ``` ## Performance optimization ### Lazy loading Load chat only when needed: ```javascript // Intersection Observer approach const observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting) { loadMoveoChat(); observer.disconnect(); } }); // Observe a trigger element observer.observe(document.getElementById("chat-trigger-section")); ``` ### Bundle size optimization For production builds: ```javascript // Load web client const script = document.createElement("script"); script.src = "https://web.moveo.ai/web-client.min.js"; ``` ## Debugging tools ### Enable debug mode ```javascript MoveoAI.init({ integrationId: "YOUR-INTEGRATION-ID", version: "v2", debug: true, // If supported }).then((instance) => { // Expose for debugging window.DEBUG_CHAT = instance; }); ``` ### Network monitoring Monitor WebSocket connections: ```javascript // Override WebSocket for debugging const OriginalWebSocket = window.WebSocket; window.WebSocket = function (...args) { console.log("WebSocket connection:", args[0]); const ws = new OriginalWebSocket(...args); ws.addEventListener("message", (e) => { console.log("WebSocket message:", e.data); }); return ws; }; ``` ## Getting help If you continue experiencing issues: 1. Check browser console for errors 2. Verify integration settings in Moveo dashboard 3. Test in incognito/private mode 4. Try a different browser 5. Contact Moveo support with: - Integration ID - Error messages - Browser/platform details - Steps to reproduce --- ## Next steps - [Web channel configuration](./configuration.md) - Customize appearance and behavior - [Developer guide](./developer-guide.md) - Advanced integration techniques - [Analytics](../../analytics/overview.md) - Monitor chat performance - [AI Agents](../../ai-agents/overview.md) - Configure your agent's responses --- ## WhatsApp Coexistence Mode ## Overview Coexistence mode allows businesses to use **WhatsApp Business App** (mobile) and **Cloud API** (automated) simultaneously on the same phone number, with bidirectional message synchronization. This is ideal for businesses that want to: - **Maintain manual control** via the WhatsApp Business App for personalized interactions - **Leverage AI automation** via Moveo's Cloud API integration for scalable support - **Keep message history synced** across both platforms --- ## Which setup path should I follow? | Your situation | Setup path | | ----------------------------------------- | ------------------------------------------------------------------------------------------------ | | Setting up WhatsApp for the first time | [New integration setup](#setup-for-new-integrations) - Enable coexistence during embedded signup | | Already have a Moveo WhatsApp integration | [Existing integration setup](#setup-for-existing-integrations) - Re-run embedded signup selecting WhatsApp Business App | :::info New integrations If you're setting up WhatsApp for the first time and want coexistence, follow the standard [WhatsApp Business setup](./whatsapp.md#setup-guide). During embedded signup, when the Meta modal asks you to select a WhatsApp account type, choose **WhatsApp Business App** to enable coexistence automatically. ::: --- ## Prerequisites Before enabling coexistence mode, ensure you have: ✅ **Meta-approved BSP with coexistence capability** - Moveo.AI is a Meta Tech Partner with coexistence support ✅ **Business verification** - PLBV (Phone-Level Business Verification) or Meta Verified status ✅ **Supported region** - ❌ Nigeria and South Africa are **not supported** for coexistence ✅ **WhatsApp Business App installed** - Installed on your mobile device --- ## Setup for new integrations ### Embedded Signup with Coexistence 1. Navigate to **Integrations** in your Moveo account 2. Select your environment 3. Click **Configure** on the WhatsApp card 4. Follow the embedded signup flow 5. **Key step**: When the Meta modal asks you to select a WhatsApp account type, choose **WhatsApp Business App** — this enables coexistence automatically 6. Enter your existing WhatsApp Business App phone number 7. Meta displays a QR code → Scan with WhatsApp Business App 8. Accept the consent screen (optionally enable history sharing) --- ## Setup for existing integrations ### Step 1: Check eligibility | Requirement | Status | | --------------------------------------------- | -------------------------------------- | | Meta-approved BSP with coexistence capability | ✅ Moveo.AI is Meta Tech Partner | | Business verification (PLBV or Meta Verified) | Must verify | | Region supported | ❌ Nigeria, South Africa not supported | ### Step 2: Re-run embedded signup 1. Install WhatsApp Business App on phone (if not already) 2. Go to **Integrations** → WhatsApp → **Configure** and start the embedded signup flow 3. **Key step**: When the Meta modal asks you to select a WhatsApp account type, choose **WhatsApp Business App** — this enables coexistence automatically 4. Enter your existing phone number 5. Scan QR code displayed by Meta 6. Accept consent screen --- ## How it works ### Message flow When coexistence mode is enabled, messages flow bidirectionally: ``` Customer sends message ↓ Both WhatsApp Business App AND Cloud API receive it ↓ AI agent responds via Cloud API (appears in App) ↓ Human agent replies via App ↓ AI agent is paused — new bot sessions are blocked for this user ↓ Message visible in Human Chat with 📱 icon ↓ Human agent sends reset command → AI agent resumes on next user message ``` :::caution Messages are visible to the end user All messages sent from the WhatsApp Business App — including the reset command — are delivered to the end user's WhatsApp chat. There is no way to send a "hidden" message from the Business App. For this reason, you can configure a custom reset command that looks natural in conversation. ::: ### Key behaviors | Scenario | Behavior | | --------------------- | ----------------------------------------------------------------------------------------------------- | | Human agent replies via App | AI agent pauses (handover), message recorded in Human Chat with 📱 icon | | Human agent sends location | Recorded as "Shared location: \{name\}" | | Human agent sends contact | Recorded as "Shared contact: \{name\}" | | Session expired | Message still reaches user, just not tracked in Moveo | | No active session | AI agent session creation is blocked until the coexistence timeout expires or the human agent resets | ### Handing back to the AI agent When the human agent is done and wants the AI agent to resume, they send the **reset command** from the WhatsApp Business App. This removes the block on the AI agent, so the next message from the end user will create a fresh session handled by the bot. The default reset command is `/reset`, but you can configure a custom command text (e.g., `done`, `handoff`) to make it look more natural to the end user, since the message is visible in their chat. The matching is **case-insensitive** and ignores leading/trailing whitespace. :::warning Rule required For the AI agent to automatically handle the conversation after the reset command, you must have a rule with the trigger **"A customer starts a conversation"** that assigns the AI agent. After the reset, the next user message creates a new session — this trigger ensures the bot is assigned to it. See [Rules](../environments/rules.md) for setup instructions. ::: :::info Reset command is not recorded The reset command is treated as a control message — it is **not** saved in the session history. However, it is still visible to the end user as a regular WhatsApp message. ::: | Setting | Default | Description | | -------------------------- | --------- | ------------------------------------------------ | | `coexistence_reset_text` | `/reset` | The command text the human agent sends to reset. Can be customized to any text. Set to empty to disable. | | `coexistence_timeout` | 7 days | How long the AI agent stays paused without a reset | --- ## Verification checklist ### Pre-setup - [ ] Business is verified (PLBV or Meta Verified) - [ ] Region is supported - [ ] WhatsApp Business App installed on device ### Post-setup - [ ] Coexistence enabled via embedded signup (selected WhatsApp Business App) - [ ] Test: Send message from App → appears in Human Chat with 📱 icon - [ ] Test: Session hands over when agent replies via App --- ## Limitations | Limitation | Impact | | --------------------------------- | ----------------------------------------- | | **No OBA/Blue Badge** | Not available for coexistence accounts | | **Broadcast lists disabled** | Must use API for broadcasts | | **Companion devices unsupported** | Windows/WearOS devices cannot be linked | | **14-day media limit** | Older media cannot sync | --- ## Troubleshooting
No 📱 icon on messages **Cause**: `is_coexistence` flag not saved properly **Solution**: Re-save the integration settings in Moveo with coexistence mode enabled
"Session not found" warnings in logs **Cause**: Normal for conversations that started before coexistence was enabled **Solution**: This is expected behavior. New conversations will be tracked properly.
Messages from Windows/WearOS missing **Cause**: Companion devices (Windows, WearOS) are not supported in coexistence mode **Solution**: Use the phone app only for sending messages
Reset command not working **Symptoms**: The human agent sends the reset command from the WhatsApp Business App but the AI agent doesn't resume. **Possible causes**: 1. **The end user hasn't sent a new message yet.** The reset command unblocks the AI agent, but the bot only resumes when the end user sends their next message (which creates a fresh session). This is expected behavior. 2. **The command text doesn't match.** The reset text must match the configured `coexistence_reset_text` value (default: `/reset`). The match is case-insensitive, but the content must match — for example, if the default is `/reset`, sending `reset` without the slash won't work. 3. **Reset is disabled.** If `coexistence_reset_text` is set to an empty string, the reset command is disabled entirely. The AI agent will only resume after the coexistence timeout expires.
--- ## Resources ### Official documentation - [WhatsApp Coexistence Overview](https://developers.facebook.com/docs/whatsapp/coexistence) - [SMB Message Echoes Webhook](https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components#smb-message-echoes) - [WhatsApp Business Platform](https://developers.facebook.com/docs/whatsapp) ### Support - [Meta Business Help Center](https://www.facebook.com/business/help) - Moveo support: support@moveo.ai --- ## Next steps Once coexistence mode is enabled: 1. **Test the integration** - Send a message from the WhatsApp Business App and verify it appears in Human Chat with the 📱 icon 2. **Train your team** - Ensure agents understand that replying via the App will trigger a handover 3. **Configure your AI Agent** - See [WhatsApp Business](./whatsapp.md#configuration-options) for profile customization and message templates --- ## WhatsApp Flows WhatsApp Flows collect information from users through native forms that open directly inside WhatsApp. Instead of asking questions one by one and waiting for responses, flows present a complete form where users fill in everything at once (dates, selections, text fields) and submit it in a single action. Consider reporting a broken package through a chatbot. Without flows, the bot asks "What's your order number?", waits for a reply, then "What's your name?", waits again, then "Can you describe the damage?". This is a tedious exchange. With flows, users tap a button, fill out a clean form with fields for order number, name, and damage details, and submit it all together. ## When to use flows Flows work best for collecting multiple pieces of structured information: A dental clinic uses flows to let patients book appointments. The form includes a date picker, available time slots pulled from their calendar system, and fields for name and phone number. Patients complete the entire booking in under a minute without leaving WhatsApp. A B2B software company qualifies leads through flows. When someone asks about pricing, the bot sends a quick form asking for company size, industry, and specific needs. Sales gets structured data instead of parsing through chat messages. An ecommerce company collects feedback after purchase through flows. Customers rate their experience on a scale, select what they liked from a list, and optionally leave comments. Response rates are higher than email surveys because it's so frictionless. A tech company creates support tickets through flows. Users categorize their issue from a dropdown, describe the problem, and optionally mark it as urgent. The support team receives properly categorized tickets instead of unstructured messages. --- ## Before starting A few things need to be in place: 1. **WhatsApp Business integration** already active in the Moveo environment. If not set up yet, follow the [WhatsApp integration guide](./whatsapp) first. 2. **A flow created in Meta Business Manager**. Flows are designed in Meta's Flow Builder, where the screens, fields, and validation are all defined. Moveo sends and receives flows, but doesn't create them. 3. **The Flow ID** from Meta Business Manager. This ID is entered when configuring the flow in Moveo. For dynamic flows that pull live data (like available appointment slots), a custom endpoint is also required. More on that in the [Data Exchange section](#data-exchange-dynamic-flows). --- ## How flows work Here's what happens when an [AI Agent](../ai-agents/quickstart.md) sends a flow to a user: ```mermaid sequenceDiagram participant U as User participant W as WhatsApp participant M as Moveo AI Agent participant F as Flow (Meta) M->>W: Send flow message with CTA button W->>U: Display message + "Open Form" button U->>W: Tap button W->>F: Open flow (fullscreen form) U->>F: Complete and submit form F->>W: Close flow W->>M: Return response data Note over M: Data stored in context.flow_response M->>W: Continue conversation W->>U: Display follow-up message ``` The AI Agent sends a message with a CTA button. The user taps it, and WhatsApp opens the flow as a fullscreen form. Once submitted, the flow closes, and all the data entered becomes available in `context.flow_response`. The agent can then use that data to continue the conversation, whether confirming the booking, thanking the user for feedback, or proceeding with the next step. --- ## Creating a flow in Meta Flows are built in Meta Business Manager, not in Moveo. Here's the quick version: 1. Go to the WhatsApp Business Account in [Meta Business Manager](https://business.facebook.com) 2. Navigate to **Account tools** → **Flows** 3. Create a new flow using the Flow Builder 4. Design the screens and fields 5. Copy the **Flow ID** (needed for Moveo) For detailed instructions on building flows, refer to [Meta's WhatsApp Flows documentation](https://developers.facebook.com/docs/whatsapp/flows). :::note Flows must be **published** in Meta before they work in production. During development, enable **draft mode** in Moveo to test unpublished flows. ::: --- ## Adding a flow to an AI Agent Once a flow exists in Meta, it can be triggered from any [node](../ai-agents/dialogs.md) in the AI Agent using the **WhatsApp Flow** response type. ### Configuration fields | Field | Required | What it does | Example | | ------------------ | -------- | ------------------------------------------------------------------------- | ----------------------------------------- | | **Flow ID** | Yes | ID from Meta Business Manager that identifies which flow to send | `1234567890123456` | | **Body** | Yes | Message users see before the button (e.g., “Let’s book your appointment”) | Let’s book your appointment | | **Button text** | Yes | What the CTA button says (e.g., “Book Now”). Max 20 characters | Book Now | | **Flow action** | Yes | Either `navigate` (simple) or `data_exchange` (dynamic) | `navigate` | | **Header** | No | Optional header text above the body | Appointment Booking | | **Footer** | No | Optional footer text below the body | Takes about 1 minute | | **Initial screen** | No | Which screen to start on (for navigate flows) | `APPOINTMENT_FORM` | | **Initial data** | No | JSON data to pass to the first screen | `{"key_1": "data", "key_2": "more data"}` | | **Draft mode** | No | Enable to test unpublished flows | `true` | --- ## Navigate vs Data Exchange There are two types of flows, and choosing the right one depends on whether the form content is static or dynamic. ### Navigate (simple flows) With navigate flows, although everything is defined upfront in Meta's Flow Builder, a payload with [context variables](../ai-agents/context.md) can be passed to the first screen in the `initial_data` field. The screens, options, and validation rules are all static. When a user opens the flow, they navigate through predefined screens. Navigate flows work well for: - Contact forms with fixed fields - Surveys with predetermined questions - Lead capture forms - Any form where the options don't change based on user input or external data ### Data Exchange (dynamic flows) Data Exchange flows call a custom endpoint on each screen transition. This allows populating dropdowns dynamically, validating input against live data, or changing what the user sees based on their previous selections. Data Exchange flows are useful for: - Cascading dropdowns (selecting a country populates the state dropdown) - Live availability (only showing appointment slots that are actually open) - Dynamic pricing based on selections - Validation against the database (checking if an email is already registered) :::warning Data Exchange flows require building and hosting an endpoint that handles Meta's encryption protocol (RSA-OAEP + AES-128-GCM). See [Building a Data Exchange endpoint](#building-a-data-exchange-endpoint) for details. ::: --- ## Using flow response data When a user submits a flow, all responses land in `context.flow_response`. Individual fields can be accessed in subsequent nodes to personalize the conversation or pass data to external systems. For example, if an appointment booking flow collected `date`, `time`, `name`, and `phone`, the data can be accessed like this: ```javascript const booking = context.flow_response; // Use the data to confirm the appointment const message = `Thanks ${booking.name}! Your appointment is confirmed for ${booking.date} at ${booking.time}. A reminder will be sent to ${booking.phone}.`; ``` A `trigger_node_id` can also be configured to route the conversation to a specific [dialog node](../ai-agents/dialogs.md) after the flow completes. This is useful when different follow up paths are needed based on what the user submitted. This [context variable](../ai-agents/context.md) can be used like any other context variable in the dialog flows to populate text responses. --- ## Building a Data Exchange endpoint Data Exchange flows require an endpoint that Meta's servers can call. The endpoint receives encrypted requests and must return encrypted responses. The encryption uses two layers: - **RSA-OAEP (2048-bit)** for the key exchange - **AES-128-GCM** for the actual payload The endpoint must: 1. Accept POST requests from Meta 2. Decrypt the incoming payload 3. Process the flow action (determine what to show next) 4. Encrypt and return the response 5. Respond within 10 seconds Here's what a response looks like before encryption: ```json { "screen": "SELECT_TIME", "data": { "available_slots": ["9:00 AM", "10:30 AM", "2:00 PM", "4:30 PM"], "selected_date": "January 15, 2024", "message": "Here are the available times for your selected date:" } } ``` For complete implementation details including encryption examples, see [Meta's endpoint guide](https://developers.facebook.com/docs/whatsapp/flows/guides/implementingyourendpoint). --- ## Testing flows Before going live, test the flow thoroughly using draft mode. 1. Enable **Draft mode** in the WhatsApp Flow response configuration 2. Send a test message from a phone number registered in the Meta App 3. Tap the button and go through the flow 4. Check that `context.flow_response` contains the expected data 5. Verify subsequent nodes handle the response correctly :::note Draft mode only works with test phone numbers registered in the Meta App. Regular users can't see unpublished flows. ::: ### What to check - The flow opens when users tap the button - All form fields render correctly - Validation errors show for invalid input - The form submits successfully - Response data appears in `context.flow_response` - The agent handles the response appropriately ### Common issues | What's happening | Likely cause | What to try | | ---------------------- | -------------------------------------------------- | -------------------------------------------------- | | Flow won't open | Wrong Flow ID or flow isn't published | Double-check the ID; enable draft mode for testing | | Response data is empty | Field names in the code don't match the flow | Check the exact field names in Meta's Flow Builder | | Timeout errors | Data Exchange endpoint is too slow | The endpoint must respond within 10 seconds | | Encryption failures | Keys or encryption implementation don't match spec | Review Meta's encryption documentation carefully | --- ## Limitations **Platform constraints:** - Flows only work on WhatsApp. Other channels don't support them - Meta must approve flows before production use - The 24-hour messaging window still applies - Flows are mobile-only (no desktop WhatsApp support) **Flow design limits:** - Maximum 10 screens per flow - Users can input text and make selections, but can't upload files - All text fields have character limits - Some flow types don't support back navigation **Technical limits:** - Data Exchange endpoints must respond within 10 seconds - All Data Exchange communication requires encryption - Flow content is determined at screen transitions. There are no live updates within a screen --- ## Learn more **Meta documentation:** - [WhatsApp Flows overview](https://developers.facebook.com/docs/whatsapp/flows) - [Flows API reference](https://developers.facebook.com/docs/whatsapp/flows/reference) - [Building your endpoint](https://developers.facebook.com/docs/whatsapp/flows/guides/implementingyourendpoint) **Related Moveo guides:** - [WhatsApp Business integration](./whatsapp) - [Context variables](../ai-agents/context.md) - [Webhooks](../ai-agents/webhooks.md) --- ## WhatsApp Business ## Overview WhatsApp Business integration enables your AI Agent to communicate with customers through the world's most popular messaging platform. With over 2 billion users globally, WhatsApp provides a familiar and convenient channel for customer support, sales, and engagement. This integration leverages Meta's WhatsApp Business API to provide: - **24/7 automated customer support** through your verified business number - **Seamless handover** to human agents when needed - **Rich messaging capabilities** including text, images, and interactive elements - **Global reach** with end-to-end encryption for secure conversations --- ## Prerequisites Before setting up the WhatsApp integration, ensure you have: ✅ **A dedicated phone number** for WhatsApp Business - Must be able to receive SMS or voice calls for verification - Cannot be registered to any existing WhatsApp account (personal or business) - Can be migrated from another WhatsApp Business provider if needed ✅ **Business verification requirements** - Company's legal name and website - Valid business email address - SSL-secured website with clear business information ✅ **Meta Business Account** (or ability to create one) - Admin access to your Facebook Business Manager - Authority to grant permissions to third-party apps ✅ **Moveo account setup** - An active [AI Agent](../ai-agents/overview.md) configured - An [environment](../environments/overview.md) to connect the integration --- ## How it works The WhatsApp Business integration creates a bridge between your customers on WhatsApp and your Moveo AI Agent: 1. **Customer initiates conversation** by messaging your WhatsApp Business number 2. **Moveo receives the message** through Meta's WhatsApp Business API 3. **AI Agent processes and responds** based on your configured knowledge and dialogs 4. **Messages are delivered** back to the customer through WhatsApp 5. **Handover to human agents** when the AI Agent determines it's necessary All conversations maintain WhatsApp's end-to-end encryption and comply with Meta's business messaging policies. --- ## Setup guide Moveo offers two methods to connect WhatsApp Business: :::tip Already using WhatsApp Business App? If you want to keep using the **WhatsApp Business App** on your phone alongside Moveo's AI automation, see [WhatsApp Coexistence Mode](./whatsapp-coexistence.md). This allows agents to respond directly from the mobile app while keeping messages synced with Human Chat. ::: ### Option 1: Embedded Signup (Recommended) The embedded signup flow is the fastest way to get started. It handles all the technical configuration automatically.
📱 Connect with Embedded Signup #### Step 1: Prepare your information Before starting, gather: - Your phone number for WhatsApp Business - Company registration details - Business website URL - Business email address #### Step 2: Start the connection process 1. Navigate to **Integrations** in your Moveo account 2. Select your environment 3. Click **Configure** on the WhatsApp card 4. Select **Connect** #### Step 3: Authenticate with Meta 1. Log in to Facebook with your personal or professional account 2. Select **Continue as [Your Name]** 3. Select **Get Started** #### Step 4: Configure Meta Business Account - **Existing account**: Select from dropdown - **New account**: Fill in your company information #### Step 5: Set up WhatsApp Business Account When selecting your WhatsApp account type, choose **WhatsApp Business App** if you want to use [coexistence mode](./whatsapp-coexistence.md) — this lets human agents respond from the mobile app while the AI agent handles automated conversations on the same number. Fill in: - Account Name - Display Name (shown to customers) - Business Category #### Step 6: Verify your phone number 1. Enter your phone number 2. Choose verification method (SMS or voice call) 3. Enter the 6-digit verification code 4. Review permissions and limits 5. Click **Finish** #### Step 7: Activate the integration 1. Return to Moveo's Integration page 2. Wait for account registration to complete (usually instant) 3. Toggle **Active** to enable the integration 4. Click **Get Started**
### Option 2: Manual Setup
⚙️ Manual connection flow (Advanced) Use this method if you need custom configuration or already have a WhatsApp Business API setup. #### Prerequisites for manual setup - Verified [Facebook Business Manager](https://m.facebook.com/help/1710077379203657) account with admin access - Meta developer account with an [App](https://developers.facebook.com/) connected to your Business Manager #### Step 1: Create WhatsApp product in your Meta App 1. Navigate to your Meta App 2. Go to **Add Product** page 3. Click **Set up** under WhatsApp 4. Select your Meta Business Manager account #### Step 2: Add and verify your phone number 1. Click **Add phone number** in your WhatsApp product 2. Complete the verification form 3. Wait for Meta verification (1-2 business days) Monitor verification status in WhatsApp Manager: #### Step 3: Configure Moveo integration In Moveo Console: 1. Add a new WhatsApp Integration 2. Select **Manual setup** 3. Configure the following fields: **Required configuration:** | Field | Where to find it | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Access Token** | Generate via [Business Manager](https://www.facebook.com/business/help/503306463479099) with `whatsapp_business_messaging` and `whatsapp_business_management` permissions | | **App Secret** | Meta App → Settings → Basic | | **Phone Number ID** | WhatsApp product → Your phone number | | **Verify Token** | Create your own secure token | #### Step 4: Configure webhook 1. Get your Integration ID from the Moveo URL 2. In Meta App → WhatsApp → Configuration: - Callback URL: `https://channels.moveo.ai/v1/whatsapp/` - Verify token: Use the token from Step 3 - Subscribe to `messages` webhook field #### Step 5: Register phone number After Meta verifies your number: 1. Go to WhatsApp Configuration in Meta App 2. Register your phone number
--- ## Configuration options ### Business profile customization Customize how your business appears to customers in WhatsApp: - **Profile picture**: Your business logo or avatar - **Business description**: Brief description of your services - **Business hours**: Operating hours displayed to customers - **Category**: Industry classification - **Website**: Link to your business website Access these settings in [WhatsApp Manager](https://business.facebook.com/wa/manage/home/). ### Message templates WhatsApp requires pre-approved templates for business-initiated conversations: 1. Create templates in WhatsApp Manager 2. Submit for Meta approval (usually it takes less than a minute) 3. Use approved templates for: - Appointment reminders - Order updates - Account notifications - Re-engagement campaigns ### Rate limits and messaging tiers WhatsApp assigns tiers to outbound messages based on your business verification and quality rating. This **does not apply** when the message is initiated by the customer: | Tier | Daily conversation limit | Requirements | | ---------- | ------------------------ | ------------------------------ | | Unverified | 50 | Phone number verified | | Tier 1 | 1,000 | Business verified | | Tier 2 | 10,000 | Quality rating: Medium or High | | Tier 3 | 100,000 | Consistent quality metrics | | Tier 4 | Unlimited | High volume, excellent quality | --- ## Testing your integration ### Test mode Before going live, test your AI Agent with WhatsApp using Moveo's test number: 1. Go to Integrations → WhatsApp 2. Select **Test Integration** 3. Add your personal WhatsApp number 4. Send a message to the test number 5. Verify AI Agent responses ### Test scenarios Validate these key scenarios: - ✅ Welcome message and greeting - ✅ FAQ responses - ✅ Multi-turn conversations - ✅ Handover to human agent - ✅ Media handling (images, documents) - ✅ Error handling and fallback responses --- ## Common use cases ### Customer support - 24/7 automated responses to common queries - Order status and tracking information - Technical troubleshooting guides - Escalation to human agents for complex issues ### Sales and lead generation - Product information and recommendations - Price quotes and availability checks - Appointment scheduling - Lead qualification and routing ### Notifications and updates - Order confirmations and shipping updates - Appointment reminders - Account alerts and security notifications - Marketing campaigns (with user consent) --- ## Troubleshooting ### Connection issues
Phone number verification fails - Ensure the number can receive SMS/calls - Check it's not registered to any WhatsApp account - Try voice call if SMS doesn't arrive - Contact Meta support if verification repeatedly fails
Business verification pending - Review your website for clear business information - Ensure SSL certificate is valid - Add privacy policy and terms of service - Typical approval time: 1-2 business days
Messages not being received - Verify integration is set to **Active** - Check webhook configuration in Meta App - Confirm phone number registration is complete - Review Meta App permissions
### Message delivery issues
Customer doesn't receive responses - Check WhatsApp messaging tier limits - Verify template approval for business-initiated messages - Review quality rating in WhatsApp Manager - Ensure customer hasn't blocked your number
Media files not sending - Verify file size limits (images: 5MB, documents: 100MB) - Check supported formats (JPEG, PNG, PDF, etc.) - Ensure proper media URL configuration - Review Meta's media guidelines
--- ### Migration issues
Phone migration blocked by Two-Factor Authentication (2FA) - Error message: `Please ensure two-step authentication is disabled.` - Cause: Two-step verification is enabled on the source WhatsApp Business Account (WABA). - Resolution: - Disable two-step verification in WhatsApp Manager. See Meta: [Disabling Two-Step Verification](https://developers.facebook.com/docs/whatsapp/cloud-api/phone-numbers#disabling-two-step-verification) - In Moveo, delete the failed integration and reconnect after disabling 2FA
Missing payment method/credit line after migration - Error message: `Your WhatsApp account must have an active credit line in order to send messages after migration.` - Cause: The new or migrated WABA (WhatsApp Business Account) has no active payment method/credit line in Meta Business Manager. - Resolution: - Add a valid payment method to the WABA in Meta Business Manager - In Moveo, delete the integration and reconnect once billing is active
--- ## Limitations ### Platform limitations - **24-hour messaging window**: After 24 hours of customer inactivity, only template messages allowed - **Media restrictions**: Limited file types and sizes - **Rate limits**: Based on tier and quality rating - **Template approval**: Required for business-initiated conversations ### Integration constraints - One phone number per WhatsApp Business account - Cannot use personal WhatsApp numbers - Business verification required for higher tiers - Geographic restrictions in some countries --- ## Resources ### Official documentation - [WhatsApp Business Platform](https://developers.facebook.com/docs/whatsapp) - [Embedded Signup Errors](https://developers.facebook.com/docs/whatsapp/embedded-signup/errors/) - [WhatsApp Manager](https://business.facebook.com/wa/manage/home/) - [Business Verification](https://www.facebook.com/business/help/2058515294227817) ### Support - [Meta Business Help Center](https://www.facebook.com/business/help) - [WhatsApp Business API Support](https://www.facebook.com/business/help/2640149499569241) - Moveo support: support@moveo.ai --- ## Next steps Once your WhatsApp integration is active: 1. **Configure your AI Agent** with WhatsApp-specific responses 2. **Set up message templates** for proactive messaging 3. **Test thoroughly** before promoting your WhatsApp number 4. **Monitor analytics** to optimize response quality 5. **Train your team** on handover procedures --- ## Zendesk Chat ## Overview Zendesk Chat integration enables your AI Agent to work seamlessly within your existing Zendesk support infrastructure. By connecting Moveo with Zendesk, you create an intelligent first line of support that can handle routine inquiries while smoothly escalating complex issues to your human agents. This integration provides: - **Unified support experience** with AI and human agents working together - **Automatic ticket creation** for all customer conversations - **Tag-based routing** to direct conversations to the right AI Agent or team - **Seamless handover** between AI and human agents - **Complete conversation history** maintained in Zendesk --- ## Prerequisites Before setting up the Zendesk integration, ensure you have: ✅ **Zendesk requirements** - Zendesk Chat **Enterprise** version (required for API access) - Administrator role in your Zendesk account - Active Zendesk Support subscription ✅ **Moveo account setup** - An active [AI Agent](../ai-agents/overview.md) configured - An [environment](../environments/overview.md) selected for the integration ✅ **Technical requirements** - Authority to create API clients in Zendesk - Access to Zendesk Chat settings and configuration :::note Zendesk Chat is an add-on to Zendesk Support. Both services must be active for the integration to work. ::: --- ## How it works The Zendesk integration creates a bridge between your customers and your support team, with Moveo's AI Agent acting as an intelligent intermediary: 1. **Customer initiates chat** through your Zendesk Web Widget 2. **Ticket is created** automatically in Zendesk Support 3. **AI Agent engages** based on tags and routing rules 4. **Conversation proceeds** with AI handling routine inquiries 5. **Handover occurs** when human assistance is needed 6. **History is preserved** for seamless agent takeover The integration operates through Zendesk's **Web Widget Classic** (chat mode), not the messaging widget or answer bot. --- ## Setup guide ### Step 1: Get info from Moveo 1. Log in to your Moveo.AI account and click to **Connect** a new Zendesk integration. 2. Note down the _Client Name_, _Company_, and _Callback URL_. ### Step 2: Create Zendesk agent 1. Go to your Zendesk Chat account. 2. Create a new Agent and set the role to **Administrator**. 3. This new Agent is the AI Agent, so give it a name that suits your business needs. ### Step 3: Get the authorization details 1. Log in to Zendesk Chat using the Agent you just created. 2. Go to **Settings** → **Account** → **API & SDKs** → **Add API client**. 3. Provide the _Client Name_, _Company_, and _Callback URL_ you got from the [info from Moveo](#step-1-get-info-from-moveo). 4. Click **Create API client**. 5. Note down the _Client ID_ and _Client Secret_. 6. Note down the _Subdomain_ of your Zendesk integration. You can find your domain by inspecting the Zendesk URL. For example, if the URL of your Zendesk chat is `https://mycompany.zendesk.com/...`, the subdomain is `mycompany`. ### Step 4: Pass details to Moveo 1. Go back to the Moveo.AI Zendesk integration. 2. Copy the _Client ID_, _Client Secret_, and _Subdomain_ from the authorization details into the **Authorize Zendesk** section. 3. Click connect and follow the authorization prompt. ### Step 5: Activate and select tags 1. After connecting your integration, set the status to active to start receiving messages. 2. Optional: Select the tags you want the AI Agent to engage. If you select no tags, the assistant will respond to all messages. --- ## Configuration options ### Zendesk-side configuration When integrating Moveo with Zendesk, it is important to note that Moveo's AI capabilities will operate through Zendesk's **Web Widget Classic**, where chat interactions take place. This is different from using Zendesk's native answer bot, which is considered messaging through the Web Widget. :::note This distinction is important because when the Zendesk answer bot is handling a conversation, no ticket has been created in Zendesk and no agents are engaged. However, when using Moveo's integration as an agent within Zendesk and through the API client established in chat, Moveo's AI capabilities will only be utilized when a ticket has already been created. ::: In order for the Zendesk chat to result in a conversation that includes one or more Moveo AI Agents and also creates a Zendesk ticket, you need to perform the following steps on the Zendesk side: - Go to Admin Center → Channels → Web Widget (Classic) and enable the **Chat** setting. - Go to Settings → Widget → Forms and turn on the Pre-chat form. You can also require the user to select a specific department in the pre-chat form, where they will still have the option to go straight to a live agent if they choose a department that is not linked to Moveo. For example, if a user selects the **Marketing** department, Moveo handles the conversation. If they select the **Customer Support EN** department, the conversation goes to a live agent. - Always have at least one agent with **Online** status in Zendesk support. This agent can be either one of your live agents or Moveo. --- ## Testing your integration ### Test scenarios 1. **Basic functionality** - Send a test message through the Web Widget - Verify AI Agent responds appropriately - Check ticket creation in Zendesk Support 2. **Tag-based routing** - Test messages with different department selections - Verify correct AI Agent engagement - Confirm tag application 3. **Handover process** - Trigger a handover scenario - Verify smooth transition to human agent - Check conversation history preservation ### Monitoring - **Agent status**: Ensure at least one agent is online - **Widget visibility**: Confirm chat widget appears correctly - **Response times**: Monitor AI Agent response speed - **Ticket creation**: Verify all conversations create tickets --- ## Common use cases ### Tier 1 support automation - Handle password resets and account questions - Provide product information and pricing - Process simple troubleshooting steps - Collect initial information for escalation ### Department-based routing - Marketing inquiries to specialized AI Agent - Technical support to troubleshooting flows - Sales questions to lead qualification - Billing issues to payment assistance ### After-hours coverage - 24/7 AI Agent availability - Ticket creation for morning follow-up - Emergency escalation protocols - FAQ handling during off-hours --- ## Best practices ### Widget configuration - Enable pre-chat forms for better routing - Set clear department options - Configure operating hours correctly - Customize widget appearance to match brand ### AI Agent setup - Train on your Zendesk knowledge base - Configure appropriate handover triggers - Set clear escalation criteria - Use tags effectively for routing ### Team coordination - Keep at least one agent online status - Define clear handover procedures - Document AI Agent capabilities for team - Regular review of AI-handled tickets --- ## Troubleshooting
Handover not working Handover might fail if triggered immediately when dialog starts: - Insert a pause response before handover - Ensure proper agent availability - Check department configuration - Verify routing rules
AI Agent not responding - Verify integration is set to Active in Moveo - Check API client credentials are correct - Ensure at least one agent has Online status - Confirm Web Widget Classic is enabled (not messaging)
Tickets not being created - Verify Zendesk Support is active - Check Web Widget configuration - Ensure pre-chat form is enabled - Review ticket creation rules
Wrong AI Agent engaging - Review tag selection in Moveo integration - Check department routing rules - Verify AI Agent assignment to correct tags - Test with different department selections
--- ## Limitations ### Platform requirements - **Enterprise only**: Zendesk Chat Enterprise required for API access - **Widget type**: Only works with Web Widget Classic (chat mode) - **Ticket requirement**: AI Agent only engages after ticket creation - **Online status**: Requires at least one online agent ### Integration constraints - Cannot use Zendesk's native answer bot simultaneously - Pre-chat form recommended for proper routing - Limited to chat interactions (not messaging) - Tag-based routing only --- ## Resources ### Documentation - [Zendesk Chat Documentation](https://support.zendesk.com/hc/en-us/categories/360002048633) - [Web Widget Classic Guide](https://support.zendesk.com/hc/en-us/articles/360022184314) - [API Client Management](https://support.zendesk.com/hc/en-us/articles/360022185314) ### Support - [Zendesk Support Center](https://support.zendesk.com) - Moveo support: support@moveo.ai --- ## Next steps Once your Zendesk integration is active: 1. **Configure departments** for proper routing 2. **Train your AI Agent** on common support scenarios 3. **Set up tags** for different conversation types 4. **Test thoroughly** before full deployment 5. **Monitor performance** and optimize responses --- ## Knowledge bases best practices The following guide outlines best practices for optimizing your knowledge base to ensure optimal performance from your AI Agent. Adhering to these guidelines will enable the model to accurately match the appropriate document and provide precise responses to user queries. ## Provide clear and concise documents - Ensure that each topic is presented clearly and concisely. - Aim to address one topic per document. - Avoid lengthy or convoluted answers that could cause confusion. ## Include context Provide necessary context or background information for each topic. This aids the system in better understanding the question and generating relevant responses. Here's an example: ```md ## How do I install the latest updates for Product XYZ? Product XYZ regularly releases updates to enhance performance, add new features, and address any bugs or security vulnerabilities. Staying up-to-date with these updates is crucial for ensuring optimal functionality and security of your software. ``` ## Use standard language Utilize universally understood language and terminology. Minimize the use of industry-specific jargon or abbreviations unless essential for clarity. ## Numbering or bullet points Utilize bullet points or numbered lists for easy reference. This facilitates the model in identifying and addressing each subquestion individually. Here's an example: ```md ## What are the features of Product XYZ? The features of Product XYZ include: - Affordability - Speed - Sleek design ``` ## Avoid ambiguity between documents Ensure documents are clear and unambiguous to enhance clarity within the knowledge base. As an illustrative example, it is advisable to create a unified, comprehensive document guiding users on adding a card to a digital wallet. This document should encompass instructions for both Google Pay and Apple Pay, avoiding the creation of separate documents for each: **"How do I add my card to Google Pay"** and **"How do I add my card to Apple Pay"**. ## Next steps - [Test your knowledge base](./test.md) - Verify your content produces accurate responses - [Publish content](./publish.md) - Make your optimized content available to live agents - [Knowledge base overview](./overview.md) - Learn more about knowledge base features --- ## Knowledge base through documents Upload your own documents to enable your AI Agent to answer questions based on them. ## Upload document To upload documents to your Moveo AI Agent: 1. Navigate to **Knowledge** in the top navigation bar. 2. Select the knowledge base you want to add documents to, or create a new knowledge base as described in the [Knowledge base overview](./overview.md). 3. Navigate to the **Documents** tab. 4. Click the **Upload** button, located on the right side of the **Documents** tab. 5. A sidebar will appear, featuring a drag-and-drop component. You can either: - Drag and drop your desired files directly into the designated area. - Click **Browse** to select files from your computer. - Supported file types include: `.docx`, `.pdf`, `.txt`, `.md`, and `.html`. 6. Once you have selected your files, click the **Upload** button within the sidebar to begin the upload process. Each uploaded document progresses through four stages: - **Pending**: The document is not yet available for use. - **Indexing**: The document is being analyzed, processed, and optimized for efficient retrieval by your AI Agent. - **Draft**: The document is not live for production use but can be utilized for testing your AI Agent. - **Published**: The document has been successfully processed and is now ready for use by your AI Agent. ## Replace a document Replace an existing document by clicking on the three dots, selecting **Replace**, and uploading your replacement document. ## Webpage source The Webpage Source field appears in the sidebar when you click on a document row in the table and allows you to optionally add a URL (e.g., https://example.com) that will be shown as a clickable source link in the webchat widget. This helps improve credibility by letting end users trace answers back to an external source, especially when the uploaded document doesn’t have one automatically. If left empty, no source link will be displayed, even if the document content is used in an answer. ## Delete a document 1. Locate the document you want to delete in the table. 2. Click the three dots icon on the document row. 3. Select **Delete** from the dropdown menu. 4. Confirm the deletion when prompted. :::warning Deleting a document removes it permanently from your knowledge base. Your AI Agent will no longer be able to reference this content. ::: ## Next steps - [Publish content](./publish.md) - Make your documents available to live agents - [Test your knowledge base](./test.md) - Verify your agent answers correctly - [Best practices](./best-practices.md) - Optimize your document content --- ## Knowledge base through external sources '@site/src/components/Img'; Connect to an existing knowledge base to allow Moveo to ingest your articles. Moveo supports external sources including [Intercom](#intercom) and [Zendesk](#zendesk) knowledge bases. ## Intercom To establish a connection with Intercom, follow these steps: 1. Click the **Add** button 2. Select your desired source from the "Select source" dropdown menu 3. Once a source like Intercom is selected, click the **Redirect** button to connect your workspace. Your platform will need access to retrieve articles from the external source 4. Choose the Intercom knowledge base as your data source 5. Click on the **Connect** button 6. Grant Moveo access to retrieve your articles by authorizing its access 7. Choose the specific articles you want your AI Agent to be able to answer :::note For non-professional accounts, you need to **publish** your Intercom articles to have them appear in Moveo. ::: ## Zendesk To establish a connection with Zendesk, follow these steps: 1. Click the **Add** button 2. Select your desired source from the "Select source" dropdown menu 3. Fill in your Zendesk subdomain and press **Enter** to load the languages of this knowledge base 4. Select language from the dropdown menu to load all available articles 5. Choose the specific articles you want your AI Agent to be able to answer 6. Click the **Add** button to add the selected articles to your knowledge base. ## Next steps - [Publish content](./publish.md) - Make your imported articles available to live agents - [Test your knowledge base](./test.md) - Verify your agent answers correctly - [Best practices](./best-practices.md) - Optimize your knowledge base content --- ## Knowledge base through Q&A A Q&A (Question & Answer) section allows you to address common inquiries and provide helpful information to your users. ## Create a Q&A 1. Navigate to **Knowledge** in the top navigation bar. 2. Click on the knowledge base you want to add a Q&A to, or create a new knowledge base as described in the [Knowledge bases overview](overview.md). 3. Access the **Q&A** section. 4. Click on the **Add** button to toggle the **Add Q&A** sidebar. 5. Type the full question and answer. 6. Click the **Add** button to save your Q&A. ## Edit a Q&A 1. Locate the Q&A you wish to edit and click the three dots icon. 2. Select **Edit** from the dropdown menu to open the editing interface. 3. Update the question and/or answer fields with your desired changes. 4. Click the **Update** button to save your modifications. ## Upload a Q&A 1. Access the **Q&A** section. 2. Click on the **Upload** button to toggle the **Upload Q&A** sidebar. 3. Upload your `.csv` file using the **accepted format**. If you need a template, click **Download CSV example** to get a file with the correct format. Once the file is uploaded, your Q&As will be processed and added to your knowledge base. ## Tips for effective Q&As Follow these guidelines to create Q&As that produce accurate AI responses: - **Use natural question phrasing** - Write questions the way customers actually ask them - **Include question variations** - Add common alternative phrasings as separate Q&As - **Keep answers focused** - Address one topic per Q&A entry - **Add context when needed** - Include relevant background information in the answer - **Avoid jargon** - Use clear, customer-friendly language ## Delete a Q&A 1. Locate the Q&A you want to delete and click the three dots icon. 2. Select **Delete** from the dropdown menu. 3. Confirm the deletion when prompted. ## Next steps - [Publish content](./publish.md) - Make your Q&As available to live agents - [Test your knowledge base](./test.md) - Verify your agent answers correctly - [Best practices](./best-practices.md) - Optimize your knowledge base content --- ## Knowledge base '@site/src/components/Arcade'; A knowledge base is a powerful tool that allows you to curate and manage documents from multiple sources, such as web pages, file uploads, and external knowledge bases. Use knowledge bases to enhance your [AI Agent](../ai-agents/overview.md), ensuring it delivers accurate and reliable responses to user queries. :::important A single knowledge base can be used by **multiple** AI Agents. ::: ## How do knowledge bases work? For every user message (request), Moveo first attempts to generate a response based on its AI Agent configuration. If the AI Agent returns **unknown**, Moveo then searches within knowledge bases for relevant answers. It classifies the most relevant articles related to the user's query, identifies the specific sections containing the answer, and generates a response using its Generative AI / LLM capabilities. ## Creating a knowledge base To create a knowledge base: 1. Navigate to **Knowledge** in the top navigation bar. 2. Click the **+ Create** button. 3. Enter a **name** for your new knowledge base and select its **language**. 4. Click the **Create** button. Your new knowledge base now appears in the Knowledge base list. ## Connecting a knowledge base Connect a knowledge base to your AI agent using one of the following methods: ### From knowledge base details To access the **Additional Info** sidebar for a knowledge base, click the **"Info" icon** (usually found below the header). This sidebar is where you'll connect AI Agents to your knowledge base. To connect AI Agents, use the **select dropdown** menu within this sidebar. ### AI Agent Knowledge It is also possible to connect a knowledge base to an AI Agent from the AI Agent's **Knowledge** tab. To do this, check this [guide](../ai-agents/knowledge.md#connect-a-knowledge-base). ## Fragments Fragments are small chunks of text, typically around 400 words, extracted from the provided content. These segments enable the AI to efficiently analyze and interact with the information. Each fragment consists of approximately 400 words. For reference, 2,500 fragments correspond to roughly 250–300 pages of content. ## Adding live instructions Enhance AI Agent responses by dynamically providing real-time user data through the `live_instructions` [context variable](../ai-agents/context.md). This allows the AI to incorporate live details, such as transaction history, user preferences, or other relevant information. One way to achieve this is by creating a webhook that fetches the necessary user data from your system and formats it into live instructions. You can then connect this webhook to your AI Agent. See this [guide](../ai-agents/build-a-webhook.md#use-case-live-instructions) for more information. ## Guidelines and best practices For optimal performance, follow our [best practices guide](./best-practices.md). --- ## Publish Content created from Q&As, Documents, Webpages, and External Sources is initially assigned a **Draft** status. This means the content is not yet utilized by live [AI Agents](../ai-agents/overview.md), but can be thoroughly tested using the **Test knowledge base** feature. ## Why use draft status? Draft status allows you to: - **Test before going live** - Verify content works correctly with your AI Agent - **Review for accuracy** - Ensure information is correct and up-to-date - **Stage updates** - Prepare new content without affecting production - **Collaborate safely** - Multiple team members can add content without impacting users ## Publish content To change the status from **Draft** to **Published** and enable the content for live AI Agent use: 1. Click the **Publish** button to open the publishing modal. 2. Within the modal, select the datasource you want to publish. 3. Press the **Publish** button to finalize the process. ## Bulk publishing Publish multiple datasources at once by selecting all the datasources in the modal before clicking **Publish**. :::tip Always test your content before publishing. Use the [Test knowledge base](./test.md) feature to verify your AI Agent responds correctly. ::: ## Next steps - [Test your knowledge base](./test.md) - Verify content before publishing - [Best practices](./best-practices.md) - Optimize your content for better results - [Knowledge base overview](./overview.md) - Learn more about knowledge base features --- ## Test knowledge base Testing your knowledge base ensures your AI Agent provides accurate responses before publishing content to production. ## Run a test 1. Click on the **Test** button to open the testing interface. 2. Select an AI Agent from the dropdown menu. 3. Enter your message in the text box. 4. Click the send icon to begin the conversation. ## Understanding test results The right panel provides tabs to help you analyze the test: | Tab | What it shows | |-----|---------------| | **Details** | The source documents used to generate the response | | **Context** | Variables and context data available during the conversation | | **Conversation** | Full conversation history and message details | ## What to look for When evaluating test results, check for: - **Correct information** - Does the response match your knowledge base content? - **Source accuracy** - Is the AI pulling from the right documents? - **Complete answers** - Are all parts of the question addressed? - **Natural language** - Does the response sound conversational? ## Troubleshooting poor results If your AI Agent provides incorrect or incomplete answers: 1. **Check content quality** - Review the source document for clarity 2. **Add more context** - Include background information in your content 3. **Reduce ambiguity** - Ensure similar topics don't overlap confusingly 4. **Test variations** - Try different phrasings of the same question ## Next steps - [Publish content](./publish.md) - Make tested content available to live agents - [Best practices](./best-practices.md) - Improve your content quality - [Knowledge base overview](./overview.md) - Learn more about knowledge base features --- ## Knowledge base through webpages The webpages data source allows you to gather and store content from various webpages. Your AI Agent uses this collected information to answer customer questions effectively. ## Configuration Below are the parameters you can use to configure the ingestion process: ### Full website This knowledge base starts with a seed URL. Seed URLs are the starting points for your crawl. They act as the base addresses from which the crawler begins exploring links. The crawler visits only those URLs that match the seed URLs or belong to their subdirectories. For example, if the seed URL is `https://example.com/`, the crawler explores that page and all its linked subpages such as `https://example.com/blog/`, `https://example.com/about-us/`, etc. #### Excluded URLs Excluded URLs are those you want the crawler to ignore. You can specify them using the same format as **seed URLs**. The crawler does not visit any URLs that match the excluded URLs or belong to their subdirectories. For example, if you exclude `https://example.com/blog/`, neither that page nor any pages under the blog directory will be visited. ### Single URLs Single URLs are pages you want the crawler to visit **without** following any links from them. ### Sitemap URLs [Sitemap](https://developers.google.com/search/docs/crawling-indexing/sitemaps/overview) URLs enable the crawler to fetch a list of pages to visit. For example, `https://example.com/sitemap.xml` can be used to locate multiple URLs for ingestion. ### Excluded assets The crawler ignores certain assets such as images, CSS, JavaScript files, and PDFs. Below is the complete list of ignored file types: - PNG - JPG - JPEG - GIF - PDF - CSS - JS :::note Moveo crawls webpages every 24 hours. So you might not see the changes you make immediately. ::: ## Add a webpage 1. Navigate to **Knowledge** in the top navigation bar. 2. Select the knowledge base you want to add a webpage to, or create a new knowledge base as described in the [Knowledge bases overview](overview.md). 3. Navigate to the **Webpages** tab. 4. Click the **Add** button to toggle the **Add Webpage** sidebar. 5. Select which method of ingestion you want to use. 6. Type the full URL of the webpage you want to add. ## Ingestion report The Ingestion Report provides details on the results of your webpage's data ingestion. By clicking on it, you can see how your site was ingested, the time it took, and any issues encountered (for example, problematic URL fields). ## Troubleshooting ### CDN or WAF blocking the crawler If your website is protected by a CDN or WAF (Web Application Firewall) such as Cloudflare, Akamai, or AWS CloudFront, the Moveo crawler may be blocked from accessing your pages. To resolve this, allowlist the Moveo crawler's IP addresses in your security settings. **Moveo crawler IP addresses** depend on the region your account is hosted in. See [Outbound IP addresses](../platform/outbound-ip-addresses) for the full list, then allowlist the addresses for your account's region (or all of them if you are unsure). 1. Log in to your [Cloudflare dashboard](https://dash.cloudflare.com/). 2. Select your domain. 3. Go to **Security** → **WAF** → **Tools**. 4. Under **IP Access Rules**, add the Moveo crawler IP addresses for your region with the action set to **Allow**. 1. Log in to the [Akamai Control Center](https://control.akamai.com/). 2. Navigate to **Security** → **IP/Geo Firewall** (or your WAF configuration). 3. Add the Moveo crawler IP addresses for your region to your allowlist. 4. If using **Bot Manager**, create an exception rule for these IPs under **Transactional Endpoints** or **Custom Bot Categories**. 1. Open the [AWS WAF console](https://console.aws.amazon.com/wafv2/). 2. Create or edit an **IP set** with the Moveo crawler IP addresses for your region. 3. Add a **Rule** to your Web ACL that matches the IP set and sets the action to **Allow**. 4. Ensure this rule has a higher priority than any blocking rules. If you use a different WAF or CDN provider (Imperva, Fastly, etc.), add the Moveo crawler IP addresses for your region to your allowlist or create an equivalent bypass rule. ## Frequently asked questions 1. **What file types are excluded during ingestion?** The crawler ignores files with extensions PNG, JPG, JPEG, GIF, PDF, CSS, and JS. 2. **Can I force the crawler to follow links from Single URLs?** No. Single URLs are crawled in isolation; the crawler does not follow any further links from them. 3. **Is there a way to view the status of my crawl?** Yes. Open the Ingestion Report, which outlines the process duration, URL issues, and any potential errors. 4. **How can I block the crawler from certain sections of my site?** You can list the paths or pages to be excluded under **Excluded URLs**. The crawler will ignore any URLs or subdirectories specified there. 5. **Can I use a sitemap for just one part of my webpage?** Absolutely. Point the crawler to any sitemap URL relevant to the sections you want to crawl. 6. **How do I resolve issues with my CDN or WAF blocking the crawler?** Allowlist the Moveo crawler IP addresses in your CDN or WAF settings. See the [Troubleshooting](#cdn-or-waf-blocking-the-crawler) section above for step-by-step instructions. 7. **What happens if a URL is both in Seed URLs and Excluded URLs?** Excluded URLs take precedence. Any URL listed in Excluded URLs (or its subdirectories) will not be crawled. 8. **How can I integrate this with a site protected by login credentials?** At the moment, Moveo's crawler does not support authentication. You must provide publicly accessible URLs to be crawled. 9. **Does Moveo process JavaScript on my webpage?** Currently, the crawler focuses on static HTML content. If your webpage relies heavily on JavaScript for rendering, consider providing static versions of critical content for more complete indexing. --- ## Account ## Set up your account To create an account on Moveo, follow these steps: 1. **Sign up** at the [Moveo Console](https://console.moveo.ai). 2. Enter your company email address or log in using your Google credentials. 3. If you sign up with an email, a verification link will be sent to your inbox. Click on it without closing the original tab. 4. In the new tab, enter the verification code provided by Moveo. 5. Complete the introductory guide. 6. Start using your new account. :::tip Explore the pre-built templates available in the Moveo Console to familiarize yourself with the platform. ::: ## Account ID The Account ID is the unique identifier of your account within Moveo. Knowing this ID is essential for integrating your account with other services such as [Zapier](./plugins/zapier.md). You can find your Account ID by: 1. Click your avatar in the top-right corner 2. Select **Profile**. 3. In the left sidebar, at the top, navigate to **Account Settings → Information**. 4. On the botton, copy the `account_id`. ## Expired Account When your trial or plan has expired, the following message will appear at the top of your Moveo console. If you wish to extend your trial period, send an email to the **support team** explaining the reason for the extension along with the account ID. You can find the account ID by going to the settings of your account, then clicking on `information`. --- ## API Keys ## What is an API Key? An API Key is a unique identifier used to authenticate an application or user when calling an API. It is a secret token required to access certain functionalities within our system, such as fetching analytics data, sending messages, or managing resources. ## Types When creating an API Key, you can specify its access scope by selecting one of the following types: - **Analytics**: Provides access to fetch analytics data for custom use cases or integration with external tools like PowerBI. [See available queries](/api/analytics/api-overview) - **Use**: Grants permissions to [Sessions](https://api.moveo.ai/api/docs/public/#/Sessions), [Message](https://api.moveo.ai/api/docs/public/#/Message), and [Classify](https://api.moveo.ai/api/docs/public/#/Classify) endpoints. - **Manage**: Allows creation, modification, and deletion of resources such as AI Agents, broadcasts, knowledge bases, datasources, desks, and more. [View API Documentation](https://api.moveo.ai/api/docs/public) ## Key Management and Security For security reasons, the API Key is **only visible once** upon creation. Ensure you copy and store it securely. If you lose it, you'll need to generate a new key. ## Permissions API Keys are managed under the account settings and are accessible exclusively to: - **Admins** - **Owners** ## How to create an API Key 1. Go to **Deploy → Developer Tools → API Keys**. 2. In the card on the right side, set a name to identify the use you will give to the key. 3. Select the type of key you want to create. 4. Click **Create**. :::warning The API Key will only be displayed once. Make sure to copy it and store it securely. ::: --- ## Billing This section describes the billing procedure for the Moveo AI services and is meant for account owners. In the **Billing** page of your account, you can perform essential actions: - Choose your plan. - Add or update your payment method(s). - Adjust billing details, including your tax region, billing address, company name, invoice recipient, and language preference. Moveo's [pricing plans](https://moveo.ai/pricing) offer a number of free conversations with the AI Agent. Once you exceed this limit, a modest additional monthly fee per conversation comes into play. It's important to note that this fee only applies to [meaningful conversations](../analytics/overview.md#meaningful-conversations). For a complete record of your financial transactions, the **Invoices** page of your account has you covered. It's your go-to place for tracking your billing history with Moveo AI. --- ## Desktop notifications '@site/src/components/Arcade'; In this guide, we show how to allow desktop notifications when you receive a new message. In this guide we show how to allow desktop notifications when you receive a new message. 1. Go to the top right of your screen to navigate to your profile. 2. Go to **Personal Settings > Notifications** and then enable the `Desktop Notifications` 3. Make sure you allow your browser to send notifications to your system. - For **Windows**: Navigate to **Settings → System → Notifications & actions** and select **Allow browser notifications**. - For **macOS**: Navigate to **System Preferences → Notifications**, pick your browser and select **Allow notifications**. ### Troubleshooting Ensure that you have whitelisted Moveo.AI in your browser settings to receive desktop notifications. 1. **Google Chrome**: Navigate to **Settings → Privacy and Security → Permissions → Notifications** and make sure Moveo is allowed to send notifications. 2. **Safari**: Navigate to **Safari → Preferences → Websites → Notifications** and make sure Moveo is allowed to send notifications. 3. **Firefox**: Navigate to **Settings → Privacy and Security → Permissions → Notifications** and make sure Moveo is allowed to send notifications. --- ## Event notifications Event notifications are a type of webhook that listens for events occurring in a conversation. You can use them to trigger actions in external systems based on these events. For example, event notifications can be used to add a customer ID to a CRM system or to send a notification to a Slack channel when a conversation is escalated to a human agent. ## How do they work? Event notifications function similarly to regular [webhooks](../ai-agents/webhooks.md). You define a URL where Moveo sends event notifications using a **POST** request and configure the specific events that trigger them. :::important Unlike regular webhooks, which are triggered when a dialog action is reached, event notifications are triggered when a specific event occurs during a conversation. ::: ## Events Event notifications are triggered when a specific event occurs during a conversation. You can get this information from the `event_type` field in the payload. It also can be found in `X-Moveo-Event` header of the request. This can be useful if you want to trigger different actions based on the event type without having to parse the payload. | Event | Triggered when | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | | `dialog:expired` | [Inactivity timeout's](../ai-agents/advanced.md#inactivity-timeout) time has passed from the last user message | | | A dialog has not been resolved, and the session has expired. | :::note Currently, `dialog:expired` is the only event that can be used to trigger event notifications. More events will be added in the future. ::: ## Request Payload While regular webhooks operate at the conversation level, event notifications work at the account level. This means that the payload sent to the webhook includes information about the account and the event that triggered the notification. The structure of the payload is similar to the [webhook payload](../ai-agents/webhooks.md#payload-reference), but it is wrapped within an object containing `account_id` and `event_type` information. Below is an example: ```json { "account_id": "b8a3e9eb-b0ba-4185-850c-fd449cbc2008", "event_type": "dialog:expired", "request_id": "6ca38741-f0ce-43d2-9ba6-99894ed18208", "timestamp": 1742304407801, "events": [ { "session": { "context": { "global": { "client_url": "" }, "user": { "browser": "Chrome 134.0.0.0", "display_name": "Visitor 412", "language": "en", "locales": ["en-gb", "en-us", "en"], "location": { "city": "Athens", "country": "GR", "latitude": 37.9842, "longitude": 23.7353 }, "platform": "Mac OS 10.15.7", "timezone": "Europe/Athens", "user_id": "HD22bzXMumP_KOalmrLvD", "verified": false } }, "history": [ { "author_id": "HD22bzXMumP_KOalmrLvD", "author_type": "user", "responses": [ { "action_id": "b1ce6303-08fc-4d0c-9e99-640d969e9b30", "text": "defaultstartmessage", "type": "text" } ], "timestamp": 1742304104215 }, { "author_id": "537c6e04-b69e-4658-b97f-2ca95aef91d2", "author_type": "brain", "intent_used": "greeting", "responses": [ { "action_id": "a8c628bb-752a-4e80-b741-a75a37702bed", "text": "Hello! 😳\nPlease tell me who you are?", "type": "text" } ], "timestamp": 1742304106737 } ], "is_conversation": true, "is_handover": false, "session_id": "916bac5e-8325-4860-8a41-cfa818b260e3", "source": { "channel": "web", "desk_id": "6634f5d1-e0ce-4ead-8e06-8d8f7972e90d", "integration_id": "1d093558-bac1-4954-acdd-c8d8dc05fa30", "is_test": true } }, "timestamp": 1742304407521 } ] } ``` ## Response handling Since event notifications serve as notifications rather than requests for data, the webhook should not return any specific response payload. Instead, it must return a `2xx` status code to acknowledge the receipt of the notification. ## Troubleshooting ### Handling duplicate events Webhook endpoints might occasionally receive duplicate events. To prevent processing duplicates, use the `X-Request-Id` header, which contains a unique UUID for each request (e.g., `"X-Request-Id": "a636fbdc-e257-4859-90dc-ead9dd999f12"`). :::important Although the request ID is also provided in the payload (`request_id`) and the `X-Moveo-Request-Id` header, these are used internally by Moveo and are not guaranteed to be unique per webhook request. Therefore, it's advisable to rely on the `X-Request-Id` header. ::: ### Timeout and retries Your server should respond with a 2XX response within 5 seconds of receiving a webhook event. If your server takes longer than that to respond, the webhook service retries up to 5 times. After that, it terminates the connection and considers the notification a failure. --- ## Members management Collaborate with colleagues across multiple accounts in Moveo. This guide helps you invite new members to your account, and locate and accept invitations to other accounts. ## Inviting new members 1. Click on your profile icon in the top-right corner of the screen to access your profile settings. 2. Navigate to **Manage Access**. 3. Click on the **Invite** button. 4. Enter the email address of the person you want to invite and select their roles. Not sure which role to assign? See [Roles and permissions](./permissions.md) for a description of what each role can do. 5. Click on the **Invite** button to send the invitation. ## Viewing and accepting invitations 1. Click on your profile icon in the top-right corner of the screen to access your profile settings. 2. Navigate to **Personal Settings → Invitations** to view all the accounts you have been invited to. Here, you can also see the role assigned to you in each account. [Learn more about permissions.](./permissions.md) 3. Once you accept an invitation, click on your profile icon again to view the list of accounts you are a member of, and select the newly added account. --- ## Language Models ## Introduction Language models offer a straightforward way to integrate pre-trained Large Language Models (LLMs) from external providers with your Moveo AI agents. This feature enables users to connect with popular LLM providers, allowing enhanced customization and flexibility. ## Available providers Moveo supports integration with the following LLM providers: - **OpenAI** - **Azure OpenAI** - **Anthropic** - **Gemini** Each provider has unique configuration requirements. Follow the steps below to set up a language model for each provider. ## Connect a language model To connect a language model: 1. Navigate to the **Language Models** page. 2. Select the desired provider by clicking the **Configure** button on its tile. This opens a configuration modal. 3. Enter the required details as prompted: - **OpenAI, Anthropic, and Gemini** require an API key and model selection. - **Azure OpenAI** requires an API key, model, deployment ID, and instance name. ### Example: connect OpenAI 1. Click **Configure** under the OpenAI tile. 2. In the modal, enter your OpenAI **API Key**. 3. Select the preferred model from the dropdown. 4. Click **Test & Connect** to confirm the connection. ## Manage connected models Once configured, connected models are displayed in the **Connected Models** section. Here, you can view details such as: - **Provider** (e.g., OpenAI) - **Model** (e.g., gpt-4) - **Creator** (user who configured the model) - **Last Used** (date of last usage) To manage or disconnect a model, use the options menu (⋮) on the model card. ## Connect a model to an AI agent Once a model is connected, you can use it in your AI Agent as part of its model strategy. See the [Model strategy](../ai-agents/model-strategy.md) guide to configure which models power your AI Agent on each channel. ## Security and best practices - API keys are sensitive information. Store them securely and limit access to authorized personnel only. - Ensure each model is connected using the proper API key with appropriate permissions for its intended use. --- ## Outbound IP Addresses ## Introduction When Moveo makes outbound calls to your systems — [agent webhooks](../ai-agents/webhooks) POSTing to your backend, or the [knowledge-base crawler](../knowledge-base/website) fetching your website — the traffic leaves our infrastructure through a small, stable set of public NAT IP addresses. If your backend, CDN, or Web Application Firewall (WAF) restricts inbound traffic by source IP, add these addresses to your allowlist so Moveo's requests are not blocked. :::note IP allowlisting is a **fallback, not a replacement** for [HMAC signature verification](../ai-agents/webhooks#authenticating-webhook-calls). It authenticates the network, not the request, and Moveo's egress IPs may change with infrastructure updates. Where possible, verify the `X-Moveo-Signature` and treat an IP allowlist as an additional layer. ::: ## Which addresses apply to your account Moveo runs in several regions. **Your account is hosted in one region, and all of its outbound traffic originates from that region's addresses.** Allowlist the row that matches your account's region. If you are not sure which region your account is in, allowlist every address below, or ask your Moveo contact. | Region | Cloud / Region | Outbound IP addresses | | ---------------------- | ------------------------ | -------------------------------------------------- | | Europe | AWS `eu-central-1` | `18.192.167.150`, `18.198.233.220`, `3.66.239.254` | | United States | GCP `us-central1` | `34.135.131.192` | | Brazil / South America | GCP `southamerica-east1` | `34.39.187.109` | The Europe region uses three addresses — one NAT gateway per availability zone for redundancy. Any of the three may appear as the source of a given request. :::note Dedicated deployments Single-tenant or dedicated deployments use separate addresses that are provided during onboarding. The table above covers Moveo's shared multi-tenant regions only. ::: ## What uses these addresses - **Webhooks** — every [agent webhook](../ai-agents/webhooks) (dialog, first message, pre message, post message, and authentication webhooks) is sent from the outbound addresses of the region your account is hosted in. - **Knowledge-base crawler** — when Moveo [indexes your website](../knowledge-base/website) for the knowledge base, the crawler requests your pages from the same region's addresses. --- ## Developer Tools The Developer Tools section provides essential tools for integrating and extending the Moveo platform. Use these tools to connect external systems, customize AI behavior, and automate workflows. ## Available tools ### API keys [API keys](./api-keys.md) authenticate your applications when calling Moveo APIs. Create and manage keys to: - Connect external applications to Moveo - Access the GraphQL and REST APIs ### Language models [Language models](./language-models.md) power your AI Agents' responses. Configure models to: - Choose your preferred LLM provider (Moveo, OpenAI, Anthropic) - Select specific model versions ### Event notifications [Event notifications](./event-notifications.md) send real-time updates to your systems. Use them to: - Trigger actions when conversations reach certain states - Sync conversation data with CRM systems - Send alerts to team communication channels ## Getting started 1. **Create an API key** - Generate credentials for your integration 2. **Configure your language model** - Choose the AI model for your agents 3. **Set up event notifications** - Connect external systems to receive updates ## Next steps - [API documentation](/api/analytics/api-overview) - Explore the full API reference - [Webhooks](../ai-agents/webhooks.md) - Send data from dialogs to external systems - [Integrations](../integrations/overview.md) - Connect messaging channels --- ## Roles and permissions Moveo.AI uses Role-Based Access Control (RBAC) to manage what each member can see and do inside an account. Instead of granting permissions one by one, you assign one or more **roles** to a member, and each role bundles a set of permissions for a specific job function. A member can hold multiple roles at once; their effective access is the **union** of every role assigned directly to them and to the teams they belong to. Manage members, roles, and teams from the **Manage access** page in the account settings. ## Permission matrix The table below shows which permissions each default role grants. Use it as the reference when picking a role for a new member. | Permission | Owner | Billing | Admin | Chat Manager | Chat Agent | Builder | | ------------------------------------------------------------------------- | ----- | ------- | ----- | ------------ | ---------- | ------- | | [Create, edit AI Agents](../ai-agents/overview.md) | ✓ | - | ✓ | - | - | ✓ | | [Create AI Agent versions](../ai-agents/versions.md) | ✓ | - | ✓ | - | - | ✓ | | [View AI Agent logs](../analytics/logs.md) | ✓ | - | ✓ | - | - | ✓ | | [Create, edit rules](../environments/rules.md) | ✓ | - | ✓ | - | - | - | | [Create, edit integrations](../integrations/overview.md) | ✓ | - | ✓ | - | - | - | | [Create, edit context bundles](../environments/context-bundles.md) | ✓ | - | ✓ | - | - | - | | [Create, edit business hours](../environments/business-hours.md) | ✓ | - | ✓ | ✓ | - | - | | [Reply to users](../chat/overview.md) | ✓ | - | ✓ | ✓ | ✓ | - | | [Create, edit quick responses](../chat/quick-responses.md) | ✓ | - | ✓ | ✓ | ✓ | - | | [Create, edit campaigns](../campaigns/campaigns.md) | ✓ | - | ✓ | ✓ | ✓ | - | | [Create, edit knowledge bases](../knowledge-base/overview.md) | ✓ | - | ✓ | - | - | ✓ | | [Create, edit environments](../environments/overview.md) | ✓ | - | ✓ | ✓ | - | - | | [Access analytics](../analytics/overview.md) | ✓ | - | ✓ | ✓ | - | - | | Edit permissions | ✓ | - | ✓ | - | - | - | | [Create, edit teams](#teams) | ✓ | - | ✓ | - | - | - | | [View activity history](#activity-history) | ✓ | - | ✓ | - | - | - | | [Update account](./account.md) | ✓ | - | ✓ | - | - | - | | [Invite members](./invitations.md) | ✓ | - | ✓ | - | - | - | | [Access billing](./billing.md) | ✓ | ✓ | - | - | - | - | | [Create API keys](./api-keys.md) | ✓ | - | ✓ | - | - | - | To edit the role of each member, navigate to the **Manage access** page in the **Account settings**. ## Roles ### Owner The person who created the account. The Owner has unrestricted access and is the only role that can transfer ownership, delete the account, or assign the **Billing** role to other members. There is exactly one Owner per account, set at account creation and changed only through an explicit ownership transfer. :::note An owner can transfer ownership of the account to another member by clicking the **Transfer Ownership** option on the **Manage access** page. ::: ### Admin Trusted operator who runs the workspace day-to-day — configuring integrations, writing routing rules, inviting members, and managing roles and teams. Admins have full operational access; the only thing they cannot do is access billing. ### Builder Conversation designer or prompt engineer focused on the AI side of the platform. Builders create, test, and publish AI Agents and the knowledge bases that power them, but do not participate in the live-chat operation or account administration. ### Chat Manager Support team lead or operations manager who runs the live-chat operation. Chat Managers do everything a Chat Agent does, plus configure the queues, departments, business hours, SLAs, and environments that shape how conversations are routed. ### Chat Agent Front-line human agent who replies to customers. Chat Agents pick up conversations and use the productivity tools (notes, quick responses, views) set up by the Chat Manager, but cannot change how the operation is configured. ### Billing Finance team member or accountant who needs invoice access without seeing conversations or AI Agent configuration. The Billing role is limited to billing information — invoices, payment methods, and subscription details — and can only be assigned by the Owner. ## Teams Teams group members so you can assign roles to several people at once. Create a team from the **Manage access** menu where roles are assigned. You can add or remove members, edit team details, or delete the team entirely. A member's effective access is the **union** of the roles assigned directly to them and the roles assigned to every team they belong to. For example, a member with a **Chat Manager** individual role who also belongs to a team granted the **Builder** and **Chat Agent** roles has the combined permissions of all three. :::note You can edit the access of a member or a team from the **Manage access** menu, in the respective tab. ::: ## Invitations Invite new users to your account from the **Manage access** menu. Either manually select roles for the new member or add them to a specific team. See [Invite new members](./invitations.md) for the step-by-step flow and how invitees accept the invitation. ## Activity history View all the latest changes in your account in the **Activity history** menu. This menu displays detailed records of all changes users have made in [AI Agents](../ai-agents/overview.md) and [environments](../environments/overview.md). --- ## Create an event notification This tutorial walks you through creating an [**event notification**](../event-notifications.md) that triggers when a chatbot **conversation expires**. Using a **streaming platform's customer support** as an example use case, the event notification sends conversation details to an external webhook when a user session ends due to inactivity. ## Scenario Imagine a **streaming service** where users chat with a support bot to resolve issues. If a conversation remains inactive for too long, it expires. When this happens, the conversation details (including user ID, session history, and metadata) go to a **CRM system** for follow-up with the user. Only conversations that include the `context.tags` field with a value of `success` are processed, ignoring incomplete or unresolved interactions. ## Step 1: Handling the event notification Your external system needs to process incoming webhook requests when a conversation expires. Below is a **Node.js Express** server that listens for event notifications, filtering out unresolved conversations and only processing those marked as successful. ```javascript const express = require("express"); const bodyParser = require("body-parser"); const crypto = require("crypto"); const app = express(); const port = process.env.PORT || 3000; const SECRET = "mySuperSecretKey123!"; // Middleware to handle duplicate requests app.use((req, res, next) => { const reqId = req.headers["X-Request-Id"]; if (!shouldProcessRequest(reqId)) { console.log("Ignoring duplicate request"); return res.status(200).send("Ignored"); } next(); }); app.use(bodyParser.json()); app.post("/webhook/chat_expired", (req, res) => { const headers = req.headers; const body = req.body; console.log("Received chat expiration webhook:", body); // Validate HMAC signature const signature = headers["x-moveo-signature"]; const expectedSignature = calculateSignature(JSON.stringify(body), SECRET); if (signature !== expectedSignature) { console.error("Invalid signature!"); return res.status(401).send("Unauthorized"); } // Check if the conversation was successfully completed const conversationTags = body.events[0]?.session?.context?.tags || []; if (!conversationTags.includes("success")) { console.log("Ignoring incomplete or unresolved conversation."); return res.status(200).send("Ignored"); } console.log("Signature valid. Processing expired chat..."); console.log(`Account ID: ${body.account_id}`); console.log(`Event Type: ${body.event_type}`); res.status(200).send("Webhook received successfully"); }); function calculateSignature(body, secret) { const hmac = crypto.createHmac("sha256", secret); hmac.update(body); return hmac.digest("hex"); } app.listen(port, () => { console.log(`Server listening at http://localhost:${port}`); }); ``` ## Step 2: Navigate to event notifications 1. Go to **Deploy → Developer Tools → Event Notifications**. 2. Click **Create Event**. ## Step 3: Fill in the event notification details ### **1. Name** Give the event a recognizable name: > **Chat Expired - Notify CRM** ### **2. Event** Select the event that will trigger the notification. For this example, use the `dialog:expired` event. This event fires when a conversation remains inactive for a set [threshold](../../ai-agents/advanced.md#inactivity-timeout). ### **3. URL** Provide the webhook URL where the conversation data will be sent: > `https://api.crmplatform.com/webhook/chat_expired` ### **4. Secret** Set a secret key to sign the request body and validate incoming notifications: > `mySuperSecretKey123!` ### **5. SSL Verification** Enable SSL verification for secure communication. > ✅ **Enable SSL Verification** Click **Save** to create the event notification. ## Step 4: Updating or deleting an event notification - To **update** an event notification, go to **Deploy → Developer Tools → Event Notifications**, select the event, and modify the fields. - To **delete** an event notification, click **Delete** on the event in the list. Enable or disable the endpoint by clicking the toggle button on the event notification. This allows stopping events from being sent to the webhook URL without deleting it. ## Example Payload for `dialog:expired` Below is an example payload sent when a conversation expires. Notice that the `context.tags` array contains `success`, meaning the conversation was completed successfully. ```json { "account_id": "b8a3e9eb-b0ba-4185-850c-fd449cbc2008", "event_type": "dialog:expired", "events": [ { "session": { "context": { "user": { "display_name": "John Doe", "user_id": "123456789", "email": "john.doe@example.com" }, "tags": ["success"] }, "history": [ { "author_id": "123456789", "author_type": "user", "responses": [ { "text": "I need help with billing", "type": "text" } ], "timestamp": 1742304104215 }, { "author_id": "bot123", "author_type": "brain", "responses": [ { "text": "Sure! What seems to be the issue?", "type": "text" } ], "timestamp": 1742304106737 } ], "session_id": "916bac5e-8325-4860-8a41-cfa818b260e3", "source": { "channel": "web" } }, "timestamp": 1742304407521 } ], "request_id": "6ca38741-f0ce-43d2-9ba6-99894ed18208", "timestamp": 1742304407801 } ``` ## Conclusion By following this tutorial, you have successfully created an **event notification** that triggers when a chatbot conversation expires. This setup ensures that only successfully completed conversations are logged in an external system, enabling your support team to take meaningful action while ignoring incomplete interactions. --- ## Use Moveo with Zapier ## Overview Moveo can trigger external workflows in Zapier through its [event notifications](../event-notifications.md) feature. Using this capability, you can integrate Moveo with Zapier effortlessly, eliminating the need for custom integrations. ## How to connect Moveo with Zapier ### Requirements - A Zapier account. - A Moveo account. ### Step 1: Retrieve your account ID Zapier identifies your Moveo account using your account ID. As event notifications are account-level, you must [copy your account ID](../account.md#account-id) from the Moveo dashboard. ### Step 2: Create a [management API Key](../api-keys.md#how-to-create-an-api-key) The API key grants Zapier access to your Moveo account, enabling it to listen and respond to events. ### Step 3: Create a Zap in Zapier You must have a Zapier account. If you don't have one yet, create one [here](https://zapier.com/app/home). 1. Log in to your Zapier dashboard and click on the **Create a Zap** button. 2. In the trigger step, select **Moveo** as your app. 3. Under **Trigger event**, choose the specific event you wish to track from Moveo. 4. In the **Account** section, click on **Sign In**, then enter your previously copied Moveo account ID and API Key. 5. Click **Continue** to validate the connection. Zapier will perform a test request to ensure it's properly connected. 6. Once successfully connected, configure the action Zapier should perform when the event occurs. --- ## Security & Compliance Moveo maintains enterprise-grade security standards with SOC 2 Type II, ISO 27001, and HIPAA compliance. ## Trust Center Visit our [Trust Center](https://trust.moveo.ai) for: - Compliance certifications and reports - Security practices and policies - Data protection measures - Penetration test summaries ## Certifications - **SOC 2 Type II** - Security, availability, and confidentiality - **ISO 27001** - Information security management - **HIPAA** - Healthcare data compliance (BAA available) For compliance documentation or security questionnaires, contact [security@moveo.ai](mailto:security@moveo.ai). ## Next steps - [Single Sign-On](./sso.md) - Configure SSO for your organization - [Permissions](./permissions.md) - Set up role-based access control --- ## Single Sign-On (SSO) Single Sign-On (SSO) is an authentication scheme that allows a user to log in with a single set of credentials to multiple independent software systems. When correctly implemented, it provides a seamless user experience and robust security. ### Standard Authentication By default, our platform supports authentication via **Google** and **Microsoft** using the OAuth 2.0 protocol. This enables users to sign in using their existing Google or Microsoft accounts without the need to create or manage a separate password for our service. ### SSO Integration For organizations that require centralized user management, we offer a premium SSO integration feature. This allows you to connect our platform with your organization's Identity Provider (IdP), such as Microsoft Azure AD, Okta, or other SAML 2.0-based providers. #### How It Works Once SSO is configured for your workspace, any sign-in attempt from a user with an email domain associated with your organization will be redirected to your IdP. The user will authenticate using their corporate credentials, and upon successful authentication, they will be securely redirected back to our platform. To enable this feature, please send an email to [support@moveo.ai](mailto:support@moveo.ai?subject=SSO%20Enablement%20Request&body=Company%3A%20[Enter%20Company%20Name]%0AIT%20Manager%20Email%3A%20[Enter%20IT%20Manager's%20Email%20Address]%0AReason%3A%20SSO%20Enablement%20Request) including: - Company name - IT manager's email address The designated IT manager will receive an invitation to the SSO setup dashboard to begin the configuration process. ### Benefits of Centralized Access Management Integrating our platform with your IdP provides several key benefits for security and administration: - **Centralized User Management**: Administrators can manage access to our platform through your central user directory. This simplifies the process of provisioning and de-provisioning users as part of standard employee onboarding and offboarding procedures. - **Enhanced Security**: Enforce your organization's security policies, including multi-factor authentication (MFA) and password complexity requirements, managed directly from your IdP. - **Improved User Experience**: Users can access our platform using their familiar corporate credentials, eliminating the need to remember another password and reducing login friction. - **Simplified Auditing and Compliance**: Centralized authentication creates a single, auditable record of user access, which simplifies security reviews and compliance reporting. When an employee's access is revoked in your IdP, their access to our platform is immediately and automatically terminated. --- ## Taxes This section explains how taxes are calculated and applied to your Moveo.AI invoices. ## How taxes work Moveo.AI is required by law to apply taxes in certain countries and regions depending on your account's tax location. The applicable tax rates and types vary based on local regulations. If you are a registered business in certain locations, you can enter your VAT or GST ID to remove applicable taxes from your monthly bills. ## How is my tax location determined? Your tax location is typically based on your account address, which is initially set to the payment address of your primary payment method when you sign up. In some locations, we are required by law to consider other account details, such as: - Other payment addresses associated with your account - IP addresses used during account activity - Business registration details You can view and update your account address at any time from the **Billing** page in your account settings. :::tip If you've set your account address correctly but your tax location doesn't match what you expect, please [contact our support team](https://moveo.ai/contact) for assistance. ::: ## Tax types by region Different regions have different tax types and rates. Here are some common examples: | Region | Tax type | Description | |--------|----------|-------------| | European Union | VAT | Value Added Tax applied to digital services | | United Kingdom | VAT | 20% VAT on digital services | | United States | Sales Tax | Varies by state and locality | | Australia | GST | Goods and Services Tax | | Canada | GST/HST | Federal and provincial taxes | | Singapore | GST | Goods and Services Tax | :::important Tax rates and requirements change frequently as governments update their digital services taxation policies. Your actual tax rate will be calculated based on current regulations at the time of billing. ::: ## Managing your tax settings To update your tax information: 1. Go to **Account Settings → Billing**. 2. In the **Billing details** section, update your: - Tax region - Billing address - Company name (for business accounts) 3. If applicable, enter your VAT or GST registration number to claim tax exemption. ## Tax exemptions ### Business VAT/GST exemption If your business is registered for VAT, GST, or similar taxes in your region, you can enter your registration number in your billing settings. Once verified, applicable taxes will be removed from future invoices. To add your tax ID: 1. Navigate to **Account Settings → Billing**. 2. In the billing details section, locate the tax ID field. 3. Enter your VAT/GST registration number. 4. The system will validate your tax ID and update your tax status accordingly. ### Other exemptions Some organizations may qualify for tax exemptions based on their status (e.g., non-profit organizations, government entities). If you believe your organization qualifies for a tax exemption, please [contact our support team](https://moveo.ai/contact) with the relevant documentation. ## Viewing taxes on your invoices All applicable taxes are itemized on your invoices. To view your invoices: 1. Go to **Account Settings → Invoices**. 2. Select an invoice to view the detailed breakdown. 3. Tax amounts are shown as separate line items. ## Invoice currency All Moveo.AI invoices are issued in **USD (United States Dollars)**. Tax calculations are performed in USD regardless of your location. ## Frequently asked questions ### Why am I being charged tax? Moveo.AI is legally required to collect and remit taxes in many jurisdictions. The specific tax applied depends on your account's tax location and local regulations governing digital services. ### Can I get a refund for taxes paid? If you believe taxes were incorrectly applied to your account, please [contact our support team](https://moveo.ai/contact). We can review your account and issue corrections if applicable. ### How do I update my tax location? Update your billing address in **Account Settings → Billing**. Your tax location will be recalculated based on the new address. ### Why doesn't my VAT/GST number work? VAT and GST numbers must be valid and active with the relevant tax authority. Ensure you're entering the correct format for your region. If you continue to experience issues, contact our support team. --- ## Not receiving emails If you're not receiving emails from Moveo (such as notifications, reports, or password resets), follow the steps below to diagnose and resolve the issue. ## Check your spam folder Emails from Moveo may be filtered into your spam or junk folder. Search for emails from `@moveo.ai` in your spam folder and mark them as "not spam" to ensure future delivery. ## Verify your email address Confirm that the email address in your Moveo account settings is correct. A typo in your email address will prevent delivery. 1. Go to **Settings** → **Account** 2. Verify your email address is spelled correctly 3. Update if necessary and save changes ## Check if you unsubscribed You may have accidentally unsubscribed from Moveo emails. All emails from Moveo contain an unsubscribe link in the footer: If you clicked this link, you were removed from all Moveo mailing lists. To resubscribe, contact support at [support@moveo.ai](mailto:support@moveo.ai). ## Corporate email filters If you use a corporate email system, your IT department may have filters that block external emails. Ask your IT team to: - Allowlist the domain `moveo.ai` - Check quarantine for blocked messages - Verify DMARC/SPF settings aren't rejecting Moveo emails ## Still not receiving emails? If none of the above solutions work, contact [support@moveo.ai](mailto:support@moveo.ai) with: - Your account email address - The type of email you're expecting (notification, report, password reset) - When you last received emails from Moveo --- ## Next steps - [Troubleshooting overview](./overview.md) - Other common issues - [Platform status](./platform-status.md) - Check for ongoing issues - [Account settings](../platform/account.md) - Manage your account --- ## Troubleshooting overview This guide helps you diagnose and resolve common issues with the Moveo platform. ## Quick diagnostic steps Before diving into specific issues, try these general steps: 1. **Check platform status** - Visit the [status page](./platform-status.md) for ongoing incidents 2. **Clear browser cache** - Many UI issues resolve after clearing cache and refreshing 3. **Try incognito mode** - Rules out browser extension conflicts 4. **Verify permissions** - Ensure your account has the necessary [permissions](../platform/permissions.md) 5. **Check integration settings** - Confirm your [integration](../integrations/overview.md) is active --- ## AI Agent issues ### Agent not responding to messages
Symptoms and solutions **Check these common causes:** - **Agent not published** - Verify the agent is [published](../ai-agents/versions.md) in the active environment - **Rules not configured** - Check that [rules](../environments/rules.md) route conversations to the agent - **Environment mismatch** - Ensure the integration is connected to the correct [environment](../environments/overview.md) - **Knowledge base empty** - The agent needs content in its [knowledge base](../knowledge-base/overview.md) to respond
### Agent giving incorrect answers
Symptoms and solutions **Improve response accuracy:** - **Update knowledge base** - Ensure your [knowledge base](../knowledge-base/overview.md) contains accurate, up-to-date information - **Refine guidelines** - Add clearer [guidelines](../ai-agents/knowledge.md#guidelines-prompting) to shape responses - **Check for conflicts** - Multiple knowledge sources with conflicting information can cause issues - **Test thoroughly** - Use the [test feature](../ai-agents/test.md) to validate responses before publishing
### Agent responding slowly
Symptoms and solutions **Potential causes:** - **Large knowledge base** - Very large knowledge bases may take longer to search - **Complex guidelines** - Overly complex instructions can slow response generation - **Network latency** - Check your connection and the [platform status](./platform-status.md) - **Peak usage** - Response times may vary during high-traffic periods
--- ## Integration issues ### Messages not being received
Symptoms and solutions **Check these settings:** - **Integration status** - Verify the integration is set to **Active** in Moveo - **Webhook configuration** - Ensure webhooks are properly configured in the external platform - **Credentials** - API keys and tokens may have expired; regenerate if needed - **Domain/IP allowlists** - Some platforms require Moveo's domains to be allowlisted
### Messages not being sent
Symptoms and solutions **Troubleshoot outbound messages:** - **Check platform limits** - External platforms may have rate limits or sending restrictions - **Verify account status** - Your account on the external platform may be suspended or limited - **Review message content** - Some platforms block messages with certain content patterns - **Check integration logs** - Review [analytics logs](../analytics/logs.md) for error details
--- ## Live chat issues ### Messages not appearing in inbox
Symptoms and solutions **Verify these settings:** - **Integration connected** - Confirm the [integration](../integrations/overview.md) is properly connected - **Business hours** - Check if [business hours](../environments/business-hours.md) are restricting availability - **Department routing** - Verify [department](../chat/departments.md) assignments are correct - **Agent availability** - Ensure human agents are online and assigned to the department
### Handover to human not working
Symptoms and solutions **Check handover configuration:** - **Handover action configured** - Verify the [handover action](../ai-agents/operations/handover.md) is set up in your dialog - **Human agents available** - At least one human agent must be online - **Department exists** - The target department must exist and have agents assigned - **Business hours active** - Handover may be restricted outside business hours
--- ## Account and access issues ### Cannot log in
Symptoms and solutions **Try these steps:** - **Check credentials** - Verify you're using the correct email and password - **Reset password** - Use the "Forgot password" link on the login page - **Check SSO** - If your organization uses [SSO](../platform/sso.md), use that login method - **Contact admin** - Your account may have been deactivated; contact your account administrator
### Missing features or permissions
Symptoms and solutions **Permission-related issues:** - **Check your role** - Your [role and permissions](../platform/permissions.md) determine what you can access - **Contact admin** - Request additional permissions from your account administrator - **Plan limitations** - Some features may not be available on your current plan
--- ## Email issues For email-related problems, see [Not receiving emails](./not-receiving-emails.md). --- ## Get support If you can't resolve your issue using this guide: 1. **Check platform status** - Visit [status.moveo.ai](https://status.moveo.ai) for ongoing incidents 2. **Search documentation** - Use the search bar to find relevant guides 3. **Contact support** - Email [support@moveo.ai](mailto:support@moveo.ai) When contacting support, include: - A screenshot or screen recording of the issue - Steps to reproduce the problem - Your account email and environment name - Any error messages you see - When the issue started occurring --- ## Next steps - [Platform status](./platform-status.md) - Check for ongoing incidents - [Not receiving emails](./not-receiving-emails.md) - Email delivery problems - [AI Agents](../ai-agents/overview.md) - Agent configuration - [Integrations](../integrations/overview.md) - Channel setup --- ## Platform status The Moveo status page provides real-time information about platform availability, ongoing incidents, and scheduled maintenance. ## Check current status Visit [status.moveo.ai](https://status.moveo.ai) for the latest platform status: