Skip to main content
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.
Required scope:
Example response:
Store the channel id when you need to send WhatsApp templates from a specific number.

List Conversations

Required scope:
Common query parameters: Example:
To retrieve only contacts who opted out of supported WhatsApp STOP commands:
Each returned conversation includes optedOut, optedOutAt, and optedOutReason. Use the contact identifier in the returned participant object to suppress the matching recipient in your own campaign system. Visito continues to block outbound sends to an opted-out conversation even if your external synchronization is delayed. The endpoint returns the current live window:
Pass the response’s nextCursor as the cursor query parameter with the same filters to fetch the next page. Keep limit between 1 and 200. Stop when hasMore is false; nextCursor is then omitted. Conversations are ordered by most recent message, with conversation ID as the tie-breaker. This is a live list: new messages can move a conversation ahead of your cursor, so refresh the first page for new activity and deduplicate IDs when merging pages. Invalid cursors return 400 M2M_INVALID_REQUEST.

Get Conversation Detail

Required scope:
Use this endpoint before sending a reply so your integration has the latest conversation context. Example response:
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

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:
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

Required scope:
Required headers:
Request body:
You can send text, media, or both:

Automatic AI pause (auto-freeze)

Accepted replies inherit the business default from Configuration → Personalization → Assistant settings → Pause AI after a team reply. Admins can choose Off, 15 minutes, 30 minutes, 1 hour, or 2 hours on web and in mobile Personalization → Assistant settings. Businesses without a saved preference keep the server default (normally 30 minutes). This applies to text, existing mediaId attachments, and URL attachments. Each accepted reply restarts the selected timer. Settings changes affect future replies, not existing pauses. Automatic assistant messages do not acquire an operator pause. Omit autoFreeze to inherit the business default. Override one reply with:
Use integer minutes from 1 to 120. To skip creating or extending a pause:
Off preserves any existing pause. It does not resume AI. Pause changes run asynchronously after acceptance, without waiting for attachment preparation or delivery. Replaying the same Idempotency-Key does not restart the timer; recovery uses the original reply’s saved choice and acceptance time.

Show the expiry and resume AI

Conversation list/detail objects include the optional ISO timestamp frozenUntilAt. Use it for “AI paused until…”. GET /conversations/{conversationId}/policy also returns isFrozen and frozenSecondsRemaining (conversations:read). Your Resolve action can clear the timed pause using conversations:policy:write:
The same endpoint accepts {"freezeForMinutes":120} to set a pause explicitly. Do not combine it with unfreeze:true. No separate /unfreeze endpoint is needed. Clearing the timer does not override manual mode, blocking, or unresolved handoffs; resolve an open handoff through the handoff workflow first.
Older dashboard clients using autoFreeze.enabled retain their historical behavior: enabled:false clears a timed pause. New integrations and updated apps should use mode; do not combine mode and enabled.

Send an attachment by URL

URL attachments are available by default on supported channels with conversations:write. Existing text and mediaId replies remain available. M2M has no multipart upload endpoint.
Use the same reply endpoint, token, and Idempotency-Key. No prior upload or mediaId is needed:
For an image, use {"media":{"type":"image","url":"https://files.example.com/photo.jpg"}}. For ordinary audio, use {"media":{"type":"audio","url":"https://files.example.com/message.mp3"}}. A WhatsApp voice note uses:
Use one media object or one existing mediaId, never both. filename is optional. text accompanies image/video/documents as a caption on WhatsApp; Instagram and Messenger may deliver it separately. WhatsApp audio cannot include text in the same request. voice is only valid on audio; voice: true requires WhatsApp and mono OGG/Opus. Files are not transcoded. Webchat is outside this release. Unsupported combinations return 400 REPLY_MEDIA_COMBINATION_UNSUPPORTED; Visito does not substitute a text link. Providers may reject malformed or unsupported codec details even after initial validation. The URL must serve the file directly over public HTTPS on port 443 without cookies or custom authorization headers. Signed URLs are accepted and must remain valid until preparation completes, including retries. Private networks and IPv6 destinations are rejected. Up to three redirects are checked. Downloads have a 30-second deadline and byte limits are enforced on the received stream. Visito queues preparation, validates the content, and stores a copy before dispatch. 202 means accepted, not downloaded or delivered. Persist replyId and requestEventId; use the delivery-status endpoints and conversation history to reconcile. After preparation succeeds, delivery retries reuse Visito’s copy, including after the source URL expires. Invalid fields/URLs and known unsupported combinations fail before acceptance. Later download, format, size, or storage failures mark the queued reply as failed; no substitute text is sent. Failed preparation exposes a sanitized errorCode on message/request status. Preparation errors include REPLY_MEDIA_SOURCE_CHANGED, REPLY_MEDIA_TOO_LARGE, REPLY_MEDIA_UNSUPPORTED_FORMAT, REPLY_MEDIA_CONTENT_TYPE_MISMATCH, REPLY_MEDIA_UNSAFE_DESTINATION, REPLY_MEDIA_TIMEOUT, and REPLY_MEDIA_DOWNLOAD_FAILED. Retry a request only with its original body and Idempotency-Key to avoid creating another send. Successful response:
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 to create, list, and send templates. See Daily operations for conversation search, follow-ups, reviews, WhatsApp start, reservations, and messaging configuration.