> ## Documentation Index
> Fetch the complete documentation index at: https://help.pipelime.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Outreach and AI blocks

> The blocks that send: email, LinkedIn, WhatsApp, Instagram, MercadoLibre, and the AI blocks that decide what to say.

export const Screenshot = ({id, alt, caption, frame = 'browser', url, marks = [], lang = 'en', workspace = 'northwind-outbound'}) => {
  const src = `/images/screenshots/${lang}/${id}.png`;
  const chrome = url ? `app.pipelime.ai/${workspace}${url}` : 'app.pipelime.ai';
  return <figure className={`pl-shot pl-shot--${frame} not-prose`}>
      <div className="pl-shot__frame">
        {frame !== 'bare' && <div className="pl-shot__bar">
            <span className="pl-shot__dots">
              <span className="pl-shot__dot" />
              <span className="pl-shot__dot" />
              <span className="pl-shot__dot" />
            </span>
            <span className="pl-shot__url">{chrome}</span>
          </div>}
        <div className="pl-shot__media">
          <img src={src} alt={alt} loading="lazy" />
          {marks.map(mark => <span key={mark.n} className="pl-shot__mark" style={{
    left: `${mark.x}%`,
    top: `${mark.y}%`
  }} aria-hidden="true">
              {mark.n}
            </span>)}
        </div>
      </div>
      {caption && <figcaption className="pl-shot__caption">{caption}</figcaption>}
    </figure>;
};

Two categories on the blocks palette do the actual talking: **Outreach** sends something on a channel, and **AI** reads or writes the words.

<div className="pl-availability">
  <div className="pl-availability__row">
    <div className="pl-availability__label">Where</div>
    <div className="pl-availability__value"><span className="pl-path">Outreach<span className="pl-path__sep">→</span>Workflow Builder</span></div>
  </div>

  <div className="pl-availability__row">
    <div className="pl-availability__label">Your role needs</div>
    <div className="pl-availability__value">Create access to Workflow Builder <code>create-workflows</code>. Admin and Member have it by default.</div>
  </div>

  <div className="pl-availability__row">
    <div className="pl-availability__label">To create or change</div>
    <div className="pl-availability__value"><code>create-workflows</code> to add one, <code>update-workflows</code> to change one, on top of the permission above.</div>
  </div>

  <div className="pl-availability__note">Not listed in the sidebar today; reachable from the surfaces that link to it, and by URL. If you cannot find this in your sidebar, your workspace may have a custom menu configuration. Contact support and we will check it for you.</div>
</div>

## Outreach blocks

Eleven blocks in **Outreach** act on the lead through a channel. None of them branch: each has exactly one way in and one way out, so anything you want to happen because a message went out (a wait, a stage change, a reaction to a reply) is its own block afterward.

| Block                             | What it does                                                                                                                                                                                                                                                                                               | Needs            |
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| **Send Email**                    | Opens a fresh thread with the lead. It skips the lead if that lead already has any sent message on file, whether from this workflow, another workflow or a campaign, so nobody is cold-emailed twice.                                                                                                      | An email account |
| **Send Follow-up**                | Threads onto the most recent message in the lead's thread with that mailbox and reuses its subject. With no prior thread it sends a fresh email instead of stalling.                                                                                                                                       | An email account |
| **Send Reply**                    | Answers the lead's last incoming message, threaded onto it and reusing its subject. It skips when there is nothing to reply to. Can be saved as a draft for a person to send by hand.                                                                                                                      | An email account |
| **LinkedIn: View Profile**        | Visits the lead's profile, a quiet first touch before connecting.                                                                                                                                                                                                                                          | LinkedIn         |
| **LinkedIn: Connect**             | Sends a connection request, with or without a note.                                                                                                                                                                                                                                                        | LinkedIn         |
| **LinkedIn: Message**             | Sends a direct message to a lead you're already connected to.                                                                                                                                                                                                                                              | LinkedIn         |
| **LinkedIn: Engage with post**    | Likes or comments on the lead's most recent post.                                                                                                                                                                                                                                                          | LinkedIn         |
| **LinkedIn: Withdraw Invitation** | Cancels a connection request that's still pending, the natural move once the lead never accepted.                                                                                                                                                                                                          | LinkedIn         |
| **Send WhatsApp**                 | Messages the lead's phone number on WhatsApp.                                                                                                                                                                                                                                                              | WhatsApp         |
| **Send Instagram DM**             | Messages the lead's Instagram username.                                                                                                                                                                                                                                                                    | Instagram        |
| **Answer MercadoLibre Question**  | Answers the buyer question that started the workflow, using the whole listing (title, spec sheet, description) plus any tone or house rules you add. With no MercadoLibre question trigger upstream it answers the lead's most recent unanswered question instead, and the builder warns you that it will. | MercadoLibre     |

