List Channels
Use channels to discover the connected accounts your integration can work with.id when you need to send WhatsApp templates from a specific number.
List Conversations
Example:
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
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
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:
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
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, existingmediaId 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:
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 timestampfrozenUntilAt. 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:
{"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.Idempotency-Key. No prior upload or mediaId is needed:
{"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:
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
- Persist the
conversationId,replyId,requestEventId,correlationId, andIdempotency-Keyfrom the202response. - Read
GET /m2m/v1/conversations/{conversationId}/messages. - Match
requestEventIdtomessages[].eventId. - Treat
queuedas pending,sentas handed to the provider, andfailedorblockedas unsuccessful. - If the original send request times out, retry the exact same body with the same idempotency key before deciding to create new outbound work.
409 REPLY_WINDOW_CLOSED. For WhatsApp, use an approved template to reopen the conversation instead of retrying the reply.