Action nodes
The steps that do the work — send messages, manage conversations, route, apply AI, and keep your CRM in sync — with the parameters and outputs of each.
Action nodes are where a workflow does something. Add as many as you need and chain them in any order. Every action's parameter fields accept {{trigger.*}} and {{<step>.*}} variables — optionally with an explicit format like {{trigger.payload.total | toCurrency: "INR"}} — and most actions also produce variables that later steps can read.
Some actions need a conversation
Conversation-scoped actions (Open, Resolve, Star, Send Message, Add Label, Assign…) need a conversation to act on. Under conversation triggers that's automatic. Under Incoming Webhook, Contact Stage Changed, or Workflow Error, supply one first — for example with Send WhatsApp Template to a phone number (it creates the conversation) or Find Contact. Each action below notes whether it requires a conversation.
Every action that runs on a conversation returns {{<step>.conversationId}}, so you can pass the conversation forward. Action-specific outputs are listed with each one.
Conversation management
Open Conversation
Sets the conversation's status to Open.
- Needs a conversation: Yes · Parameters: none · Output:
conversationId
Resolve Conversation
Marks the conversation Resolved. Note this only changes the status — it does not unassign the AI persona, so the agent keeps replying if one is assigned. To stop AI replies, use Assign to User as well.
- Needs a conversation: Yes · Parameters: none · Output:
conversationId
Star Conversation
Stars the conversation for quick access.
- Needs a conversation: Yes · Parameters: none · Output:
conversationId
Unstar Conversation
Removes the star.
- Needs a conversation: Yes · Parameters: none · Output:
conversationId
Messaging
Send Message
Sends a message into the conversation. Compose the text right in the node.
- Needs a conversation: Yes
- Parameters:
- Message — the body. Supports
{{...}}templating. - Generate with AI — when on, the message text is used as a prompt and the reply is written by AI.
- Quick replies — optional tappable buttons; each has a
titleand an optionalpayloadthat comes back when the customer taps it. - Attachments — optional media/files; give each a public
urland atypeofIMAGE,VIDEO,AUDIO, orFILE.
- Message — the body. Supports
- Outputs:
conversationId,messageId,quickReplyCount,attachmentCount
The AI may reply too
This send is independent of the built-in AI agent — if a persona is assigned, its reply still goes out, and on a new conversation it often lands before this step runs. Use a workflow message to complement the agent, and see Workflows and the built-in AI agent if you need the workflow to own the response.
WhatsApp's 24-hour window
On WhatsApp you can only send a free-form message while the customer-service window is open (they messaged in the last 24 hours). To start a conversation, or to reach someone after the window closes, use Send WhatsApp Template with an approved template instead. A Decision node's 24h Reply Window condition lets you branch between the two.
Send Email
Sends an email reply on the conversation's email-channel thread.
- Needs a conversation: Yes (an email conversation)
- Parameters: To / Cc / Bcc (optional; default recipient is the contact's address, comma-separate multiple), Subject (optional; defaults to the thread's subject), HTML body (preferred), or plain-text Message as a fallback. All support templating. One of HTML or Message must be non-empty.
- Outputs:
conversationId,messageId,subject
Availability
Send Email is gated by a feature flag. If you don't see it, contact support to enable it for your organization.
Send WhatsApp Template
Sends an approved WhatsApp template — the only way to start a WhatsApp conversation or message someone outside the 24-hour window.
- Needs a conversation: No. It works two ways:
- Into a conversation — leave the recipient blank; it uses the trigger's conversation.
- To a phone number — under a trigger with no conversation (like Incoming Webhook), set Recipient phone. The step creates or reuses that person's conversation, so later steps act on it automatically.
- Parameters: Conversation (optional), Recipient phone / Recipient name (for mode 2), Channel (required when sending to a phone), Template (required when sending to a phone; reuses the last template sent when a conversation is bound), Body variables (map of name → value), Header text or Header media URL. All values support templating.
- Outputs:
conversationId,conversationCreated(false = reused),messageId,templateId,templateName
Labels
Add Label
Applies one or more existing labels to the conversation.
- Needs a conversation: Yes · Parameter: the label(s) to add · Outputs:
conversationId,labelIds
Remove Label
Removes one or more labels from the conversation.
- Needs a conversation: Yes · Parameter: the label(s) to remove · Outputs:
conversationId,labelIds
Routing
Assign to User
Assigns the conversation to a specific teammate — and clears the AI assignee, so the built-in agent stops replying. This is the way to route a conversation away from AI.
- Needs a conversation: Yes · Parameter: the target user · Outputs:
conversationId,userId
Assign to AI
Assigns the conversation to a specific AI persona, overriding the default persona Cloodot would otherwise pick. It sets who answers — it doesn't send a reply by itself; the chosen persona responds from the conversation's next message on.
- Needs a conversation: Yes · Parameter: the AI persona version · Outputs:
conversationId,personaVersionId
Assignment vs. the built-in AI flow
On a new conversation the agent usually replies before a workflow's assignment runs, so Assign to User takes effect from the next message rather than suppressing the first reply. Assign early when a conversation shouldn't be handled by AI. Full detail: Workflows and the built-in AI agent.
AI
AI Extraction
Reads a source — by default the previous step's output — and pulls out the fields you define, turning free-form text or a raw API response into structured data you can branch on.
- Needs a conversation: Only when Extract from is set to Conversation. Reading the previous step (or a custom input) works under any trigger, including webhooks.
- Parameters:
- Extract from → Previous step (the output of the step wired into this one), Conversation (the transcript, up to the last 50 messages), or Custom (any value you bind, e.g.
{{fetch_order.response.body}}) - Fields — the schema to extract into. One row per value: a name, a type (text, number, yes/no, or list of text), and a description telling the model what to look for. The description is what the model actually extracts against, so it's worth writing.
- Instructions — extra steering. Required only when no fields are defined, in which case the model decides the shape from the instructions alone.
- Extract from → Previous step (the output of the step wired into this one), Conversation (the transcript, up to the last 50 messages), or Custom (any value you bind, e.g.
- Outputs:
conversationId,extractedData— each field lands under its own name, so reference it downstream as{{ai_extraction.extractedData.<name>}}(or with a Decision node's Variable condition on the same path). A field the source doesn't state comes backnullrather than invented.
Extracting from an API response
The common pairing is Simple API Request → AI Extraction: fetch an order, an invoice, or a CRM record, then pull the two or three values you actually need out of the response into named fields. Large responses are truncated at 12,000 characters before the model reads them.
CRM
These actions operate on a contact, so they work under any trigger — including webhooks, the classic "external CRM fired a webhook → mirror the contact" flow.
Create Contact
Creates a contact in your CRM, with custom fields and a policy for duplicates.
- Needs a conversation: No
- Parameters: Name (required), Phone, Email (both used to match existing contacts), Stage, Custom fields (one row per field; blank values are skipped), and If a match exists →
update(default),skip, orfail. - Outputs:
contactId,created(false = matched an existing contact),name,email,phone,stageId
Update Contact
Updates a contact's details and custom fields. Blank values keep the current data.
- Needs a conversation: No — targets the Contact parameter (templatable, e.g.
{{trigger.contactId}}) or, when blank, the triggering conversation's contact. - Parameters: Contact (optional), Name, Phone, Email, Custom fields
- Outputs:
contactId,updatedFields,name,email,phone
Find Contact
Looks up a contact by phone or email so later steps can use it. Returns found = false instead of failing when there's no match — branch on it with a Decision node.
- Needs a conversation: No
- Parameters: Phone (checked first) and/or Email. Both support templating.
- Outputs:
found,contactId,name,email,phone,stageId,stageName,customFields
Change Contact Stage
Moves a contact to a lifecycle stage in your pipeline.
- Needs a conversation: No — targets the Contact parameter or the triggering conversation's contact.
- Parameters: Stage (required), Contact (optional)
- Outputs:
contactId,fromStageId,toStageId,toStageName
Skill Set actions
Installed Skill Sets show up here too, each listed as {Skill Set} · {skill}. They appear only when the Skill Set is installed, and let a workflow call your custom skills as a step.
Loop prevention
To stop infinite loops, some actions are hidden based on your trigger. A workflow triggered by Label Added can't Add Label; Conversation Resolved can't Resolve Conversation; Contact Stage Changed can't Change Contact Stage; and so on for each matching trigger–action pair.