## Overview

Some native actions do a lot more than set a single value — creating a **CRM deal**, a **charge**, a
**task**, a **contact** or a **conversation** takes several fields. Those actions now expose a **real
form** in the Flow Builder action node, instead of a single-value picker. You fill each field with the
same typed inputs used everywhere else in the builder, including the `{{ variable }}` picker.

At the same time, the long event and action lists are now **grouped by module** and **searchable**, so
you can find `crm_item_won` or "Create deal" without scrolling through everything.

## Prerequisites

- **Admin** permission to edit automations, macros, flows and webhooks.
- The relevant module enabled (CRM, Payments, Tasks, Follow-ups, …) so its pickers can load.

## Step by step

1. Open a flow, add a **General actions** node and choose the action.
2. Fill dependency fields first, such as **pipeline → stage**.
3. Use `{ }` for variables and **Advanced** for targets, links and attributes.
4. Run **Run test** with the right context and inspect outputs, skips and effects before publishing.

## Settings & options

### Action forms (param-driven)

When you pick one of these actions on a **General actions** node, a form appears with exactly the fields
the action accepts:

- **Create CRM deal** — title, description, **pipeline → stage** (the stage list follows the pipeline
  you choose), **value** (with variables), currency, priority, assignee, team, expected close date,
  **opening date**, **contact** (by id, email or phone), **organization**, **participants** (deal
  collaborators), and the **custom** and **additional attributes**.
- **Create charge** — billing type, **amount** (with variables), currency, description, due date,
  installments (for credit card), and, under **Advanced**, the payment connection, deal link, catalog
  products and source.
- **Create task** — title, description, assignee, priority, status, due date or "due in N days", task
  list, and, under **Advanced**, the **team**, the **parent task**, the **start date**, the **labels**
  and the **custom** and **additional attributes**.
- **Create an appointment** — calendar, title, description, location, timezone, start and end, all-day,
  conferencing, invitees, recurrence, and, under **Advanced**, the explicit **contact**, the link to a
  **deal** and to a **task**, plus the **custom** and **additional attributes**.
- **Create contact** / **Create conversation** — the identity fields (name, email, phone, identifier),
  inbox, custom attributes; and for conversations, the initial status, assignee, team and message.
- **Enroll in follow-up** — the sequence, plus optional deal/charge links under **Advanced**.
- **Create subscription** — billing type, amount, currency, **cycle** (weekly to yearly), description,
  first due date and, under **Advanced**, the payment connection and plan.
- **Send WhatsApp template** — the Meta-approved template's name, language and variables, with the
  namespace and fallback text under **Advanced**.
- **Chaining verbs** — add note/checklist/participant, assign a deal or task, comment/label/link a task,
  send/cancel a charge or subscription, take over a conversation, and adjust an ad budget now have forms
  with an explicit **target** field under Advanced (see "Chaining steps" below).

Two details worth knowing:

- **Money is written in major units and accepts variables.** `4.97` means `R$ 4,97`; you can also type
  a token like `{{ crm.value }}` and it is rendered when the flow runs.
- The **pipeline → stage** picker is dependent: choosing a different pipeline clears the stage so you
  never keep a stage that belongs to another pipeline.

### The same forms in Automations and Macros

These forms are no longer exclusive to the Flow Builder. **Create a CRM deal**, **Create a task**,
**Create an appointment**, **Create a contact**, **Link a task to a record**, **Set the task team** and
**Register an order** now show the full form in the **Automations** and **Macros** editors too — before this, "Create a deal in
the CRM" offered only a title and a description there, with no pipeline, stage, value or owner.

Every other action is unchanged: the ones that already have a dedicated editor (deal value, custom
attribute, catalog, payments, commerce, WhatsApp…) keep their rich widget.

A few fields appear in the **Flow Builder only**: the ones that exist for step chaining (the **contact**
and **company** on "Create a deal", the **parent task** on "Create a task"). In a rule that fires per
conversation, a fixed value there would pin every run to the same record — leaving them blank makes the
action use the triggering conversation's contact, which is the correct behavior.

