Skip to main content

messages

messages.delete​

Delete Message

Effects: delete, write

Delete a message from a thread. Supports Telegram, WhatsApp, and other connected channels. Note: Some channels have time limits on message deletion.

Arguments​

ArgumentTypeRequiredDescription
message_idstringyesID of the message to delete
thread_idstringyesThread/channel ID containing the message

messages.edit​

Edit Message

Effects: write

Edit the text of a message you already sent, in place. Supported on Telegram, WhatsApp, LiveChat, Max.ru, LINE, WeChat and similar channels; NOT supported on Gmail, Instagram, or LinkedIn (their platforms forbid editing) — those return an explicit error. Note: channels impose their own limits (own messages only, edit time windows such as ~48h on Telegram / ~15min on WhatsApp).

Get the message_id from messages.read_history (each row's id).

Arguments​

ArgumentTypeRequiredDescription
message_idstringyesID of the message to edit (from messages.read_history).
new_textstringyesReplacement text for the message.
thread_idstringyesThread ID containing the message (numeric DB id or channel_ref like 'telegram:-100123').

messages.forward​

Forward Message

Effects: send, write

Forward a message from one thread to another. Supports native Telegram forwarding (preserves original sender attribution) and text-based forwarding for cross-channel scenarios.

Arguments​

ArgumentTypeRequiredDescription
dest_thread_idstringnoDestination thread to forward into. Provide at least one of dest_thread_id or recipient_name. To forward into the active conversation, pass the current thread_id. (If both are provided, dest_thread_id wins and recipient_name is ignored.)
recipient_namestringnoName of person to forward to (channel auto-resolved). Provide at least one of dest_thread_id or recipient_name. Use only when forwarding to a different contact than the current conversation.
source_message_idstringyesID of the message to forward
source_thread_idstringyesThread containing the message to forward (e.g., 'telegram:123456' or numeric DB ID)

messages.press_button​

Press Message Button

Effects: send, external_api

Press a button under a message in a Telegram chat, as the connected Telegram account: the inline menus bots such as @BotFather reply with. Name the button by its exact label.

Returns the message as it looks after the press (bots usually edit it into the next menu) and anything the bot sent after it, each with its own buttons and a message_id you can pass back to press the next one.

Refused: buttons that need the account's cloud password (the owner confirms those in the Telegram app), and buttons that share a phone number or location, pay, or open a web app. A link button is not pressed; its URL is returned. A label that matches no button returns the buttons that exist.

Get the message_id from messages.read_history. Telegram user accounts only; a bot account cannot press buttons.

Arguments​

ArgumentTypeRequiredDescription
button_textstringyesThe button's label, exactly as shown (case is ignored if nothing matches exactly).
message_idstringyesMessage the button is under: a DB id from messages.read_history, or a 'telegram:<id>' returned by a previous press.
thread_idstringyesThread containing the message (numeric DB id or channel_ref like 'telegram:123456789').

messages.read_history​

Read Message History

Effects: read

Read messages from a conversation thread. Use text_contains to find specific messages by content; media_type (photo, document, video, voice, link), date_from/date_to (YYYY-MM-DD, inclusive) and direction (incoming, outgoing) narrow the search and work without text: a photo with no caption sent by the other side in a given month is media_type='photo', direction='incoming' and the dates. A search runs over the loaded part of the conversation and, when that is not all of it, asks the channel's own server (Telegram) to search the rest and stores the hits (a search with text_contains also stores the neighbouring messages of its first 20 hits; one without words stores the hits alone). search_coverage says which: complete = true with a source, or complete = false with the reason, in which case an empty list is not proof the text is absent. sync.loaded_from is the date since which EVERY message is stored (null when unknown); sync.oldest_stored_at is the oldest message stored at all, gaps or not. Returns the most recent messages, including sender info and timestamps.

Voice calls: each row carries a meta object with allowlisted keys (event_type ∈ 'call_started'|'call_ended'|null, source ∈ 'voice_transcript'|null, call_id, speaker_display_name, duration_seconds, outcome, direction) plus per-message channel. To find calls without scanning every row, use calls.list_history instead.

Usage:

  1. Get thread_id from threads.list first, OR
  2. Use contact_name to auto-resolve thread_id

Examples:

  • User: 'show me messages from chat with [contact]' → read_history(contact_name='[contact]', limit=10)
  • User: 'last 5 messages from thread 571' → read_history(thread_id=571, limit=5)

Arguments​

ArgumentTypeRequiredDescription
beforestringnoCursor for the page of OLDER messages of a chat read live (source: "live", a Discord channel that is not synced): pass the previous answer's next_before. Pages hold at most 100 messages (limit). A stored chat pages with offset instead (the answer's next_offset). OMIT for the newest page.
channel_account_idstringnoConnected account the conversation must belong to, when you know it (from channels.list). Scopes the lookup to that account, so the same person reached on two connected accounts cannot be confused for one, and a chat that does not exist on this account is 'not found' instead of someone else's thread with a matching id.
contact_namestringnoContact/thread name to search for (optional if thread_id provided). Example: 'Jane Smith', 'John Doe'
date_fromstringnoFilter: only messages sent on or after this day (YYYY-MM-DD, UTC).
date_tostringnoFilter: only messages sent on or before this day (YYYY-MM-DD, UTC).
directionstringnoFilter: 'incoming' = written by the other side, 'outgoing' = written by the owner of the connected account. OMIT for both. (one of incoming, outgoing)
include_outgoingbooleannoInclude messages sent by you (default: true) (default True)
limitintegernoMaximum number of messages to return (default: 10, max: 100) (default 10; min 1.0; max 100.0)
load_untilstringnoLoad this conversation's history down to this day (YYYY-MM-DD, UTC) in the background, a page at a time. For a channel whose server cannot search (WhatsApp), or to read everything around a date. The answer's history_load says how far back the history reaches now and, once the run is over, why it stopped; call again to follow it. OMIT for a normal read.
media_typestringnoFilter: only messages carrying this kind of attachment. Works without text_contains, which is how a photo or document sent without a caption is found. OMIT for every kind. (one of photo, document, video, voice, link)
offsetintegernoNumber of messages to skip (for pagination, default: 0) (min 0.0)
text_containsstringnoFilter: only return messages containing this text (case-insensitive substring match)
thread_idstringnoThread ID from threads.list (e.g. '571'), or a channel_ref (e.g. 'telegram:1306644770'). Optional if contact_name provided.