**Send Follow-up** and **Send Reply** carry a second guard of their own: each skips when a sent message already threads onto the message it was about to thread onto. Two enrollments racing on the same lead produce one send, not two.

One more block sits in **Outreach** and is the only one there that branches: **Run Workflow**, which starts a second workflow on the same lead and exits **Started** or **Skipped**. It sends nothing itself, and [CRM and integration blocks](/en/workflows/crm-and-integration-blocks#run-workflow) covers it.

<Note>
  A block that needs LinkedIn, WhatsApp, Instagram or MercadoLibre stays visible in the palette before you've connected one: it shows dimmed, with a badge naming the channel it needs, and clicking it does nothing. That is a different state from a block the engine cannot run, which is dropped from the palette entirely. Two blocks are in that second state today, **Instagram: Reply to Comment** and **Enroll in Campaign**: no executor is registered for either, so they never reach the palette and a workflow that somehow contains one is refused at activation. [Canvas, palette and inspector](/en/workflows/canvas-palette-and-inspector) covers the mechanic, and [Channels overview](/en/channels/overview) covers what unlocks each channel.
</Note>

<Screenshot id="workflows/outreach-and-ai-blocks--channel-blocks" url="/workflows/new" alt="The blocks palette with the Triggers category collapsed so Outreach and AI are in view, every LinkedIn, WhatsApp, Instagram and MercadoLibre block dimmed and carrying a Connect badge" caption="A workspace with no channel connected yet. Connect one and the same cards become usable the next time the palette loads." />

## AI blocks

| Block                    | What it does                                                                                                     | Branches                                    |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| **AI Decision (Branch)** | Answers a question you write, about the lead, and branches on the answer.                                        | Whatever you define, two or more            |
| **AI Classify Message**  | Reads the message that triggered this workflow and branches on its intent.                                       | Whatever you define, two or more            |
| **AI Conversation**      | Holds a back-and-forth with the lead on WhatsApp or email, collecting whatever fields you ask for along the way. | **Completed**, **Incomplete**, **No reply** |
| **AI Qualify Lead**      | Scores the lead against criteria you write and branches on a threshold.                                          | **Qualified**, **Not qualified**            |
| **AI Generate Content**  | Writes copy about the lead and saves it to a variable a later block can use.                                     | None, always continues                      |

The **AI Conversation** block is the deepest of the five, holding a multi-turn conversation and writing custom fields back to the lead. It gets its own page: [The AI Conversation block](/en/workflows/ai-conversation-block).

## Write it yourself, or let the model write it

Most blocks that compose a message start with the same **Message** toggle, between **AI** and **Custom template**. A fresh block starts on **AI**, except **Send WhatsApp** and **Send Instagram DM**, which start on **Custom template**.

In **AI** mode you get one field, **Prompt**. What you write there, plus the lead and company dossier the generator attaches on its own, is what the message gets written from. Switch to **Custom template** and **Prompt** gives way to text you write yourself. On an email block (**Send Email**, **Send Follow-up**, **Send Reply**) that is a **Subject** and a **Body**, on tabs of their own. On **LinkedIn: Message**, **Send WhatsApp** and **Send Instagram DM** it is a single **Message** field, since a DM has no subject line.

**LinkedIn: Connect** works differently: by default it sends a bare connection request with no note at all. Turn on the note and the same AI-or-template choice appears for the note's own text, labelled **Note** rather than **Message**, with a **Note** field in template mode. **Answer MercadoLibre Question** is the other outlier: it has no toggle at all, since it only ever writes with AI, from the buyer's question and the listing.

<Warning>
  An empty message is caught in two places, and the second one is the surprise. The builder reports it as an error on the block and holds **Activate** back, checking whichever field the block's current mode uses. On an email block in **Custom template** mode that check passes as soon as either **Subject** or **Body** has text, so a subject with an empty body activates cleanly and then fails when the workflow reaches the block, because the send path needs a body. See [Validate, test with AI and activate](/en/workflows/validate-test-and-activate).
</Warning>

**Send Email**, **Send Follow-up** and **Send Reply** each carry a **Sender** field and a format choice between **HTML** and **Plain text**. Left on Auto, the first send picks a mailbox and pins it to that lead's run, so the whole conversation stays on one address; it moves to another only if the pinned one is gone, archived or inactive, never for a passing throttle. Name a specific account instead and it is used as named and never switched. **Send Email** alone adds an open and click tracking toggle, on by default.

**Send Reply** can also be saved as a draft, with the toggle reading `Save as draft for manual review`. The reply is still written and stored against the lead's thread, but it is stored as a draft rather than as a scheduled send, and the cron that dispatches workflow email only picks up scheduled ones. It waits for a person.

<Screenshot id="workflows/outreach-and-ai-blocks--send-email-inspector" url="/workflows/new" alt="A freshly added Send Email block's inspector, showing Sender set to Auto, the Message toggle on AI with an empty Prompt field, Plain text selected as the format, the tracking toggle on, and a disabled Test generation button underneath" caption="Everything here is what a Send Email block starts with. Nothing is required except a prompt or a template body, whichever mode you're in." />

## Test what the AI would write

A **Test generation** button sits directly under the prompt field, on any block whose message actually gets generated. It does not run the block. It asks for a sample of what the prompt would produce, written for a real lead pulled from your workspace, or for a built-in demo persona if the workspace has no leads yet. Nothing is sent and nothing is saved.

| Block                                                                                         | Gets Test generation? | Notes                                                             |
| --------------------------------------------------------------------------------------------- | --------------------- | ----------------------------------------------------------------- |
| **Send Email**, **Send Follow-up**, **Send Reply**                                            | Yes                   | Only while in **AI** mode                                         |
| **LinkedIn: Message**                                                                         | Yes                   | Only while in **AI** mode                                         |
| **LinkedIn: Connect**                                                                         | Yes                   | Only with the note turned on, and only while in **AI** mode       |
| **Send WhatsApp**, **Send Instagram DM**                                                      | Yes                   | Start on **Custom template**, so switch to **AI** first           |
| **Answer MercadoLibre Question**                                                              | Yes                   | Works even with nothing typed. The buyer's question is the prompt |
| **AI Generate Content**                                                                       | Yes                   | Always AI, so it's always available                               |
| **AI Conversation**                                                                           | Yes                   | Previews only the opening message, not the whole conversation     |
| **LinkedIn: View Profile**, **LinkedIn: Engage with post**, **LinkedIn: Withdraw Invitation** | No                    | Nothing gets written, so there's nothing to test                  |
| **AI Decision (Branch)**, **AI Classify Message**, **AI Qualify Lead**                        | No                    | These decide something, they don't write a message                |

The button stays disabled until the block's own prompt field has text in it, and hovering it says so. On **AI Conversation** that field is the conversation goal. **Answer MercadoLibre Question** is the exception: the buyer's own question already is the prompt, so it tests from empty. A result stays on screen while you regenerate, so nothing flashes away mid-run.

**Send Reply**'s test adds a control the others don't: a toggle to simulate the lead as **Interested**, raising an **Objection**, or **Not interested**, with the simulated inbound message shown alongside the draft it produced. **Send Follow-up**'s test notes that it's simulating a follow-up where the lead hasn't replied yet. **Answer MercadoLibre Question**'s test shows the real buyer question it sampled to answer, since the generated reply reads as random without it.

## The AI blocks that branch

**AI Decision (Branch)** and **AI Classify Message** both hand back one of your own branches, not a fixed set the product chose for you. **AI Decision (Branch)** starts with two, **YES** and **NO**; **AI Classify Message** starts with four, **Interested**, **Objection**, **Not now** and **Not interested**. Add, rename or remove one and the block's exits on the canvas update to match, since the exits are drawn straight from your list and there is no catch-all "anything else" exit beside them. Every branch needs its own label and its own value. The model is held to the exact set of values you type, so an answer that fits none of them is not something it can produce. A single branch doesn't validate, and two branches sharing a label or a value don't either.

The two blocks differ in what they read. **AI Decision (Branch)** asks a question you write, against a context picker: leave it empty and the model sees everything on file for the lead (profile, company, every conversation across every channel, activity, notes), or narrow it to specific dossier sections or single fields. **AI Classify Message** has no such picker: its input is always the message that triggered the workflow, read against the rest of the lead's history for background. With no message to classify, the run ends there before any model call is made. With `Skip automatic / out-of-office replies` on, the classification still costs a model call, and an out-of-office, a bounce or a no-reply autoresponder then ends the run rather than being pushed down one of your real intents.

<Screenshot id="workflows/outreach-and-ai-blocks--ai-decision" url="/workflows/new" alt="An AI Decision block's inspector open on the canvas, its Question field filled in and three custom branches typed into the branch editor below it, with the matching three colored branch rows visible on the block's canvas card" caption="Two branches to start; add, rename or remove them and the block's own exits on the canvas follow along." />

## AI Qualify Lead

Write your qualification criteria in plain language and the block scores the lead from 0 to 100 against it, using the same context picker as **AI Decision (Branch)**. The score decides the branch: **Qualified** at or above the threshold you set, **Not qualified** below it.

## AI Generate Content

Writes copy from a prompt you give it and saves the result to a variable name you choose, so a later block can drop it in with a merge tag. It always continues; there's no branch to wire. Unlike the two blocks above it has no context picker: it always writes against the full lead dossier. The variable name keeps only letters, numbers and underscores and turns anything else into an underscore, and a name starting with an underscore, or one that is `ai` or `trigger`, gets prefixed so it cannot overwrite the run's own bookkeeping. See [Merge variables and lead fields](/en/workflows/merge-variables-and-lead-fields) for how to reference it once it's saved.

The prompt on this block, on **AI Decision (Branch)** and on **AI Qualify Lead** is a required field, so the builder blocks activation while one is blank. If a run ever does reach one empty, the block fails there rather than quietly writing nothing. **AI Generate Content** treats an empty answer from the model differently: it retries, and only fails the run once the retries run out.

## Related

<CardGroup cols={2}>
  <Card title="The AI Conversation block" icon="messages-square" href="/en/workflows/ai-conversation-block">
    The one AI block that holds a real back-and-forth and collects fields as it goes.
  </Card>

  <Card title="How a workflow's sends are scheduled" icon="clock" href="/en/workflows/how-sends-are-scheduled">
    Why a send waits on a busy account or a holiday, before any of these blocks fire.
  </Card>

  <Card title="Merge variables and lead fields" icon="braces" href="/en/workflows/merge-variables-and-lead-fields">
    Every value you can drop into a prompt, a template or a condition, by its exact name.
  </Card>

  <Card title="Agent instructions" icon="book-open" href="/en/ai-agents/agent-instructions">
    The other place AI writes your outreach: per-channel instructions that apply across a whole agent, not one block.
  </Card>
</CardGroup>