### No more typing ids: searchable pickers and a real date field

Every field that used to ask for a **raw id** is now a searchable picker over real records — deal, task,
contact, company, task list, calendar, charge, subscription, plan, affiliate and ad campaign. Each field
has a toggle between:

- **Choose** — search by name (or title) across the account's records;
- **Variable** — the text field with the `{{ }}` picker, for chaining `{{ steps.create_deal.id }}`.

The mode follows the value itself: a value containing `{{` opens in variable mode. Switching modes does
**not** erase what you had configured, and a saved id whose record is not in the first page still reads
as `#123` instead of looking empty. The list is only fetched when you open the picker.

Business timestamps (an appointment's **start** and **end**, a deal's **opened at**) now use the date and
time picker in the **account timezone** — the same component as the rest of the product — with the
variable mode beside it. Pure day fields (due date, expected close date) stay plain dates.

"Link a task to a record" is complete now: besides the type (Conversation, Contact, Deal) it has the
**target record** picker, which follows the chosen type. Without that target, the action did nothing.

### Two actions that gained a screen

- **Set the task team** — pick the task's team; leave it empty to remove the current one.
- **Register an order** — registers an order for the conversation's contact: title, amount, currency,
  status, source/gateway, external id and, under Advanced, the deal link and the affiliate. It only
  appears on accounts with the **Orders Registry** module. Orders are de-duplicated by **external id**.

### Links: who owns the record you just created

When the flow runs inside a conversation, the new deal automatically inherits **that conversation and its
contact** — the classic "conversation resolved → create deal" behaviour, and it still applies whenever
you leave those fields empty.

**What you fill in beats that inheritance.** If the form names a **contact**, that is the contact on the
deal, even when the conversation points at somebody else. Inheritance becomes just a default for when the
flow never said who the record belongs to.

In a flow **without a conversation** (webhook trigger, API, schedule) there is nobody to inherit from. For
those runs the form accepts three routes, in this order:

1. **Contact** — the id of an existing contact, usually coming from an earlier step.
2. **Contact email** — looks the address up and, when nobody matches, **creates the person**.
3. **Contact phone** — same rule, with the number normalized to the international format (you can send
   `21971532700`; it becomes `+5521971532700`).

If the person can be neither found nor created (an invalid email, say), **the deal is still created** —
only without the link — and the reason shows up as a "skipped" badge in the data panel. Losing the link is
bad; losing the deal would be worse.

### Custom attributes follow the pipeline's fields

Watch out for this rule, it catches people out: when the target **pipeline has custom fields configured**,
the deal keeps **only** the attributes on that list. Any key you send that is not configured as a field of
that pipeline is **dropped silently** — no error, no warning, no failed node.

- Before mapping an attribute in the form, check under **CRM → Settings** that it exists as a field of
  the pipeline the action will use.
- When the pipeline **configures no custom fields at all**, everything you send is stored.
- The pipeline's required fields stay required: sending one of them blank makes the creation fail (and the
  node records the error) instead of writing a half-filled record.

### Categorized, searchable lists

- **Webhook events** (Settings → Integrations → Webhooks): events are grouped by module (Conversations
  & Contacts, CRM — Deals, Tasks, Payments, WhatsApp, …). Each group has a **search box**, a
  **select-all** checkbox with a count badge, and a partial (indeterminate) state when only some events
  of the group are selected.
- **Automation triggers**: the event dropdown is grouped into module sections.
- **Actions** (Automations, Macros and the Flow Builder): the action picker shows a **module header**
  above each set of actions.

None of this changes the stored data — event keys, action names and the webhook payload are exactly the
same as before. Only the way they are presented changed.

### Run a test straight from the editor

The **Run test** button executes the flow's **current draft** once, without publishing. After the run,
every node on the canvas shows a result badge (**✓ completed** with its duration, **✗ failed** with the
error, **◇ skipped**) and the data panel starts showing the **real values** each step produced.

- Heads-up: the test runs actions **for real** — it creates records, fires charges and webhooks. An
  explicit confirmation appears before running.
