# Authentication
Source: https://docs.visitoai.com/api-docs/authentication
Create M2M credentials, assign scopes, and authenticate server-side Visito API requests.
Visito's developer API uses machine-to-machine credentials. Each key belongs to one tenant and includes explicit scopes that control what the integration can do.
M2M credentials are secrets. Store them only in server-side environment variables or a secrets manager. Never ship them in frontend, mobile, or embedded widget code.
## Create an API Key
1. Open the Visito dashboard.
2. Go to **Build → API Keys**.
3. Click **Create new API Key**.
4. Choose a clear name, such as `PMS booking sync` or `CRM automation`.
5. Select only the scopes required by your integration.
6. Copy the key immediately and store it securely.
## Authorization Header
Send the credential as a bearer token:
```http theme={null}
Authorization: Bearer visito_m2m_...
```
## Scopes
Scopes are additive. A request succeeds only when the key has the scope required by that endpoint.
| Scope | Allows |
| -------------------------- | ------------------------------------------------ |
| `channels:read` | List tenant channels and channel identifiers. |
| `conversations:read` | List conversations and read conversation detail. |
| `conversations:write` | Send replies into existing conversations. |
| `tools:read` | List and inspect custom AI tools. |
| `tools:write` | Create, update, and delete custom AI tools. |
| `tools:execute` | Test custom AI tool execution. |
| `tools:logs:read` | Read custom AI tool execution logs. |
| `whatsapp_templates:read` | List WhatsApp templates for a channel. |
| `whatsapp_templates:write` | Create WhatsApp templates for Meta review. |
| `whatsapp_templates:send` | Send approved WhatsApp templates. |
## Example
```bash theme={null}
curl https://platform-api.visitoai.com/m2m/v1/channels \
-H "Authorization: Bearer $VISITO_M2M_API_KEY" \
-H "Accept: application/json"
```
## Idempotency
Send endpoints require an `Idempotency-Key` header. Use a stable value from your system, such as a booking ID, payment ID, or CRM workflow run ID.
```http theme={null}
Idempotency-Key: booking-confirmation-2423265220870
```
If your request is retried with the same key, Visito returns the original queued operation instead of creating a duplicate send.
## Status Codes
| Status | Meaning |
| ------ | ------------------------------------------------------------------------------- |
| `200` | Read request succeeded. |
| `201` | Resource was created. |
| `202` | Outbound work was accepted and queued. |
| `400` | Request body, query, or required header is invalid. |
| `401` | Authorization header is missing or invalid. |
| `403` | Credential is valid but missing the required scope. |
| `404` | Tenant-owned resource was not found. |
| `409` | The requested action conflicts with the current conversation or resource state. |
| `429` | A send safety limit was reached. |
| `502` | Visito could not queue or complete provider-facing work. |
| `503` | A required Visito dependency is temporarily unavailable. |
## Retry Policy
* Retry `GET` requests after transient `429`, `502`, or `503` responses using exponential backoff and jitter.
* Retry reply or template send requests only with the exact same body and the exact same `Idempotency-Key`.
* Do not retry `400`, `401`, `403`, `404`, or `409` automatically.
* If a `429` response includes `error.details.retryAfterSeconds`, wait at least that long.
Use a new idempotency key when the intended recipient, template, conversation, or message content changes.
# Custom AI Tools
Source: https://docs.visitoai.com/api-docs/conversational-ai-api
Register backend actions that Visito's AI can call during conversations.
Custom tools let Visito call your backend when the AI needs live business data or needs to trigger an approved action. Common examples include looking up an order status, creating a support ticket, checking loyalty points, or updating a customer profile.
All endpoints use the M2M base URL:
```bash theme={null}
https://platform-api.visitoai.com/m2m/v1
```
## Tool Model
A tool describes what the AI can call, the JSON input it should provide, and the HTTP endpoint Visito will invoke.
```json theme={null}
{
"name": "get_order_status",
"description": "Look up the latest status for a customer order.",
"parameters": {
"type": "object",
"required": ["order_number"],
"properties": {
"order_number": {
"type": "string",
"description": "The customer's order number, for example A-1003."
}
}
},
"endpoint": {
"url": "https://example.com/visito/tools/get-order-status",
"method": "POST",
"timeoutMs": 10000
},
"auth": {
"type": "bearer",
"value": "tool_backend_secret"
},
"active": true,
"readOnly": true,
"allowInPlayground": true,
"propertyIds": []
}
```
`parameters` should be a JSON Schema object. Visito uses it to decide when the tool is relevant and to shape the input sent to your endpoint.
## What Visito Sends to Your Endpoint
For a `GET` tool, Visito converts tool arguments into query parameters. Primitive values are sent as strings; objects and arrays are JSON-encoded.
```http theme={null}
GET /visito/tools/get-order-status?order_number=A-1003
Accept: application/json
```
For a `POST` tool, Visito sends the arguments together with conversation metadata:
```json theme={null}
{
"arguments": {
"order_number": "A-1003"
},
"meta": {
"tenantId": "tenant_123",
"conversationKey": "tenant_123:whatsapp:525512345678:phone_number_id",
"conversationId": "conv_123",
"channel": "whatsapp",
"eventId": "toolreq_123"
}
}
```
Your endpoint should return a JSON object with only the fields the assistant needs. Non-object JSON responses are normalized into an object before the result is returned to the assistant.
Configured authentication is added by Visito:
* `bearer` sends `Authorization: Bearer `.
* `api_key` sends the configured secret in `auth.headerName`.
* Stored secrets are redacted from invocation logs and are never returned by the API.
## Create a Tool
```http theme={null}
POST /m2m/v1/tools HTTP/1.1
Host: platform-api.visitoai.com
Authorization: Bearer visito_m2m_...
Content-Type: application/json
```
Requires the `tools:write` scope.
```json theme={null}
{
"name": "get_order_status",
"description": "Look up the latest status for a customer order.",
"parameters": {
"type": "object",
"required": ["order_number"],
"properties": {
"order_number": {
"type": "string",
"description": "The customer's order number."
}
}
},
"endpoint": {
"url": "https://example.com/visito/tools/get-order-status",
"method": "POST"
},
"auth": {
"type": "api_key",
"headerName": "X-Tool-Key",
"value": "secret_value"
},
"active": true,
"readOnly": true
}
```
```json theme={null}
{
"tool": {
"toolId": "tool_...",
"tenantId": "tenant_...",
"name": "get_order_status",
"description": "Look up the latest status for a customer order.",
"parameters": {},
"endpoint": {
"url": "https://example.com/visito/tools/get-order-status",
"method": "POST"
},
"auth": {
"type": "api_key",
"headerName": "X-Tool-Key",
"secretLastFour": "alue",
"configured": true
},
"active": true,
"readOnly": true,
"allowInPlayground": true,
"propertyIds": [],
"createdAt": "2026-07-12T00:00:00.000Z",
"updatedAt": "2026-07-12T00:00:00.000Z"
}
}
```
Secrets are not returned after creation. Responses only include whether auth is configured and the last four characters when available.
### Create and Update Rules
* `name` must start with a letter or underscore, contain only letters, numbers, and underscores, and be at most `64` characters.
* `description` is required and can be at most `2000` characters.
* `parameters` must be a JSON Schema object. Visito sets `type: "object"` and `additionalProperties: false` when they are omitted.
* `endpoint.url` must be an HTTP or HTTPS URL.
* `endpoint.method` must be `GET` or `POST`.
* `endpoint.timeoutMs`, when provided, must be an integer from `500` to `30000`.
* `auth.type` must be `none`, `bearer`, or `api_key`.
* `allowInPlayground` defaults to `false`.
* Omitting `auth.value` during a patch preserves the existing secret. Setting `auth.type` to `none` removes it.
## List and Read Tools
```http theme={null}
GET /m2m/v1/tools HTTP/1.1
Authorization: Bearer visito_m2m_...
```
Requires `tools:read`.
```json theme={null}
{
"tools": [
{
"toolId": "tool_...",
"name": "get_order_status",
"active": true,
"readOnly": true
}
]
}
```
Read one tool:
```http theme={null}
GET /m2m/v1/tools/{toolId}
```
## Update or Delete a Tool
Update one or more fields:
```http theme={null}
PATCH /m2m/v1/tools/{toolId}
Authorization: Bearer visito_m2m_...
Content-Type: application/json
```
Requires `tools:write`.
```json theme={null}
{
"active": false,
"endpoint": {
"timeoutMs": 15000
}
}
```
Delete a tool:
```http theme={null}
DELETE /m2m/v1/tools/{toolId}
Authorization: Bearer visito_m2m_...
```
```json theme={null}
{
"ok": true,
"toolId": "tool_...",
"changed": true
}
```
## Test a Tool
Use the test endpoint before enabling a tool in production conversations.
```http theme={null}
POST /m2m/v1/tools/{toolId}/test HTTP/1.1
Authorization: Bearer visito_m2m_...
Content-Type: application/json
```
Requires `tools:execute`.
```json theme={null}
{
"input": {
"order_number": "A-1003"
}
}
```
```json theme={null}
{
"ok": true,
"output": {
"order_number": "A-1003",
"status": "delivered",
"estimated_delivery": "2026-07-10",
"tracking_url": "https://example.com/orders/A-1003"
},
"durationMs": 248
}
```
## Execution Logs
Use logs to audit AI tool calls and diagnose backend failures.
```http theme={null}
GET /m2m/v1/tools/logs?toolId=tool_...&limit=25
Authorization: Bearer visito_m2m_...
```
Requires `tools:logs:read`.
```json theme={null}
{
"logs": [
{
"logId": "log_...",
"toolId": "tool_...",
"toolName": "get_order_status",
"conversationId": "conv_...",
"status": "completed",
"method": "POST",
"url": "https://example.com/visito/tools/get-order-status",
"responseStatus": 200,
"durationMs": 248,
"startedAt": "2026-07-12T00:00:00.000Z",
"completedAt": "2026-07-12T00:00:00.248Z"
}
]
}
```
Read one log:
```http theme={null}
GET /m2m/v1/tools/logs/{logId}
```
## Endpoint Requirements
* Your endpoint must be reachable from Visito's backend.
* Supported methods are `GET` and `POST`.
* Return JSON whenever possible.
* Return a `2xx` response for success. A non-`2xx` response is recorded as `custom_tool_http_error`.
* Keep tool responses concise and structured for AI use.
* Use `readOnly: true` for lookup tools that should never mutate state.
* Use tool-specific auth secrets instead of broad internal credentials.
* Make mutating endpoints idempotent using a business identifier from `arguments` or `meta.eventId`.
* Do not rely on the assistant to hide sensitive fields returned by your endpoint; omit secrets and unnecessary personal data from the response.
## Production Checklist
1. Create the tool with `active: false`.
2. Test representative success, validation, timeout, and upstream-failure cases.
3. Confirm request headers are redacted in **Build → Tool calls → Logs**.
4. Keep the response small and stable so the assistant can interpret it reliably.
5. Set `readOnly: false` for mutations and require your own authorization and idempotency checks.
6. Enable the tool, then review invocation logs after the first real conversations.
# Developer Guide
Source: https://docs.visitoai.com/api-docs/introduction
Build server-side automations, integrations, and AI workflows with the Visito M2M API.
The Visito Developer Guide is for teams building server-side integrations on top of Visito: CRMs, PMS systems, internal tools, AI agents, reporting jobs, and operational automations.
Visito exposes a machine-to-machine API for backend systems. Use it to read connected channels, inspect conversations, send operator-style replies, manage custom AI tools, and send approved WhatsApp templates.
## Base URL
```bash theme={null}
https://platform-api.visitoai.com/m2m/v1
```
All requests must be made from your backend. Do not call the M2M API from browser or mobile client code.
## Machine-Readable API Definition
Use the [OpenAPI definition](/openapi.json) as the source for generated clients, runtime validators, and AI coding assistants. The specification covers the current `/m2m/v1` endpoints, required scopes, parameters, request bodies, response shapes, and structured errors.
Do not infer endpoints from older examples or client code. If an endpoint is not in the current OpenAPI definition or this Developer Guide, treat it as unavailable.
## What You Can Build
Pull recent conversations, inspect message history, and send replies from your own operations system.
Create, list, and send approved WhatsApp templates through connected Visito channels.
Register backend actions that Visito's AI can call during conversations.
Give Codex, Claude Code, or another assistant the exact API patterns for safe integrations.
## Core Concepts
* **Tenant**: The business account your M2M credential belongs to.
* **Channel**: A connected WhatsApp, Instagram, Messenger, or Web Chat destination.
* **Conversation**: A thread between an external user and a Visito tenant.
* **M2M credential**: A server-side API key with explicit scopes.
* **Idempotency-Key**: A required header for send operations so retries do not duplicate work.
## Request Pattern
```http theme={null}
GET /m2m/v1/channels HTTP/1.1
Host: platform-api.visitoai.com
Authorization: Bearer visito_m2m_...
Accept: application/json
```
Write operations that create outbound work also require an idempotency key:
```http theme={null}
Idempotency-Key: booking-confirmation-123
```
## Response Model
Outbound sends are asynchronous. When you send a reply or WhatsApp template, Visito returns `202 Accepted` with a queued response. Delivery status is processed by Visito's dispatcher and reflected in conversation history.
```json theme={null}
{
"accepted": true,
"conversationId": "conv_...",
"replyId": "reply_...",
"status": "queued"
}
```
`202 Accepted` means the request was stored and queued. It does not mean the channel provider delivered the message. Store the returned `replyId`, `requestEventId`, and `correlationId`, then read the conversation again to reconcile the message status.
## Error Shape
Errors use structured codes and human-readable messages.
```json theme={null}
{
"error": {
"code": "M2M_AUTH_INSUFFICIENT_SCOPE",
"message": "M2M credential does not have required scope.",
"details": {
"requiredScopes": ["conversations:write"],
"missingScopes": ["conversations:write"]
}
}
}
```
`error.details` is optional. When present, use it for structured recovery information such as missing scopes or `retryAfterSeconds`.
## Recommended First Steps
Generate a credential from the Visito dashboard with only the scopes your integration needs.
Call `GET /m2m/v1/channels` and store the `channelId` for the WhatsApp or Meta channel you want to use.
Use `GET /m2m/v1/conversations` to sync a working set into your CRM or backend.
Use `Idempotency-Key` on every send request and store the returned `replyId` for reconciliation.
# AI Coding Assistants
Source: https://docs.visitoai.com/api-docs/llms/introduction
Give Codex, Claude Code, or another assistant the right context for Visito M2M integrations.
Use this page as copy-paste context when asking an AI coding assistant to build against Visito's M2M API.
## Give the Assistant Authoritative Context
Provide these sources with the implementation request:
1. The [OpenAPI definition](/openapi.json) for machine-readable routes and schemas.
2. [Authentication](/api-docs/authentication) for scopes, idempotency, status codes, and retry behavior.
3. The workflow guide for [conversations](/api-docs/messaging-api), [custom tools](/api-docs/conversational-ai-api), or [WhatsApp templates](/api-docs/messaging-api-templates).
Tell the assistant not to invent endpoints, fields, webhooks, or pagination parameters that are absent from those sources.
## Integration Context
```text theme={null}
You are integrating with the Visito M2M API.
Base URL: https://platform-api.visitoai.com/m2m/v1
Authentication: Authorization: Bearer $VISITO_M2M_TOKEN
Token location: server-side environment variable only
Machine-readable contract: use the current Visito openapi.json
Important rules:
- Never expose the M2M token in browser or mobile client code.
- Use only the scopes required for the integration.
- Send operations are asynchronous and return 202 Accepted with status "queued".
- Include Idempotency-Key on outbound send requests.
- Treat structured error codes as stable programmatic signals.
- Retry a send only with the same request body and the same Idempotency-Key.
- Do not invent routes or fields that are absent from the API contract.
```
## Endpoint Summary
```text theme={null}
Channels:
- GET /channels
Conversations:
- GET /conversations
- GET /conversations/{conversationId}
- GET /conversations/{conversationId}/messages
- POST /conversations/{conversationId}/reply
WhatsApp templates:
- GET /whatsapp-templates/{channelId}
- POST /whatsapp-templates/{channelId}
- POST /whatsapp-templates/{channelId}/send
Custom AI tools:
- GET /tools
- POST /tools
- GET /tools/{toolId}
- PATCH /tools/{toolId}
- DELETE /tools/{toolId}
- POST /tools/{toolId}/test
- GET /tools/logs
- GET /tools/logs/{logId}
```
## Scope Map
| Operation | Required scope |
| -------------------------------------- | -------------------------- |
| List channels | `channels:read` |
| List or read conversations | `conversations:read` |
| Send a conversation reply | `conversations:write` |
| List or read custom tools | `tools:read` |
| Create, update, or delete custom tools | `tools:write` |
| Test a custom tool | `tools:execute` |
| Read custom tool invocation logs | `tools:logs:read` |
| List WhatsApp templates | `whatsapp_templates:read` |
| Create a WhatsApp template | `whatsapp_templates:write` |
| Send a WhatsApp template | `whatsapp_templates:send` |
## Contracts Assistants Commonly Miss
* `GET /conversations` returns the current first live window. M2M v1 does not currently accept a continuation cursor on this endpoint.
* `GET /conversations/{conversationId}` returns metadata only. Treat `conversation.needsReply` as the authoritative operator-action signal.
* `GET /conversations/{conversationId}/messages` returns the newest-first external transcript and supports `limit` plus an opaque `cursor` for older messages.
* M2M v1 has no media-upload endpoint. Do not generate a media upload workflow.
* Reply and template send responses are queued acknowledgements, not delivery confirmations.
* Correlate a queued `requestEventId` with `messages[].eventId` from the messages endpoint.
* A free-form reply can return `409 REPLY_WINDOW_CLOSED`; use an approved WhatsApp template when applicable.
* A template rate-limit response can include `error.details.retryAfterSeconds`.
* `error.details` is optional and can contain missing scopes or recovery metadata.
## Retry and Reconciliation Rules
```text theme={null}
GET requests:
- Retry 429, 502, and 503 with exponential backoff and jitter.
POST send requests:
- On timeout or transient failure, retry only with the identical body and identical Idempotency-Key.
- Never create a new idempotency key merely because the first response was lost.
After 202 Accepted:
- Persist conversationId, replyId, requestEventId, correlationId, and Idempotency-Key.
- Read the conversation messages endpoint and match requestEventId to messages[].eventId.
- Treat queued as pending; do not report it as delivered.
Do not automatically retry:
- 400, 401, 403, 404, or 409
```
## Codex Prompt
```text theme={null}
Build a TypeScript backend client for Visito's M2M API.
Base URL: https://platform-api.visitoai.com/m2m/v1
Auth header: Authorization: Bearer process.env.VISITO_M2M_TOKEN
Implement:
1. listChannels(): GET /channels
2. listConversations(params): GET /conversations
3. getConversation(conversationId): GET /conversations/{conversationId}
4. listConversationMessages(conversationId, params):
GET /conversations/{conversationId}/messages
5. sendReply(conversationId, body, idempotencyKey):
POST /conversations/{conversationId}/reply
6. listWhatsappTemplates(channelId): GET /whatsapp-templates/{channelId}
7. sendWhatsappTemplate(channelId, body, idempotencyKey):
POST /whatsapp-templates/{channelId}/send
Requirements:
- keep token server-side only
- require Idempotency-Key for sendReply and sendWhatsappTemplate
- parse JSON error responses with error.code and error.message
- preserve optional error.details
- retry GET requests on 429, 502, and 503 with exponential backoff and jitter
- retry a send only with the identical body and identical Idempotency-Key
- do not retry 400, 401, 403, or 404
- return typed queued responses for 202 sends
- persist replyId, requestEventId, and correlationId for reconciliation
- do not add endpoints or fields not present in the supplied OpenAPI definition
```
## CRM Automation Prompt
```text theme={null}
Create a CRM sync job using Visito's M2M API.
Flow:
1. GET /channels and find the WhatsApp channel to use.
2. GET /conversations?limit=50 to sync the current work queue.
3. GET /conversations/{conversationId} before acting on a conversation.
4. GET /conversations/{conversationId}/messages for the external transcript.
5. If a human-approved outbound template should be sent:
- GET /whatsapp-templates/{channelId}
- choose an APPROVED template by name and language
- POST /whatsapp-templates/{channelId}/send with Idempotency-Key
Output:
- typed API client
- durable idempotency key strategy
- execution log with conversationId, replyId, requestEventId, status, and error code
- unit tests for success, 429 retry, insufficient scope, and duplicate idempotency replay
```
## Custom Tools Prompt
```text theme={null}
Register a Visito custom AI tool for my backend.
Tool:
- name: check_availability
- description: Check available rooms for a date range and guest count.
- method: POST
- endpoint URL: https://example.com/visito/tools/check-availability
- auth: X-Tool-Key header from process.env.VISITO_TOOL_KEY
- parameters: JSON Schema with checkIn, checkOut, and guests
Use:
- POST /tools to create the tool
- POST /tools/{toolId}/test to verify it
- GET /tools/logs?toolId={toolId} for diagnostics
Requirements:
- do not log secrets
- validate tool input before calling Visito
- return concise JSON from my backend endpoint
- include tests for the generated route handler
```
## Safety Checklist
* Store `VISITO_M2M_TOKEN` in server-side secret storage.
* Do not paste production tokens into assistant prompts.
* Give the integration only the scopes it needs.
* Use deterministic idempotency keys for replies and template sends.
* Check template status before sending; only `APPROVED` templates can be sent.
* Log Visito `error.code`, `conversationId`, `replyId`, and `requestEventId` for support.
* Require human approval before an assistant-generated workflow sends proactive templates or enables a mutating custom tool.
# Channels and Conversations
Source: https://docs.visitoai.com/api-docs/messaging-api
Read tenant channels, sync conversations, and send replies through the Visito M2M API.
Use the M2M messaging endpoints to connect Visito with your CRM, helpdesk, analytics pipeline, or internal operations backend.
## List Channels
Use channels to discover the connected accounts your integration can work with.
```http theme={null}
GET /m2m/v1/channels
```
Required scope:
```text theme={null}
channels:read
```
Example response:
```json theme={null}
{
"channels": [
{
"id": "68505cb92a11ea971d9df8bf",
"tenantId": "tenant_123",
"type": "whatsapp",
"provider": "meta",
"name": "+52 55 1234 5678",
"active": true,
"respondEnabled": true,
"identifiers": {
"phoneNumberId": "1234567890",
"phoneNumber": "+52 55 1234 5678",
"wabaId": "987654321"
}
}
]
}
```
Store the channel `id` when you need to send WhatsApp templates from a specific number.
## List Conversations
```http theme={null}
GET /m2m/v1/conversations
```
Required scope:
```text theme={null}
conversations:read
```
Common query parameters:
| Parameter | Values | Default |
| -------------- | -------------------------------------- | ------- |
| `limit` | `1` to `200` | `50` |
| `view` | `all`, `needs_reply`, `handoff` | `all` |
| `replyState` | `all`, `failed` | `all` |
| `policyStatus` | `all`, `active`, `archived`, `blocked` | `all` |
| `responseMode` | `all`, `ai`, `manual`, `frozen` | `all` |
Example:
```bash theme={null}
curl "https://platform-api.visitoai.com/m2m/v1/conversations?view=needs_reply&limit=25" \
-H "Authorization: Bearer $VISITO_M2M_API_KEY"
```
The endpoint returns the current live window:
```json theme={null}
{
"conversations": [
{
"conversationId": "conv_123",
"channel": "whatsapp",
"participant": {
"id": "525512345678",
"displayName": "Sofia"
},
"needsReply": true,
"lastMessageAt": "2026-07-12T18:15:00.000Z",
"lastMessageText": "Can I check in early?",
"lastMessageRole": "user",
"latestReplyStatus": "sent",
"responseMode": "ai",
"messageCount": 8
}
],
"needsReplyCount": 1,
"handoffCount": 0,
"hasMore": false,
"asOf": "2026-07-12T18:15:02.000Z",
"version": 42,
"liveWindow": {
"limit": 25,
"maxRows": 200,
"mode": "first_page_realtime"
}
}
```
M2M v1 currently exposes the first live conversation window. Even if a response contains `nextCursor`, the list endpoint does not currently accept a continuation cursor. Use filters and a limit up to `200` to define the working set your integration needs.
## Get Conversation Detail
```http theme={null}
GET /m2m/v1/conversations/{conversationId}
```
Required scope:
```text theme={null}
conversations:read
```
Use this endpoint before sending a reply so your integration has the latest conversation context.
Example response:
```json theme={null}
{
"conversation": {
"conversationId": "conv_123",
"channel": "whatsapp",
"participant": {
"id": "525512345678",
"displayName": "Sofia"
},
"needsReply": false,
"lastMessageAt": "2026-07-12T18:20:00.000Z",
"lastMessageText": "Hi Sofia, early check-in is available.",
"lastMessageRole": "assistant",
"latestReplyStatus": "sent",
"messageCount": 9
}
}
```
`conversation.needsReply` is the authoritative signal that operator action is required. `lastMessageRole` describes chronology only; do not use it as a substitute for `needsReply`.
## List Conversation Messages
```http theme={null}
GET /m2m/v1/conversations/{conversationId}/messages?limit=50&cursor=...
```
The endpoint returns only the external transcript: inbound user messages and outbound assistant or operator messages. Internal system and tool activity is excluded before pagination.
Messages are ordered newest first. Treat `cursor` as opaque and pass `nextCursor` unchanged to retrieve older messages. `hasMore=true` means older external messages remain; `nextCursor` is `null` when `hasMore=false`.
Example response:
```json theme={null}
{
"conversationId": "conv_123",
"messages": [
{
"messageId": "message_123",
"eventId": "evt_123",
"direction": "outbound",
"role": "assistant",
"text": "Hi Sofia, early check-in is available.",
"createdAt": "2026-07-12T18:20:00.000Z",
"status": "sent",
"author": {
"type": "operator",
"operatorName": "CRM automation",
"displayName": "CRM automation"
},
"media": []
}
],
"nextCursor": null,
"hasMore": false
}
```
Use `messages[].eventId` to correlate a queued `requestEventId`. Delivery information can appear in `messages[].status`, `messages[].statusReason`, and `messages[].deliveries`.
`status` is always one of `received`, `queued`, `sent`, `delivered`, `read`, `failed`, `blocked`, `partial_sent`, or `unknown`. A dispatcher publish failure is normalized to `failed`.
Message direction describes chronology only. Use `conversation.needsReply`, not the latest message direction, to decide whether operator action is required.
## Send a Reply
```http theme={null}
POST /m2m/v1/conversations/{conversationId}/reply
```
Required scope:
```text theme={null}
conversations:write
```
Required headers:
```http theme={null}
Authorization: Bearer visito_m2m_...
Idempotency-Key: crm-reply-123
Content-Type: application/json
```
Request body:
```json theme={null}
{
"text": "Hi Sofia, your reservation has been updated.",
"replyToExternalMessageId": "wamid.optional-reference"
}
```
You can send text, media, or both:
```json theme={null}
{
"text": "Here is the updated receipt.",
"mediaId": "media_123"
}
```
M2M v1 does not currently expose a media-upload endpoint. `mediaId` can only reference a media asset that already exists for the conversation. For a standalone M2M integration, use text replies unless your workflow already has a valid Visito media ID.
Successful response:
```json theme={null}
{
"accepted": true,
"replyId": "reply_123",
"conversationId": "conv_123",
"requestEventId": "evt_123",
"correlationId": "corr_123",
"status": "queued",
"acceptedAt": "2026-07-12T18:20:00.000Z"
}
```
Replies are queued asynchronously. Delivery results are reconciled into Visito conversation history after the channel dispatcher sends the message.
## Reconcile an Outbound Reply
1. Persist the `conversationId`, `replyId`, `requestEventId`, `correlationId`, and `Idempotency-Key` from the `202` response.
2. Read `GET /m2m/v1/conversations/{conversationId}/messages`.
3. Match `requestEventId` to `messages[].eventId`.
4. Treat `queued` as pending, `sent` as handed to the provider, and `failed` or `blocked` as unsuccessful.
5. If the original send request times out, retry the exact same body with the same idempotency key before deciding to create new outbound work.
Free-form replies can return `409 REPLY_WINDOW_CLOSED`. For WhatsApp, use an approved template to reopen the conversation instead of retrying the reply.
## When To Use WhatsApp Templates
WhatsApp and Instagram have provider rules around free-form messages. For WhatsApp conversations outside the customer service window, use an approved WhatsApp template instead of a free-form reply.
Continue with [WhatsApp Templates](/api-docs/messaging-api-templates) to create, list, and send templates.
# WhatsApp Templates
Source: https://docs.visitoai.com/api-docs/messaging-api-templates
Create, list, and send approved WhatsApp templates through connected Visito channels.
Use the WhatsApp Templates API for proactive messages that must use Meta-approved templates: booking confirmations, check-in instructions, payment reminders, door codes, and other transactional workflows.
All endpoints use the M2M base URL:
```bash theme={null}
https://platform-api.visitoai.com/m2m/v1
```
## Requirements
* A connected, active WhatsApp channel using the Meta provider.
* The channel must have Meta `wabaId`, `phoneNumberId`, and access token details configured in Visito.
* An M2M credential with the template scopes you need.
* `Idempotency-Key` on template send requests.
Use `GET /m2m/v1/channels` to find the `channelId` for the WhatsApp number you want to send from.
## List Templates
```http theme={null}
GET /m2m/v1/whatsapp-templates/{channelId} HTTP/1.1
Host: platform-api.visitoai.com
Authorization: Bearer visito_m2m_...
Accept: application/json
```
Requires the `whatsapp_templates:read` scope.
```json theme={null}
{
"templates": [
{
"id": "1234567890",
"name": "reservation_confirmed",
"status": "APPROVED",
"language": "en_US",
"category": "UTILITY",
"components": [
{
"type": "BODY",
"text": "Hi {{1}}, your reservation is confirmed."
}
]
}
]
}
```
## Create a Template
```http theme={null}
POST /m2m/v1/whatsapp-templates/{channelId} HTTP/1.1
Host: platform-api.visitoai.com
Authorization: Bearer visito_m2m_...
Content-Type: application/json
```
Requires `whatsapp_templates:write`.
`template.name` must use lowercase letters, numbers, and underscores. `template.category` must be `UTILITY`, `MARKETING`, or `AUTHENTICATION`.
```json theme={null}
{
"template": {
"name": "reservation_confirmed",
"language": "en_US",
"category": "UTILITY",
"components": [
{
"type": "BODY",
"text": "Hi {{1}}, your reservation is confirmed.",
"example": {
"body_text": [["Sofia"]]
}
}
]
}
}
```
```json theme={null}
{
"template": {
"id": "1234567890",
"name": "reservation_confirmed",
"status": "PENDING",
"language": "en_US",
"category": "UTILITY",
"components": [
{
"type": "BODY",
"text": "Hi {{1}}, your reservation is confirmed."
}
]
}
}
```
Templates must be approved by Meta before they can be sent.
## Send a Template
```http theme={null}
POST /m2m/v1/whatsapp-templates/{channelId}/send HTTP/1.1
Host: platform-api.visitoai.com
Authorization: Bearer visito_m2m_...
Idempotency-Key: booking-123-confirmation
Content-Type: application/json
```
Requires `whatsapp_templates:send`.
```json theme={null}
{
"to": "+525512345678",
"template": {
"name": "reservation_confirmed",
"language": {
"code": "en_US"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Sofia"
}
]
}
]
}
}
```
If accepted, Visito queues the send and returns `202 Accepted`.
```json theme={null}
{
"accepted": true,
"conversationId": "conv_...",
"conversationKey": "tenant_...:whatsapp:525512345678:phone_number_id",
"replyId": "reply_...",
"requestEventId": "event_...",
"correlationId": "corr_...",
"status": "queued",
"acceptedAt": "2026-07-12T00:00:00.000Z"
}
```
Template sends are asynchronous. The API response confirms Visito accepted and queued the outbound work; it does not return the raw Meta send response.
## Send Rules
* The template must exist for the requested language.
* The template status must be `APPROVED`.
* `REJECTED`, `PENDING`, or in-review templates cannot be sent.
* `to` can include formatting such as `+`, spaces, or punctuation; Visito normalizes it to WhatsApp digits.
* Reusing the same `Idempotency-Key` for the same recipient conversation returns the original accepted send instead of creating a duplicate.
* Each WhatsApp channel is limited to 100 template sends per rolling 24-hour window through this API. When the limit is reached, Visito returns `429` with retry details.
## Common Errors
| Code | Meaning |
| ------------------------------------------ | -------------------------------------------------------- |
| `WHATSAPP_TEMPLATES_CHANNEL_NOT_FOUND` | The channel does not belong to the authenticated tenant. |
| `WHATSAPP_TEMPLATES_UNSUPPORTED_CHANNEL` | The channel is not a WhatsApp Meta channel. |
| `WHATSAPP_TEMPLATES_CHANNEL_NOT_READY` | The channel is missing Meta connection details. |
| `WHATSAPP_TEMPLATES_TEMPLATE_NOT_FOUND` | No template exists with that name and language. |
| `WHATSAPP_TEMPLATES_TEMPLATE_NOT_APPROVED` | The template exists but is not approved by Meta. |
| `WHATSAPP_TEMPLATE_SEND_LIMIT_24H_REACHED` | The channel reached the 24-hour template send limit. |
Rate-limit responses include the wait time in seconds:
```json theme={null}
{
"error": {
"code": "WHATSAPP_TEMPLATE_SEND_LIMIT_24H_REACHED",
"message": "WhatsApp template send limit reached for this channel.",
"details": {
"retryAfterSeconds": 3600
}
}
}
```
Retry the exact same send body with the same `Idempotency-Key` after the wait period. A replay returns the identifiers from the original accepted operation.
# Delete your account
Source: https://docs.visitoai.com/delete-your-account
Do you want to delete your account?
Email [help@visitoai.com](mailto:help@visitoai.com) with your email details and the account name you want to delete.
# How to personalize your Visito AI guest agent
Source: https://docs.visitoai.com/product-guides/ai-agent/ai-behavior
Configure your Visito AI agent's timezone, tone, response length, emoji use, conversation scope, name, and custom instructions for hotel guests.
Open **Agent → Personalization** to control how the agent communicates.
## AI timezone
The AI timezone grounds relative dates, current time, booking conversations, and handoff working hours. Select **Edit** to change it.
## Base style
Choose a tone preset:
* Default
* Professional
* Friendly
* Candid
* Quirky
* Efficient
* Cynical
## Response preferences
* **Emoji** - allow or prevent emoji in assistant responses.
* **Message length** - Default, Short, or Long.
* **Conversation scope** - Business only for strict property topics, or General + business for broader conversation while keeping business facts grounded.
* **Assistant name** - no personal name or a custom identity.
## Custom instructions
Use custom instructions for stable behavior that does not belong in factual knowledge, such as:
* Preferred greeting or sign-off
* Brand wording
* Topics to avoid
* How to format recommendations
* When to ask clarifying questions
Select **Save** after making changes.
Custom Instructions complement Visito's built-in agent behavior. They do not replace the complete internal system prompt.
### Starter example
```text theme={null}
Use short paragraphs and plain language.
Ask only one follow-up question at a time.
Never invent prices, availability, policies, or reservation details.
When an answer depends on the property and the property is unclear, ask which property the guest means.
Clearly distinguish a request from a confirmed arrangement.
```
Keep factual values such as hours, fees, and policies in the Knowledge Base so your team can update them independently.
Do not place passwords, API keys, or other secrets in custom instructions.
Test important changes in Playground with a new chat before relying on them in customer channels.
Use copy-ready patterns, avoid conflicting rules, and test each behavior.
# How to configure AI-to-human handoffs in Visito
Source: https://docs.visitoai.com/product-guides/ai-agent/ai-escalations
Create Visito AI escalation rules, set working hours and required fields, and route urgent or complex hotel guest requests to a human operator.
Open **Agent → Handoff Rules** to control human escalation behavior.
## What a handoff changes
A handoff tells Visito that a person must take over a guest request. When a rule creates one:
* The conversation appears in Home and the **Handoff** Conversations view.
* Visito records the reason, captured details, missing fields, and time of the request.
* AI replies pause while the handoff is unresolved.
* New guest messages stay in the thread and keep it marked for attention.
* A teammate can reply manually, assign an owner, and record the final outcome.
A manual reply does not resolve the handoff automatically. The operator must explicitly select **Resolve handoff** after handling the request.
## Master switch
Use **Enable automatic handoff rules** to turn policy-driven handoffs on or off for the active workspace.
When it is off, scenario rules remain visible but cannot trigger. This switch does not disable operator-created internal reviews.
## Escalation scenarios
Each scenario includes:
* Name and description
* Enabled state
* Global or selected-property scope
* Required fields to capture
* Optional severity and priority settings
Select **Add scenario** to create a custom rule. Select an existing row to edit it.
Required fields can include reservation ID, guest name, email, phone, stay dates, booking reference, or a custom field.
### Example: explicit request for a person
```text theme={null}
Name: Guest requests a person
Trigger:
Create a handoff when the guest clearly asks to speak with a human, employee, manager, front desk, or support agent. Do not require the guest to explain the reason before creating the handoff.
Required fields:
- Guest name, if not already known
- Property, when the workspace has multiple properties
```
Test a similar non-trigger such as “Who is the hotel manager?” to confirm the rule does not interrupt a normal informational question.
## Working hours
Open the **Working hours** tab to tell the AI when your team is available.
1. Turn on **Use working hours in handoff responses**.
2. Mark each day open or closed.
3. Enter the start and end time for open days.
4. Review **Response context preview**.
5. Select **Save working hours**.
Working hours use the AI timezone configured in Personalization.
## Resolve a handoff
Handoffs appear in Home and the **Handoff** Conversations view.
1. Open the thread and review the reason, guest messages, captured fields, and missing fields.
2. Assign a conversation owner if one person should handle the request.
3. Complete the task and reply to the guest when needed.
4. Add an optional resolution note that records the outcome.
5. Select **Resolve handoff**.
Resolving closes the active handoff and clears the needs-reply state created by it. It does not archive the conversation.
## Handoff vs internal review
Choose based on whether the guest needs a person to take over:
| Workflow | Use it when | Guest impact | AI behavior |
| ------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------- |
| **Handoff** | A person must handle the guest's request | The guest can receive a handoff acknowledgment and a manual operator reply | AI replies pause until the handoff is resolved |
| **Internal review** | A teammate needs to inspect the conversation for quality, policy, or coaching | No message or visible status is sent to the guest | AI behavior does not change |
Only one internal review can be open at a time, and it cannot be requested during an active handoff. If a new handoff occurs while a review is open, the handoff supersedes the review.
Test every custom scenario in Playground, including both inside and outside working hours.
Follow the operator workflow, assign responsibility, and choose between resolve, archive, and block.
Start with high-value scenarios, choose useful fields, and test false positives.
# How to manage AI-shareable hotel assets in Visito
Source: https://docs.visitoai.com/product-guides/ai-agent/assets
Upload approved hotel images and documents, organize them in folders, control property scope, and choose which assets the Visito AI may share.
Open **Agent → Assets** to manage customer-shareable media.
## Knowledge versus Assets
* **Knowledge Base** files are read as information for the AI.
* **Assets** are approved files the AI may send or link in a customer conversation.
Use Assets for menus, brochures, maps, room images, policies, and other collateral that should be shared directly.
## Upload an asset
1. Select **Upload asset**.
2. Choose a supported image or document.
3. Add the title and any required metadata.
4. Choose whether it applies to all properties or one property.
5. Save and wait for validation to complete.
## Folders
Select **New folder** to organize related assets. Use clear customer-facing names so operators can find the correct file quickly.
## Table fields
The Assets table shows:
* Title and file name
* Property scope
* Validation state
* Active status
* Last update
* Row actions
## Activate and scope
Turn an asset off to stop the AI from using it without deleting it. Change property scope when an asset should only be available for a specific property.
Use descriptive titles such as “Pool menu - Summer 2026” instead of generic file names.
# How to manage your hotel AI Knowledge Base
Source: https://docs.visitoai.com/product-guides/ai-agent/data-source
Add website, text, and file sources to your Visito Knowledge Base, organize hotel information, control property scope, and improve AI answers.
Open **Agent → Knowledge Base** to manage the information available to your AI.
## Add a source
Choose one of three source types:
* **Add URL** - add a single page or start a website crawl.
* **Add Files** - upload supported documents or images for extraction.
* **Add text** - enter a title and precise manual content such as policies, FAQs, or temporary instructions.
### Example: a policy the team must confirm
```text theme={null}
Early check-in policy
Standard check-in begins at 3:00 PM.
Guests may request early check-in from 11:00 AM for USD 35.
Early check-in is subject to availability and is not confirmed until the front desk approves it.
```
Use your real times, price, and approval process. This structure gives the agent a direct answer while preventing it from presenting a request as confirmed. Configure any escalation and required information separately in Handoff Rules.
## Organize sources
Use search and filters to narrow by:
* Type: Text, Files, or URLs
* Status: Active or Inactive
* Creator: All or Mine
* Property: All, Global, or a specific property
Each source row shows its name, last update, status, property scope, and actions.
## Property scope
* **Global** sources are available across the workspace.
* A property-scoped source is used only in that property's context.
Use property scope for policies, amenities, room details, and local recommendations that differ between properties.
## Activate or deactivate
Turn a source off when it should stop influencing responses without deleting it. You can reactivate it later.
## Edit or delete
Open row actions to inspect source details. Manual text can be edited. Delete a source only when it should be removed from the workspace.
## Storage usage
The RAG storage counter shows how many indexed tokens the workspace currently uses against its limit.
Keep time-sensitive policies in short manual text sources so they are easy to find and update.
Knowledge files teach the AI. If you want the AI to send an image or document directly to a guest, add it in **Assets** instead.
Plan topic coverage, write precise sources, handle multiple properties, and test retrieval.
# How to test your Visito AI agent in Playground
Source: https://docs.visitoai.com/product-guides/ai-agent/test-your-agent
Test your Visito AI agent privately, evaluate hotel knowledge and tone, verify handoffs and custom tools, and fix issues before guests see them.
Open **Agent → Playground** to test the same agent configuration used in live conversations.
## Test a conversation
1. Enter a realistic customer question in **Send a message**.
2. Review the answer for factual accuracy, tone, useful next steps, and appropriate tool use.
3. Continue the conversation to test context across multiple turns.
Playground resumes the latest active test chat automatically.
## Start a new chat
Select **New chat** when you want a clean context. The previous active session is archived and a new active session is created.
Use a new chat after major changes to knowledge, personalization, handoff rules, or custom tools.
## What to test
* Common questions from each property
* Policies, amenities, and local recommendations
* Availability and booking flows after integrations are connected
* Tone, emoji use, message length, and assistant name
* Human handoff scenarios and required-field capture
* Custom tool calls and error handling
For every handoff rule, test at least one message that should trigger it and one similar message that should not.
Test both the happy path and missing-information cases. The agent should ask for the right details instead of guessing. Completed Playground responses consume credits; see [how Visito credits work](/product-guides/product/usage-billing#what-is-a-visito-credit).
Use a repeatable test matrix, diagnose the owning configuration, and launch gradually.
# Write effective Custom Instructions
Source: https://docs.visitoai.com/product-guides/best-practices/custom-instructions
Give the agent clear, testable guidance for tone, conversation structure, and decision-making.
Custom Instructions control how the agent should communicate and make routine conversational choices. They complement Visito's built-in agent behavior; they are not a replacement for the entire internal system prompt.
## Separate facts from behavior
| If the instruction says… | Configure it in… |
| ------------------------------------------------------ | ----------------------------------------------------------------- |
| “Breakfast ends at 10:30 AM.” | Knowledge Base |
| “Use short paragraphs and ask one question at a time.” | Custom Instructions |
| “Escalate payment disputes to the billing team.” | Handoff Rules |
| “Send the spa menu when requested.” | Assets, with supporting behavior in Custom Instructions if needed |
Keeping these responsibilities separate makes information easier to update and behavior easier to test.
## Add Custom Instructions
Go to **Agent → Personalization**.
Choose the base style, emoji preference, message length, conversation scope, and assistant name.
Use Custom Instructions for specific rules not already represented by those controls.
Select **Save** after reviewing the complete configuration.
Open Playground and start a new chat so the test has a clean context.
## Starter template
Replace the bracketed content and remove rules that do not apply:
```text theme={null}
Act as a helpful concierge for [brand or property group].
Communication:
- Use short paragraphs and plain language.
- Ask only one follow-up question at a time.
- Address the guest by name when it is known, but do not repeat it in every message.
- Match the guest's language when possible.
Accuracy:
- Never invent prices, availability, policies, reservation details, or confirmation.
- When a question depends on the property and the property is unclear, ask which property the guest means.
- Clearly distinguish a request from a confirmed arrangement.
Conversation flow:
- Answer the guest's immediate question before suggesting related services.
- Collect only the information needed for the current task.
```
## Write instructions the agent can follow
Good instructions are:
* **Specific** - describe an observable response or decision.
* **Short** - one rule per bullet.
* **Prioritized** - put important accuracy and escalation rules first.
* **Compatible** - avoid rules that contradict each other or the Knowledge Base.
* **Testable** - you can write a Playground message that proves whether the rule worked.
### Vague versus testable
| Avoid | Prefer |
| ----------------------------------- | --------------------------------------------------------------------------- |
| “Be helpful.” | “Answer the immediate question first, then offer one relevant next step.” |
| “Do not be too verbose.” | “Use no more than three short paragraphs unless the guest requests detail.” |
| “Handle complaints well.” | “Acknowledge the concern before asking for reservation details.” |
| “Always collect guest information.” | “Collect only fields required for the current booking or handoff.” |
## Useful instruction patterns
### Concise hospitality responses
```text theme={null}
Lead with the direct answer.
Use bullets only when listing three or more items.
Do not repeat details the guest already confirmed.
Ask one question at the end only when more information is required.
```
### Avoid accidental promises
```text theme={null}
Do not describe requests as confirmed.
For early check-in, late check-out, upgrades, and special arrangements, state the documented policy and explain when team confirmation is required.
```
### Multi-property clarification
```text theme={null}
When the answer may differ by property and no property is established, ask the guest to choose the property before giving property-specific details.
```
## What to avoid
* Passwords, API keys, private links, or other secrets
* Long copies of policies that belong in the Knowledge Base
* Instructions to ignore product safeguards or connected-system results
* Rules that promise availability or prices without a provider result
* Handoff triggers that should be configured and tested in Handoff Rules
* Dozens of overlapping tone requirements
* Hidden operational notes that should instead become a handoff
## Test the instructions
Use a new Playground chat and test:
1. A simple FAQ that should receive a direct answer
2. A question missing the property
3. A request the team must confirm
4. A complaint
5. An explicit request for a human
6. A question outside the configured business scope
Change one group of instructions at a time. This makes it easier to identify which rule changed the behavior.
Review the available tone, response, scope, name, and Custom Instructions controls.
# AI escalation and human handoff best practices
Source: https://docs.visitoai.com/product-guides/best-practices/handoffs
Design hotel guest escalation rules that trigger at the right time, capture useful context, and give operators a clear workflow for resolution.
A useful handoff does two things: it moves the right conversation to a person, and it captures enough context for that person to continue without asking the guest to start over.
## Start with a small rule set
Begin with high-value scenarios:
1. The guest explicitly requests a person
2. A serious property or safety issue
3. A payment, charge, or refund dispute
4. A reservation change the agent cannot complete
Add narrower rules only after reviewing real conversations. Too many broad rules can create unnecessary handoffs.
## Configure a scenario
Go to **Agent → Handoff Rules** and confirm **Enable automatic handoff rules** is on.
Select **Add scenario** and give it a name an operator will understand.
State what should trigger the handoff and, when helpful, what should not.
Use selected properties when the workflow or responsible team differs by location.
Collect only information the operator needs to take the next action.
Test one message that should trigger the rule and one similar message that should not.
## Copy-ready scenarios
### Explicit request for a person
```text theme={null}
Name: Guest requests a person
Trigger:
Create a handoff when the guest clearly asks to speak with a human, employee, manager, front desk, or support agent. Do not require the guest to explain the reason before creating the handoff.
Required fields:
- Guest name, if not already known
```
### Serious room or property issue
```text theme={null}
Name: Urgent room or property issue
Trigger:
Create a high-priority handoff when a guest reports an immediate safety concern, flooding, fire or smoke, an electrical hazard, inability to access an occupied room, or another issue requiring urgent on-site attention.
Required fields:
- Guest name
- Guest phone, when not already available
- Custom field: roomNumber, when applicable
- Custom field: issueSummary
```
For urgent situations, avoid collecting nonessential details before escalating.
### Payment or charge dispute
```text theme={null}
Name: Payment or charge dispute
Trigger:
Create a handoff when a guest disputes a charge, reports being charged incorrectly, requests a refund that cannot be completed automatically, or reports a payment failure after retrying.
Required fields:
- Guest name
- Reservation ID or booking reference, when available
- Guest email or phone
- Custom field: paymentIssueSummary
```
## Choose required fields deliberately
| Scenario | Useful fields |
| ------------------ | ----------------------------------------------------------------- |
| Human requested | Guest name |
| Reservation change | Guest name, booking reference, check-in and check-out dates |
| Room issue | Guest name, guest phone, custom room number, custom issue summary |
| Payment dispute | Guest name, reservation ID or booking reference, contact method |
Scope each scenario to the properties where it applies. Do not request information already present in the conversation or connected reservation unless it must be confirmed.
## Configure working hours
Open the **Working hours** tab and enter the hours when a person can respond. The schedule uses the AI timezone configured in Personalization.
Test the same handoff:
* During working hours
* Outside working hours
* On a closed day
The agent should set accurate expectations without implying that the issue has already been resolved.
## Test both sides of every rule
| Should trigger | Should not trigger |
| -------------------------------------------------- | ------------------------------------- |
| “I need to speak to the manager.” | “Who is the hotel manager?” |
| “There is smoke coming from an outlet.” | “Where are the smoking areas?” |
| “I was charged twice.” | “What payment methods do you accept?” |
| “Please change the dates on my confirmed booking.” | “What dates are available?” |
Testing non-triggers is essential. It reveals rules that are so broad they interrupt normal self-service.
## Build an operational loop
1. Review handoffs in Home and the **Handoff** Conversations view.
2. Read the escalation reason, captured details, missing fields, and latest guest messages.
3. Assign a conversation owner so responsibility is explicit.
4. Complete the operational task and reply to the guest.
5. Add a short resolution note, then select **Resolve handoff**.
6. Identify false positives, missing context, or missing scenarios.
7. Update one rule at a time and retest it.
### Write useful resolution notes
A resolution note should let another teammate understand the outcome without rereading the entire thread.
```text theme={null}
Verified reservation 4821 with the front desk. Corrected the arrival date to
14 August and confirmed the change with the guest on WhatsApp.
```
Avoid notes such as “done” or “handled.” Include the action, result, and any remaining owner or next step.
## Use internal review for quality checks
Do not create a guest-facing handoff only because a conversation should be audited. Use **Mark for review** for:
* Quality assurance and coaching
* Policy or brand-standard checks
* Reviewing an unusual AI answer
* Confirming that an operator followed a process
Add a focused review note, such as:
```text theme={null}
Check whether the refund explanation matches our cancellation policy and add
coaching feedback if the response could be clearer.
```
The reviewer can be different from the conversation owner. Completing the review with **Mark reviewed** does not archive the conversation or change its response mode.
## Review handoff performance regularly
Sample resolved handoffs every week and look for:
* Rules that trigger on harmless questions
* Missing fields that force operators to ask the guest again
* Handoffs that remain open after the task is complete
* Vague resolution notes
* Requests that should become a new knowledge-base answer or automated action
Use what you learn to narrow triggers, remove unnecessary fields, and improve the operator runbook.
Review switches, fields, property scope, working hours, and the operator resolution flow.
Learn assignment, internal review, needs-reply, archive, block, and handoff workflows.
# Build a reliable Knowledge Base
Source: https://docs.visitoai.com/product-guides/best-practices/knowledge-base
Turn property information into focused, maintainable sources that the agent can use confidently.
A strong Knowledge Base gives the agent facts it can retrieve quickly and apply to the correct property. The goal is not to upload everything your business has - it is to provide clear, current information that answers real guest questions.
## What belongs where
| Content | Put it in |
| -------------------------------------------------------------------- | ------------------- |
| Check-in time, parking policy, amenities, fees, and room information | Knowledge Base |
| Tone, response format, and conversational behavior | Custom Instructions |
| Conditions that require a person | Handoff Rules |
| Menus, brochures, maps, and images the agent may send | Assets |
## Start with essential guest questions
Before adding sources, list the questions your team answers repeatedly. A useful first-property set is:
1. Check-in, check-out, and front-desk hours
2. Cancellation, deposit, and payment policies
3. Parking and transportation
4. Amenities and accessibility
5. Room types and occupancy details
6. Breakfast, restaurant, and room-service information
7. Pet, smoking, visitor, and child policies
8. Early check-in and late check-out
9. Directions and local recommendations
10. How to contact a person
Create a focused source for each topic rather than one large document called “Hotel information.”
## Add a focused text source
Go to **Agent → Knowledge Base** and select **Add text**.
Name the source after the topic, such as **Early check-in policy - Ocean View Hotel**.
Include the policy, applicable times or prices, exceptions, and what requires team confirmation.
Select the relevant property. Use Global only when the information is identical across the workspace.
Start a new Playground chat and ask the same question in several natural ways.
### Copy-ready example
Replace the bracketed values with your actual policy:
```text theme={null}
Early check-in policy
Standard check-in begins at [3:00 PM].
Guests may request early check-in from [11:00 AM].
The early check-in fee is [USD 35].
Early check-in is subject to availability and is not confirmed until the front desk approves it.
```
This source works because it separates facts from conditions and does not let the agent turn a request into a guarantee. Configure any required escalation separately in Handoff Rules.
## Prefer precise language
| Avoid | Prefer |
| ---------------------------------------- | ----------------------------------------------------------------------------------- |
| “Breakfast is available in the morning.” | “Breakfast is served daily from 7:00 AM to 10:30 AM in the lobby restaurant.” |
| “Parking may cost extra.” | “Self-parking costs USD 20 per vehicle, per night. Valet parking is not available.” |
| “We are pet friendly.” | “Dogs up to 20 kg are allowed. The fee is USD 30 per stay. Cats are not permitted.” |
| “Contact reception for details.” | State the known policy first, then explain which part requires reception. |
## Choose the right source type
* **Manual text** - best for policies, temporary notices, exceptions, and concise facts your team maintains directly.
* **Single URL** - best for one authoritative, frequently updated public page.
* **Website crawl** - useful for broad initial coverage, followed by review and cleanup.
* **Files** - useful for structured reference material the agent should read but not send directly.
A website crawl can import outdated, duplicated, or marketing-focused content. Review the resulting coverage and add precise manual sources for important policies.
## Scope multi-property knowledge
Use Global only for facts that truly apply everywhere, such as a company-wide loyalty program. Scope operational facts to a property when addresses, hours, amenities, fees, or policies differ.
For example, create:
* **Parking - Downtown Hotel**
* **Parking - Airport Hotel**
Do not create one Global parking source containing conflicting rules for both properties unless the text clearly identifies each property.
## Test retrieval
In a new Playground chat, ask:
* The exact FAQ: “What time is check-in?”
* A paraphrase: “How early can I get my room?”
* A question with missing property context
* A question containing an incorrect assumption
* A related question the source should not answer
The agent should use the correct property, avoid inventing missing details, and ask for clarification when the property is ambiguous.
## Maintain the Knowledge Base
* Assign an owner for each policy area.
* Include dates in time-sensitive source titles.
* Deactivate expired information immediately.
* Review top conversation questions monthly.
* Search for overlapping sources before adding a new one.
* Retest affected questions after every material change.
Review source types, filters, property scope, activation, and storage usage.
# Test and launch your agent
Source: https://docs.visitoai.com/product-guides/best-practices/testing-and-go-live
Use a repeatable test plan and go-live checklist before connecting the agent to guests.
Testing should prove more than whether the agent can answer one happy-path question. Verify facts, behavior, integrations, handoffs, and the cases where the agent should ask for help.
## Prepare a test plan
Build the test plan from real questions your team receives. Include at least:
| Area | Example test |
| --------------------------- | --------------------------------------------------------------------- |
| Basic facts | “What time is check-in?” |
| Property scope | “Does the Airport Hotel have parking?” |
| Missing context | “Can I bring my dog?” when no property is selected |
| Incorrect assumption | “Your breakfast is free, right?” |
| Request versus confirmation | “Can you guarantee early check-in?” |
| Reservation flow | Search dates, select a room and rate, then price the allocated guests |
| Handoff | “I need to speak with someone.” |
| Handoff false positive | “What payment methods do you accept?” |
| Custom Instructions | A question that requires the configured format or tone |
| Unknown information | Ask something not present in knowledge or a connected system |
For hospitality availability and pricing, test the complete two-phase flow: availability discovers date-valid inventory, then pricing validates the selected room, rate, and per-room occupancy allocation.
## Run tests in Playground
Use a clean chat after material changes to knowledge, instructions, integrations, tools, or handoff rules.
Use natural guest wording rather than copying your source title.
Test whether the agent retains context and asks only for missing information.
Mark it Pass, Needs content, Needs behavior, Needs handoff, or Needs integration.
Update the Knowledge Base for facts, Custom Instructions for behavior, Handoff Rules for escalation, or the relevant integration for provider results.
Confirm the fix did not create a new failure in a related scenario.
## Diagnose the right layer
| Problem | First place to check |
| --------------------------------------- | ------------------------------------------------------- |
| Incorrect or missing policy | Knowledge Base |
| Correct facts, wrong style or structure | Personalization and Custom Instructions |
| Conversation should reach a person | Handoff Rules |
| Wrong property used | Property scope and conversation context |
| Availability or price issue | Connected integration and the selection/allocation flow |
| Approved file is not shareable | Assets |
| Custom backend action failed | Build → Tool calls → Activity logs |
## Go-live checklist
### Workspace and property
* [ ] The active workspace is correct.
* [ ] Every active property has the correct country and timezone.
* [ ] Property-specific knowledge, assets, channels, and integrations have the correct scope.
### Knowledge and behavior
* [ ] Essential FAQs have clear, current answers.
* [ ] Conflicting or expired sources are inactive or removed.
* [ ] Custom Instructions are short, specific, and free of secrets.
* [ ] Requests are not described as confirmations.
### Handoffs
* [ ] Explicit requests for a person trigger a handoff.
* [ ] Urgent and payment scenarios capture only essential fields.
* [ ] Working hours and AI timezone are correct.
* [ ] Similar normal questions do not create false-positive handoffs.
### Testing and connections
* [ ] The main test plan passes in new Playground chats.
* [ ] Connected channels are assigned to the correct properties.
* [ ] **Active** and **Respond** states are intentional.
* [ ] Booking integrations complete availability and pricing tests.
* [ ] At least one operator knows how to review and resolve a handoff.
## Launch gradually
Start with one property or channel when possible. Review the first live conversations daily, then expand after the common questions and handoff behavior are stable.
After launch, use Conversations, Home, Follow-ups, and handoff history to identify:
* Frequently unanswered questions
* Incorrect property scope
* Repeated manual corrections
* Missing escalation scenarios
* Rules that trigger too often
Learn how test chats and clean sessions work.
Return to the full onboarding sequence.
# Cloudbeds
Source: https://docs.visitoai.com/product-guides/channels-integrations/cloudbeds
Authorize Cloudbeds, select properties, and configure booking-engine links for Visito.
## Connect from Visito
Open **Connections → Integrations** and select **Connect Cloudbeds**.
Sign in to Cloudbeds and approve the requested access.
After returning to Visito, choose one or more Cloudbeds properties.
For each selected property, enter its Cloudbeds booking-engine URL when available, such as `https://hotels.cloudbeds.com/reservation/VyoWjG`.
Visito connects the selected properties and reports any partial failures.
Visito stores the booking-engine identifier from the URL so booking flows can open the correct property.
## Manage
Open the integration row to:
* Assign the Visito property
* Enable or disable the integration
* Update booking-engine configuration
* Review booking-update webhook health
* Repair or retry supported webhook setup
Test availability and pricing in Playground after connecting. Pricing is completed after the room/rate selection and per-room guest allocation.
# Guesty
Source: https://docs.visitoai.com/product-guides/channels-integrations/guesty
Connect a Guesty Booking Engine website and assign it to a Visito property.
## Connect
1. Open **Connections → Integrations**.
2. Select **Connect Guesty**.
3. Enter the Guesty Booking Engine website, such as `https://yourbrand.guestybookings.com`.
4. Confirm the connection.
5. Assign the integration to the correct Visito property.
Visito validates and stores the Booking Engine website for availability and booking links.
## Manage
Open the integration row to review:
* Provider and integration ID
* Visito property assignment
* Active state
* Last validation
* Health information
## Troubleshooting
* Confirm the URL is the public Guesty Booking Engine website, not an internal dashboard page.
* Verify the property assignment.
* Review the health filter for degraded connections.
* Reconnect after changing the booking-engine domain.
# SiteMinder
Source: https://docs.visitoai.com/product-guides/channels-integrations/siteminder
Connect a SiteMinder booking engine to a Visito property.
## Connect
1. Open **Connections → Integrations**.
2. Select **Connect SiteMinder**.
3. Enter the full booking URL, for example `https://direct-book.com/properties/example-property-id`.
4. Select or enter the country code.
5. Confirm the connection.
6. Assign the resulting integration to the correct Visito property.
Visito parses the property identifier from the booking URL and validates the configuration.
## Manage
Open the integration row to review provider metadata, active state, property assignment, and validation status.
SiteMinder availability intentionally uses a neutral occupancy snapshot to discover date-valid inventory. The requested party is applied during pricing after room and rate selection.
## Troubleshooting
* Verify that the booking URL opens the intended property's direct-book page.
* Confirm the country code.
* Review the row's health state and last validation.
* Reconnect if provider configuration changed.
# Connect Instagram
Source: https://docs.visitoai.com/product-guides/channels/instagram/connecting
Authorize an Instagram Professional account and verify message routing through Visito.
## Connect
In Visito, go to **Connections → Channels** and confirm the active workspace.
Select **Connect Instagram** and allow the Meta window to open.
Verify the signed-in user can manage messaging for the intended Instagram Professional account.
Review the permissions and continue without removing access required for messaging.
Choose the intended account and finish the Meta flow.
Wait for the Channels table to refresh and confirm the Instagram account appears.
Assign the correct properties and verify **Active** and **Respond**.
If Visito reports that the account belongs to another workspace, find that workspace and disconnect it there before reconnecting.
## Disable conflicting Meta automations
In Meta Business Suite, open Inbox automations for the connected account. Disable greetings, instant replies, or other responses that overlap with Visito.
## Review Message Controls
In the Instagram app, review **Settings and privacy → Messages and story replies → Message controls**. Make sure the account accepts the types of message requests you expect Visito to receive.
Meta may rename or move settings. Search Instagram settings for **Message controls** if the labels differ.
## Verify the connection
1. Send a new direct message from an Instagram account that does not manage the business account.
2. Open **Conversations** in Visito and find the new thread.
3. Confirm the correct property context.
4. Verify the AI response or send a manual reply.
5. Confirm the sender receives one intended response.
## If the account is missing
* Close the Meta window and confirm the intended login.
* Verify the Instagram account is Professional.
* Ask an asset owner to review the authorizing user's access.
* Correct access first, then restart authorization.
Review Instagram-specific message and app-access issues.
Diagnose callbacks, ownership conflicts, degraded health, and response-state problems.
# Prepare Instagram
Source: https://docs.visitoai.com/product-guides/channels/instagram/introduction
Confirm account type, access, message controls, and automations before connecting Instagram.
Visito connects an Instagram Professional account through Meta authorization.
## Before you start
* Confirm the account is Professional, not Personal.
* Confirm you can sign in to the intended Instagram and Meta identities.
* Verify the authorizing Meta user can manage messaging for the account.
* Review Instagram Message Controls for messages from people you do not follow.
* Identify greetings or instant replies that could duplicate Visito responses.
* Confirm the active Visito workspace and intended properties.
* Allow popups and redirects in the browser.
If the intended Instagram account does not appear in Meta's asset picker, the problem is usually the signed-in Meta identity, account type, or asset access.
## What changes
After connection:
* New eligible Instagram messages appear in Visito Conversations.
* Operators can work from Visito.
* The AI responds only when the channel is active, **Respond** is enabled, and its property assignment is correct.
* Existing Meta automations can still run, so disable overlapping responses before testing.
Complete authorization, property assignment, and the inbound-message test.
Review shared browser, identity, access, and recovery prerequisites.
# Troubleshoot Instagram
Source: https://docs.visitoai.com/product-guides/channels/instagram/troubleshooting-connection
Resolve missing Instagram messages, incomplete authorization, and conflicting app access.
## Instagram messages do not appear
1. Confirm the channel is healthy and **Active** in Visito.
2. Verify **Respond** and property assignments.
3. Send a new direct message from a separate Instagram account.
4. In Instagram, review **Settings and privacy → Messages and story replies → Message controls**.
5. Allow the message-request categories your business intends to receive.
6. Search for the sender in Visito **Conversations**.
## Messages arrive but neither the AI nor operators can reply
If Visito receives an Instagram message and prepares a response but Meta rejects both automatic and manual replies, another connected app may own the conversation. Meta calls this **conversation routing**; the app responsible for new conversations is the **Primary Receiver**.
An administrator of the connected Facebook Page should:
1. Confirm the Instagram Professional account is connected to the intended Facebook Page. See Meta's guide to [connecting a professional Instagram account to a Facebook Page](https://www.facebook.com/help/instagram/402748553849926/).
2. Open the Page's messaging settings in Meta Business Suite or Business Settings.
3. Find **Advanced Messaging**, **Conversation Routing**, or **Instagram Receiver**. Meta's labels can vary by account and interface.
4. Set Visito as the **Primary Receiver** for Instagram conversations.
5. Remove or disable routing to messaging integrations that are no longer used. Do not remove unrelated business tools.
6. Send a new Instagram direct message from a separate account and verify both the AI response and a manual operator reply in Visito.
Meta links its current conversation-routing instructions from this [Instagram messaging help page](https://www.facebook.com/help/instagram/502741564466925/), under **How to set up conversation routing for Messenger or Instagram messages**.
Changing the Primary Receiver affects live message routing. Coordinate the change with operators and verify a new inbound conversation immediately afterward.
## The account does not appear during authorization
* Confirm Meta is using the intended login.
* Verify the account is Instagram Professional.
* Confirm the user can manage messaging for the account.
* Close the authorization window after correcting access, then restart from Visito.
## Guests receive duplicate replies
Open Meta Business Suite Inbox automations and turn off greetings, instant replies, or FAQ responses that overlap with Visito.
Check whether another messaging provider is still connected to the same Instagram account.
## Remove stale app access only as a last resort
Use normal Visito reauthorization first. Removing app access can interrupt a working connection.
If stale access repeatedly blocks authorization:
1. Confirm which Visito workspace owns the Instagram account.
2. Coordinate a short message-routing interruption with operators.
3. In Instagram, open **Settings and privacy → Website permissions → Apps and websites**.
4. Remove only the stale integration you have identified.
5. Return to Visito and reconnect immediately.
6. Repeat the inbound-message verification.
Do not remove unrelated business tools or revoke access you cannot restore.
Diagnose popup, asset-selection, workspace-ownership, callback, health, and response-state problems.
# How to connect hotel messaging channels to Visito
Source: https://docs.visitoai.com/product-guides/channels/introduction
Connect WhatsApp, Instagram, Facebook Messenger, and Webchat to Visito, assign hotel properties, and control AI response behavior by channel.
Open **Connections → Channels** to connect customer messaging surfaces and control how Visito responds.
Choose the correct Meta setup path, complete the readiness checklist, and verify message routing.
## Supported channels
Connect a new number or an existing WhatsApp Business App number.
Connect a professional Instagram account through Meta authorization.
Connect one or more authorized Facebook Pages.
Share a public link or install and customize the website widget.
## Channel table
Use filters for:
* State: All, Active, or Inactive
* Respond: All, Enabled, or Disabled
* Health: All or Degraded
Each row shows channel type, name, property assignments, active state, response state, health, and actions.
## Property assignments
Select **Assign properties** in a row to choose which active properties use the channel. A channel can serve multiple properties.
## Active and Respond
* **Active** controls whether the channel connection is enabled.
* **Respond** controls whether the agent may respond on that channel.
Some connection states temporarily disable these controls until setup is complete.
## Connect WhatsApp
1. Select **Connect WhatsApp**.
2. Complete Meta Embedded Signup.
3. Select the phone numbers to connect.
4. Confirm the selection.
New-number and WhatsApp Business App coexistence flows are both supported. If coexistence is pending, finish setup in the WhatsApp Business App and use **Retry Activation** from row actions.
## Connect Instagram
1. Select **Connect Instagram**.
2. Complete Meta authorization with an account that has the required professional-account access.
3. Return to Visito and confirm the connected account appears.
## Connect Messenger
1. Select **Connect Messenger**.
2. Complete Meta authorization.
3. Select one or more Facebook Pages.
4. Confirm the selected pages.
## Disconnect
Open row actions and select **Disconnect**. Confirm the action. Disconnecting removes routing for that channel in the active workspace.
Confirm the active workspace and property assignments before connecting or disconnecting a channel.
# Connect Messenger
Source: https://docs.visitoai.com/product-guides/channels/messenger/connecting
Authorize one or more Facebook Pages and route their Messenger conversations through Visito.
Use this flow to connect Facebook Page messages to the active Visito workspace.
## Before you start
Confirm that:
* You are signed in to the correct Visito workspace.
* The Facebook Page is active and [messaging is enabled](https://www.facebook.com/help/307375982614147).
* Your Meta user can manage messages for the Page.
* You know which Pages belong to this workspace.
* Conflicting Page Inbox automations can be disabled before testing.
If you cannot see or manage the intended Page, ask a person with full control to review your [Facebook Page access](https://www.facebook.com/help/1318804834897643/list/).
## Connect
In Visito, go to **Connections → Channels**.
Select **Connect Messenger** and allow the Meta window to open.
Confirm the signed-in Facebook user has messaging access to the intended Pages.
Review the requested permissions and continue.
Choose one or more eligible Facebook Pages, then confirm the selection.
Wait for the Channels table to refresh and confirm each selected Page appears.
Assign the correct properties and verify **Active** and **Respond**.
## Disable conflicting automations
In Meta Business Suite, open the Page's Inbox automations. Disable greetings, instant replies, or other responses that should not run alongside Visito.
## Verify the connection
1. Send a new message to the Facebook Page from a separate personal account.
2. Open **Conversations** in Visito and find the new thread.
3. Confirm the correct property context.
4. Verify the AI response or send a manual operator reply.
5. Confirm the customer receives only one response.
## If the Page is missing
* Confirm the Meta window used the intended Facebook login.
* Review the user's Page access and messaging permissions.
* Confirm Page messaging is enabled.
* Close the authorization window and restart after access is corrected.
Verify browser, login, asset, and workspace prerequisites.
Diagnose missing Pages, incomplete callbacks, and message-flow problems.
# Prepare for Meta authorization
Source: https://docs.visitoai.com/product-guides/channels/meta/getting-ready
Complete a preflight checklist before connecting WhatsApp, Instagram, or Messenger.
Gathering the correct access and asset information before opening Meta prevents most interrupted or incomplete connections.
## Visito preflight
* Sign in as an admin of the intended Visito workspace.
* Confirm the workspace name at the top of the sidebar.
* Open **Connections → Properties** and verify the properties you will assign.
* Open **Connections → Channels** in a desktop browser.
* Allow popups and cross-site redirects for the dashboard during authorization.
* Avoid private browsing if it prevents your Meta session or callback from being retained.
## Meta login preflight
Use a Meta login that:
* You can sign in to without another person's help
* Has access to the intended business assets
* Can approve the requested messaging permissions
* Is not a former employee or temporary agency identity
* Uses current recovery email, phone, and two-factor authentication details
If you manage several businesses, write down the intended Business Portfolio, Page, Instagram username, or WhatsApp number before opening the authorization window.
## WhatsApp readiness
### New number
* The phone number is not registered with WhatsApp or WhatsApp Business App.
* You control the number and can receive an SMS or phone-call verification code.
* You know which Business Portfolio and WhatsApp Business Account should own it.
* Your business profile information and public website are complete and current.
### Existing WhatsApp Business App number
* The number is active in the WhatsApp Business App, not personal WhatsApp.
* The app is updated to a version that supports Meta's coexistence flow.
* The phone is available during setup.
* You can receive the in-app coexistence prompt and scan a QR code.
* Your team has decided whether to share eligible message history during onboarding.
If the number is already connected to another API provider, do not start a new-number or coexistence flow until you understand the current ownership and migration path.
## Instagram readiness
* The account is an Instagram Professional account.
* You can sign in to the intended Instagram and Meta identities.
* The authorizing Meta user has the required access to manage messaging for the account.
* Message Controls permit the customer messages you expect to receive.
* Conflicting greeting or instant-reply automations are documented so you can disable them before testing.
## Messenger readiness
* The Facebook Page is active and visible.
* [Messaging is enabled for the Page](https://www.facebook.com/help/307375982614147).
* The authorizing Meta user can manage Page messages through Facebook or Meta business tools.
* You know which Page or Pages belong to this Visito workspace.
* Conflicting Page Inbox automations are documented.
Meta distinguishes Facebook access from task access. The important test for connection is whether the authorizing user can manage messages for the Page. A person with full control can correct Page access when necessary.
## Browser checklist
Before selecting **Connect**:
* Close duplicate Meta authorization windows.
* Sign out of an unintended Facebook or Instagram identity.
* Temporarily allow the authorization popup.
* Keep the Visito tab open while completing Meta steps.
* Do not use the browser Back button inside the authorization flow.
## Have a recovery owner
Record who can:
* Change Meta Page or Business Portfolio access
* Receive WhatsApp verification codes
* Use the WhatsApp Business App during coexistence
* Disable conflicting Meta automations
* Disconnect an asset from another Visito workspace
Choose the channel and correct setup path.
# Connect Meta channels
Source: https://docs.visitoai.com/product-guides/channels/meta/overview
Choose the correct setup path for WhatsApp, Instagram, or Messenger and understand the shared connection flow.
Visito connects WhatsApp, Instagram, and Messenger through Meta authorization. Most connection problems happen when the wrong Meta identity is used, an asset is owned elsewhere, or a channel-specific prerequisite is incomplete.
## Choose your path
| Channel and current state | Use this guide |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| A new phone number that is not registered with WhatsApp | [Connect a new WhatsApp number](/product-guides/channels/whatsapp/connecting-your-own-number) |
| A number currently used in the WhatsApp Business App | [Connect with WhatsApp coexistence](/product-guides/channels/whatsapp/connecting-your-whatsapp-business-app) |
| An Instagram Professional account | [Connect Instagram](/product-guides/channels/instagram/connecting) |
| A Facebook Page with messaging enabled | [Connect Messenger](/product-guides/channels/messenger/connecting) |
A personal WhatsApp account cannot be connected directly. Move it to the WhatsApp Business App before using coexistence, or use a different unregistered number.
## The shared connection flow
Confirm the account, Page, phone number, or Business Portfolio and the Meta user who can authorize it.
Open **Connections → Channels** and verify the active workspace before starting.
Allow the Meta window to open, sign in with the intended identity, and approve the requested access.
Choose the phone number, Instagram account, or Facebook Page that belongs to this workspace.
Complete the callback and wait for the Channels table to refresh.
Confirm health, property assignments, **Active**, and **Respond**, then send an inbound test message.
## Know which identity you are using
Meta may show several identities during setup:
* Your personal Facebook login
* A Business Portfolio
* A WhatsApp Business Account and phone number
* An Instagram Professional account
* One or more Facebook Pages
Signing in successfully does not guarantee that the selected Meta user can authorize every asset. Confirm access before troubleshooting Visito.
## What success looks like
The connection is complete when:
* The expected channel appears in **Connections → Channels**.
* The channel is not degraded or waiting for another setup step.
* The correct properties are assigned.
* **Active** and **Respond** match your launch plan.
* A real inbound message creates or updates a conversation.
* The AI or an operator can send an eligible reply.
## Replying from Meta after connection
Your team can sometimes reply from a native Meta surface, such as the WhatsApp Business App during coexistence or a connected Meta inbox. Meta sends Visito an outbound message echo so the reply can appear in the Visito conversation history.
For an outbound message that was not originally sent by Visito:
* Visito records the native message in the conversation.
* The conversation's needs-reply state is cleared.
* AI replies freeze for 30 minutes to prevent Visito and the teammate from answering at the same time.
* Guest messages received during the freeze remain visible and are marked for attention.
* When the timer ends, Visito may answer the latest unanswered guest message if the conversation is still in AI mode.
Messages originally sent from Visito can also produce Meta echoes. Visito matches and removes these duplicates, so they do not create another message or restart the freeze.
If a teammate plans to continue the conversation from Meta for longer than the temporary freeze, switch the conversation to **Manual** mode in Visito.
Learn how dashboard replies, native Meta messages, timers, and Manual mode interact.
Complete the channel-specific readiness checklist.
Find the symptom and follow the safest recovery path.
# Troubleshoot Meta connections
Source: https://docs.visitoai.com/product-guides/channels/meta/troubleshooting
Diagnose Meta authorization, asset selection, activation, message delivery, and duplicate-response problems.
Start with the visible symptom. Avoid removing business assets, deleting WhatsApp accounts, or revoking every Meta integration until you know which state is broken.
## Quick diagnosis
| What happened | Likely cause | First action |
| ----------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------ |
| The Meta window did not open | Popup, redirect, or browser-session blocking | Allow popups, keep Visito open, and retry |
| The intended asset is missing | Wrong Meta identity or insufficient asset access | Confirm the signed-in Meta user and asset permissions |
| Visito says the asset belongs to another workspace | Existing Visito ownership | Find the owning workspace and disconnect it there |
| The flow returned but no channel appeared | Authorization was canceled, expired, or incomplete | Refresh Channels once, then restart the flow |
| WhatsApp shows pending activation | Coexistence is not finished in the Business App | Finish the in-app/QR steps, then use **Retry Activation** |
| A new WhatsApp conversation fails with a billing or payment error | The WhatsApp Business Account has no usable payment method | Add or reactivate billing for that specific account in Meta |
| The channel is degraded | Meta access or channel state changed | Review row actions, diagnostics, or token refresh for that channel |
| Inbound messages do not appear | Messaging controls, Page settings, or connection health | Verify Meta message settings and send a new inbound test |
| Messages arrive but Visito does not respond | **Respond** is off, channel is inactive, or property scope is wrong | Check **Active**, **Respond**, and assigned properties |
| Guests receive two replies | Meta or another provider also has an automation enabled | Disable the conflicting greeting or instant reply |
## The Meta window does not open
1. Confirm you started from **Connections → Channels**.
2. Allow popups and redirects for the Visito dashboard.
3. Close older Meta authorization windows.
4. Retry in a normal desktop window.
5. If needed, sign in to Meta in another tab first and restart the connection.
## The account, number, or Page is missing
Verify:
* The Meta window is using the intended login.
* The asset belongs to or is shared with the expected business.
* The user can manage messaging for that asset.
* The Instagram account is Professional.
* Facebook Page messaging is enabled.
* The WhatsApp number is in the state required by the selected setup path.
If another person controls the asset, ask someone with sufficient Meta access to grant or correct your access before retrying.
## The asset belongs to another Visito workspace
A Meta channel should have one owning Visito workspace.
1. Switch to the workspace that currently owns the channel.
2. Confirm it is the same Meta asset.
3. Disconnect it from that workspace.
4. Return to the intended workspace and reconnect.
Disconnecting interrupts message routing for the current workspace. Coordinate the move with its operators.
## WhatsApp coexistence remains pending
1. Open the WhatsApp Business App on the connected phone.
2. Complete any pending coexistence confirmation or QR step.
3. Return to **Connections → Channels**.
4. Open row actions and select **Retry Activation**.
5. Wait for the row to refresh before starting a second connection.
## New WhatsApp conversations fail because of payment
Meta can reject a business-initiated WhatsApp conversation when the connected WhatsApp Business Account has no active payment method. In this case, Visito may receive inbound messages normally while **New conversation** fails.
To correct the billing state:
1. Open [WhatsApp Manager](https://business.facebook.com/wa/manage/home/) while signed in as an administrator of the Business Portfolio.
2. Select the WhatsApp Business Account and phone number connected to the Visito workspace.
3. Open its payment or billing settings. Meta may show these under **Account tools**, **Payment settings**, or **Billing & payments**.
4. Add a payment method, replace an expired or rejected method, and resolve any outstanding balance shown by Meta.
5. Confirm the payment method belongs to the WhatsApp Business Account—not only to Meta Pay or an advertising account.
6. Return to Visito and retry **New conversation**.
You can also open Meta's [Billing & payments](https://business.facebook.com/billing_hub/payment_settings) area directly. If several business accounts are available, verify the selected Business Portfolio and WhatsApp Business Account before changing billing.
A payment-method rejection is separate from template approval. Resolve the billing error first; if the next attempt returns a template-specific error, troubleshoot that result separately.
## The channel is connected but messages do not flow
Check the full path:
1. The row is healthy and **Active**.
2. **Respond** is enabled when the AI should answer.
3. The correct properties are assigned.
4. Instagram Message Controls or Facebook Page messaging allow the inbound message.
5. The test is a new customer message, not only an old conversation.
6. For WhatsApp-initiated outbound messages, use an eligible approved template when required.
Then open **Conversations** and search for the sender.
## Duplicate responses
Check Meta Business Suite Inbox automations for the connected Instagram account or Facebook Page. Turn off greetings, instant replies, FAQs, or other automations that overlap with Visito.
Also confirm the same asset is not connected to another messaging provider.
## Use built-in recovery before removing integrations
Use the channel-specific Visito actions first:
* **WhatsApp:** open **Health** to review phone and account diagnostics.
* **WhatsApp coexistence:** use **Retry Activation** after completing the Business App steps.
* **Instagram:** use **Refresh token** when the existing authorization needs renewal.
* **Callback error:** use the page's **Retry connect** action.
Remove old app access only when:
* The normal authorization flow repeatedly selects stale permissions
* You have confirmed which Visito workspace owns the asset
* You can reconnect immediately
* Your team understands the temporary interruption
## Collect details for support
Record:
* Visito workspace name
* Channel type and visible channel name
* Approximate time of the failed attempt
* The step where the flow stopped
* Visible Visito error text
* Whether Meta showed the intended asset
* Current health or pending state
Do not send passwords, verification codes, QR codes, API keys, or full access tokens.
Review the setup paths and success checklist.
# Configure Webchat
Source: https://docs.visitoai.com/product-guides/channels/webchat/configuration
Customize the launcher, customer entry flow, starter prompts, and embedded Webchat experience.
Open **Connections → Channels → Configure Webchat**, then select the **Configure** tab.
## Launcher action
Choose what happens when a visitor selects the launcher:
* **Open webchat** - opens the Visito chat experience.
* **Open external channel** - redirects to an active WhatsApp, Instagram, or Messenger target.
An external target is required when that action is selected.
## Style
Configure:
* Theme color
* Side: Left, Middle, or Right
* Size preset: Small, Medium, or Large
* Bottom offset
* Optional launcher label and label text
* Header title
The launcher preview updates as you work.
## Starter prompts
Turn starter prompts off or use AI-generated quick-start buttons based on active knowledge, instructions, and tools.
## Prechat fields
Turn prechat fields on to request customer details before the first message. Available fields include name, email, and phone.
Choose whether all selected fields or any selected field is required.
## Save and publish
Select **Save widget**. Installed widgets fetch visual configuration at runtime, so you do not need to replace the script after ordinary style changes.
Launcher label text is required when the launcher label is enabled.
# Before you start
Source: https://docs.visitoai.com/product-guides/channels/webchat/introduction
Connect Visito Web Chat to your website
You can connect the Visito Web Chat widget to your website in different ways.\
Choose the method that best fits your setup.
Embed the Visito Web Chat widget directly on your website using a simple script or the WordPress plugin.
Share a public link to your AI agent without installing anything on your site.
# Share
Source: https://docs.visitoai.com/product-guides/channels/webchat/share
Share a direct link to your Visito AI agent
Visito allows you to share your AI agent using a direct link. Anyone who visits this link will be able to start a conversation with your AI assistant immediately.
### How to share your agent
1. Go to [**Channels → Web Chat → Deploy**](https://dashboard.visitoai.com/app/channels).
2. Copy the generated link.
3. Send it to your users, add it to your social media, or place it anywhere you want guests to reach your AI agent.
This is the easiest way to let users interact with your assistant without installing anything on your website.
# Deploy Webchat
Source: https://docs.visitoai.com/product-guides/channels/webchat/website
Share your public chat URL or install the Visito widget on your website.
Open **Connections → Channels**, then select **Configure Webchat** and open the **Deploy** tab.
## Public URL
Use **Copy link** to share a standalone Webchat page. Select **Open** to test it in a new tab.
## Install snippet
1. Copy the script shown under **Install snippet**.
2. Paste it into your website before the closing `