messages.send​

Send Message

Effects: send, write

Send a message to a thread, channel, or contact. Supports Telegram, Email, LinkedIn, and other connected channels. For LinkedIn posts (comment_thread kind), this posts a comment on the post. Can automatically resolve recipients and channels when not specified. Can send files/images/documents as attachments — pass attachments=[file_id, ...] with integer file IDs obtained from collections.list_files, search.files, or files.search. text is optional when attachments are provided.

Arguments​

ArgumentTypeRequiredDescription
attachmentsarraynoArray of integer file IDs to send as attachments (images, documents, any files). Get file IDs from collections.list_files (field file_id), search.files (field file_id), or files.search — only ids returned by those calls in this workspace. The file must already exist in the workspace (status=ready) — no separate upload step needed. When attachments are provided, text becomes optional (a caption can be included alongside).
buttonsarraynoInline reply buttons shown under the message, one per row (max 10). Each item is {"label": "<visible button text>"} plus exactly one target: "value" (a string sent back as a normal incoming message when tapped, defaults to the label, max 64 bytes), "url" (opens a link) or "web_app" (opens an https page as a Telegram Mini App). A "url" button may add "track": true: the tap is then counted for this conversation (analytics_link_clicks_v in analytics.query) and the person is sent on to the url; "tag": <ai_tag id> beside it also puts that tag on the CONVERSATION at the tap (a group's tag is any member's tap; a first message to a new contact has no conversation yet and goes out untagged); "pass": "<name>" opens the url with <name>=<the chat's id on its channel> added, so the site can name the person back in its own events. Only on channels that support buttons (Telegram bot accounts); can accompany at most one attachment, and when the text is too long for a media caption the buttons arrive with the text as a second message.
formatstringnoMessage format (one of text, markdown, html; default text)
from_account_idintegernoWhich of the workspace's accounts on this channel SENDS the message, i.e. the number or handle the recipient sees. A numeric thread_id is one conversation on one account: naming a different account for it is refused. With a channel_ref or recipient_username, the conversation ON THIS ACCOUNT is used, or opened where the channel can start one; if it has none, the send is refused rather than made from another account. OMIT and the platform picks the most recently active account, which is a coin flip in a workspace with several numbers: pass it whenever one of them must not be used to open conversations (a personal line, or one under a spam restriction). An account that is not active in this workspace is refused, never silently swapped.
mentionsarraynoPeople of a group chat to @-tag so the platform really notifies them (WhatsApp, Telegram groups). Each item names one member of THIS chat by one of: "name" (as shown in the chat), "phone" (international number) or "entity_id". If the text already holds "@<name>" that spot is the tag, otherwise "@<name> " is put in front of the text. A person who is not in the chat, or who matches several, refuses the whole send and lists the members. Without this parameter a "@Name" in the text of a group message tags the member it names in the same way, and an @-word that names nobody refuses the send (on Telegram it stays text: a typed @username is a link there). Not combinable with attachments or buttons, and not available while the agent sends drafts. Text may be empty: the tags alone are sent.
private_replybooleannoComment threads only (Instagram, Facebook): answer the comment in the commenter's private messages instead of publicly under the post (Meta's Private Replies). One message per comment, within 7 days of the comment. The message is filed in the person's private conversation. To also answer publicly, make a second call without this flag. OMIT for a normal send.
recipient_namestringnoName of a person already in contacts (e.g., 'Jane', 'John'). Tool will auto-resolve channel. Optional if thread_id provided. Not for a phone number: a new number goes in thread_id (see there).
recipient_usernamestringnoTelegram @username to message (e.g. '@some_username'). Use this for a Telegram user NOT yet in contacts — it resolves the handle, adds the contact, and creates the thread. Telegram only; for existing contacts prefer thread_id or recipient_name.
reply_to_message_idstringnoID of message to reply to (optional)
silentbooleannoSend without notification
templateobjectnoWhatsApp Business API only. An approved template to send instead of free text, in Meta's shape: {name, language, components:[{type:'body', parameters:[{type:'text', text:...}]}, ...]}; language is the code as a string ('en_US'). Required when the 24-hour window of the conversation is closed (the send answers WINDOW_EXPIRED otherwise). Read the approved templates and their variables with channels.list(account_id=...).
textstringnoMessage text to send. Optional if attachments provided. (max 4096.0)
thread_idstringnoTarget thread. OMIT to reply in the same chat you received the triggering message from — the backend defaults to the current thread. Pass an explicit value ONLY to reply in a DIFFERENT thread, and only use: (a) a numeric DB thread id from search.threads, or (b) a channel_ref like 'telegram:-12345'. To write to a phone number nobody has a thread with yet: 'whatsapp:+<number in international format>' writes to it from a personal WhatsApp account (from_account_id picks which one), 'whatsapp_business:+<number in international format>' opens a WhatsApp conversation from a WhatsApp Business API number (from_account_id picks which one; the first message must be a template), and 'sms:+<number>' texts it from a workspace phone number that has SMS turned on (from_account_id picks which one), landing in that number's conversation with the recipient, next to their calls. 'x:@<handle>' sends a first X direct message to that person from a connected X account; X refuses it when their inbox is closed to the sender. 'discord:<user id>' (the person's numeric Discord id) sends a first Discord DM from a connected Discord account, into the DM that exists with them or one opened for it; new DMs are limited per account and day, and refused in words with a retry_after when over. 'skool:user:<user id>' (optionally '@<community id>' after the id, when the two share several communities) sends a first message on Skool from a connected Skool account; a Skool post thread ('skool:<account>:post:<post id>') takes a comment instead. NEVER use a chat-type word (dm, group, channel, livechat, comment_thread) — those are category labels from the SITUATION block, not ids.

messages.send_email​

Send Email

Effects: send, write

Compose and send an email — with subject, CC/BCC, and attachments. Use for email; for chat messages (Telegram/WhatsApp/livechat) use messages.send instead.

Arguments​

ArgumentTypeRequiredDescription
attachmentsarraynoArray of integer file IDs to attach.
bccarraynoEmail addresses to BCC. OMIT to skip.
ccarraynoEmail addresses to CC. OMIT to skip.
from_account_idintegernoWhich of the workspace's mailboxes SENDS an email to recipient_email (an id from channels.list). With several mailboxes and none named, an address one mailbox already writes with goes from that mailbox, any other is refused with the list. A mailbox outside the workspace is refused, never swapped. A reply in the current thread (no recipient_email) goes from that thread's mailbox.
recipient_emailstringnoRecipient email address (e.g. 'john@example.com'). Provide to start a new email thread; OMIT to reply in the current email thread.
subjectstringnoEmail subject line. Required for new emails; for replies it auto-generates 'Re: ...' when omitted.
textstringnoEmail body.