- Without a test conversation, message nodes are **skipped** (the rest of the flow still runs). You can
  provide a conversation or contact to exercise the full path.
- Available to administrators.

### Webhook trigger: flexible authentication and pre-publish testing

- The webhook URL and **token** exist from the **draft** — the panel's `curl` example is real from the
  first save.
- An authenticated delivery to an **unpublished** flow is accepted as a **test sample** (the panel
  captures the body for mapping) without starting a session. Publish when you are ready.
- Three **authentication modes**: **Signed** (HMAC over the body — the default and safest), **Bearer**
  (the `Authorization` header) and **URL secret** (`?token=…`) — the last two for tools that cannot sign
  the body (form builders, ERPs, no-code tools).
- The panel shows the **last delivery received** (accepted, sample captured, replayed or rejected by
  authentication) with its time — no more guessing whether the POST arrived.

### Chaining steps (ids of created records)

Every action that creates a record now exposes its **id** (and main fields) in the step output. In the
variable picker, look for the node's name — a "Create deal" step, for example, offers its id for later
steps to use as a target:

1. **Receive lead** (webhook trigger) → 2. **Create contact** → 3. **Create CRM deal** →
4. **Create charge** → 5. **Enroll in follow-up** → 6. **Create task**.

The step key is the **node's name** in lower case, with `_` replacing anything that is not an unaccented
letter, a digit or `_`. A node called "Find contact" becomes `find_contact`, and its output reads like
this:

- `{{ steps.find_contact.contact_id }}` — the contact that was found, ready to drop into the **Contact**
  field of a "Create CRM deal" right after it.
- `{{ steps.create_deal.id }}` — the deal you just created, to attach a charge, an appointment or a task
  to it.
- `{{ steps.create_task.id }}` — the new task, handy as the **parent task** of subtasks or as an
  appointment's link.

**Careful with accents and punctuation:** they do not fold into the plain letter, they become `_`. A node
called "Create quote (São Paulo)" answers to `create_quote_s_o_paulo`. Name the nodes you intend to chain
with plain letters and digits — or simply pick the token from the variable picker.

Renamed the node? The key follows the new name — revisit the tokens that pointed at it. If two nodes share
the exact same name, the first one keeps the key and the other answers by its node id (the variable picker
always shows the correct token, so prefer picking from it over typing from memory).

- In a flow **without a conversation** (webhook/API), the contact created in step 2 automatically becomes
  the target of the following steps.
- The note, checklist, participant, assign, comment, label and link forms carry a **target** field under
  Advanced that accepts the id of an earlier step; when empty, the flow's own records are targeted.

### When an action does nothing: the reason in the panel, and strict mode

Some actions simply have nothing to do — there was no deal to assign, the contact could not be resolved,
the module was not configured. That used to go unnoticed: the flow moved on, the step came back empty and
nothing explained why.

Now an action that decides not to act records the **reason** alongside the step. To read it:

1. Open the **Available data** panel and go to the **Steps** tab.
2. The step shows the **"Action skipped"** warning followed by the reason, in the same alert block as the
   truncation warnings.
3. With the step collapsed, the warning icon in its header already carries the reason in its tooltip —
   you do not need to expand it to understand what happened.

This applies to both **Run test** and the execution history.

By default a skipped action **does not stop the flow**: it is recorded and execution continues. Use the
warning to find out why a later step did not find the record it expected.

#### Strict mode: stop instead of carrying on with a half-built record

When moving on is worse than stopping, open **Advanced** on the action node and turn on the **"Fail the
node when the action does nothing"** switch:

- **Off (default)** — today's behaviour, with no change to any existing flow: when the action declines to
  act, the flow moves on and the reason appears on the step output.
- **On** — an action that declines to act **and produces nothing** makes the **node fail** instead of
  advancing. Use it on critical steps, such as the charge that must exist before you send the payment link.

**Mind the carve-out, it is subtle:** a *partial* success still moves on even with the switch on — for
example, the contact was created but could not be linked to the inbox (the chosen inbox's channel could
not derive a `source_id`). The contact **exists** and the next steps already have a real record to use, so
stopping there would be wrong. The switch only halts the case where the action produced nothing at all.

The option appears under **Advanced** on the generic **General actions** node and on every per-module
action node: **CRM**, **Tasks**, **Contacts**, **WhatsApp**, **Calendar**, **Payments**, **Catalog**,
**Commerce** and **Ads**. The **Account Brain** node runs on its own engine, so it does not carry the
switch.

### Send WhatsApp template and send WhatsApp flow

Both WhatsApp messaging actions existed in the engine but **appeared in no picker** — you could not build a
rule or macro with them. They are now in the **Automations**, **Macros** and **Flow Builder** catalogs (in
the generic action node and in the **WhatsApp** node), with a full form:

- **Send template** — the **template** is a list of the account's **approved** templates (no typing the
  name). Leave the **language** empty and the send adopts the picked template's own language. The
  **variables** fill the `{{1}}`, `{{2}}` placeholders in the body.
- Under **Advanced**, two new fields cover the templates a flat map could never reach: **header variables**
  (including `media_url` + `media_type` for a media header) and **button variables** (a JSON array, one
  object per dynamic button). Without them a template with a media header or a dynamic button was rejected
  by Meta.
- **Send flow** — pick the **published flow** from a list; the flow token is minted on every send. You can
  set the button text, message, header, footer, mode (published/draft), initial screen and initial data.

### List and size conditions

In a Flow Builder condition, the **Value** field now follows the **operator**, not only the field:

- **in list / not in list** — pick **several values** at once; they are stored comma-separated, exactly
  what the engine reads. Before you could only pick one, which made the operator a slower "equals".
- **length greater/less than**, **date within N days**, **date before/after** — go back to **free text**,
  because the compared value is a size, a number of days or a date, not a value of the field.
- **array contains** keeps a single pick: it compares **one** member of the array.

### An invalid delay is now blocked at publish time

A **delay** node with every unit at zero silently waited **1 second**, and a mistyped unit failed the node
only at run time. Both now show up as an error when publishing the flow. A unit holding a variable
(`{{ }}`) is still resolved at run time.

### WhatsApp option lists

A list with more than 10 rows, a title over 24 characters or a description over 72 was refused by WhatsApp
and the message was lost. It is now trimmed to the limit before sending (extra rows are dropped, long text
is cut) and the message goes through.

## Use cases

- Create a contact, chain its id into a deal, then use the deal id in a charge or task.
- Update CRM and tasks from webhook/API data without pinning IDs from another run.
- Stop a critical path when an action produces no effect by enabling strict mode.

## Tips, limits & best practices

- Leaving an optional field empty simply omits it — the action uses its default.
- Prefer **variables** over hard-coded values in titles, descriptions and amounts so the same flow adapts
  to each contact or deal.
- Only fill **Contact** when you really mean to override: inside a conversation-driven flow, leaving it
  empty keeps the conversation's own contact, which is usually the right answer.
- Before mapping custom attributes, confirm they are configured as fields of the target **pipeline** —
  otherwise they are dropped without warning.
- When a later step cannot find the record it expected, look for the previous step's **"Action skipped"**
  warning in the **Steps** tab — the reason is usually right there.
- Turn **strict mode** on only for the nodes where "did nothing" is a real problem, and handle the error
  output with a notification or an alternative path.
- Use the group **search** to jump straight to an event by its label or its technical key.

## Troubleshooting

- If a picker is empty, confirm the module, permission and any dependency selected first.
- If an action is skipped, read its trace reason before changing downstream steps.
- If publish rejects the node, fix the schema field reported by validation; v2 does not accept undeclared fields.

## See also

- [Flow Builder: trigger data, mapping and transformation](/hc/ajuda/articles/automation-flows-flow-builder-dados-e-mapeamento-en)
- [Flow Builder: native actions](/hc/ajuda/articles/automation-flows-flow-builder-acoes-nativas-en)
- [Flow Builder in practice](/hc/ajuda/articles/automation-flows-flow-builder-operacao-en)