> ## 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.

# Logic, Timing and Finish blocks

> Branch on what you know, wait for time or for a reply, and end a flow deliberately.

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>;
};

Logic blocks send a lead down one path or another. Timing blocks decide when a lead moves on: after a span, after something happens, or a counted number of times around a cycle. Finish blocks end its run in this workflow on purpose.

<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>

## The full block catalog

These ten blocks sit inside the builder's full catalog, reproduced below so you can see them next to everything else on the palette. [Triggers reference](/en/workflows/triggers-reference), [Outreach and AI blocks](/en/workflows/outreach-and-ai-blocks), [Find & Enrich blocks](/en/workflows/find-and-enrich-blocks) and [CRM and integration blocks](/en/workflows/crm-and-integration-blocks) cover the rest of it. This page covers three of the ten sections below: **Logic**, **Timing** and **Finish**.

### Triggers

| Block                              | What it does                                                                                                                | Branches | Needs                    |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------ |
| **New Lead Ready**                 | Starts when a lead is enriched and ready for outreach.                                                                      | -        | -                        |
| **On a Date or Schedule**          | Starts on a date you pick, or on a repeating schedule, for the leads you choose.                                            | -        | -                        |
| **Time Since Event**               | Starts a set time after (or before) a date on the lead: created, converted, meeting scheduled, return date.                 | -        | -                        |
| **Tag Added**                      | Starts the moment a tag lands on the lead: tagged by hand, by an import, by a channel or by another workflow.               | -        | -                        |
| **Reply Received**                 | Starts when the lead replies by email or LinkedIn.                                                                          | -        | -                        |
| **Email Opened**                   | Starts when the lead opens an email you sent.                                                                               | -        | -                        |
| **Link Clicked**                   | Starts when the lead clicks a tracked link in your email.                                                                   | -        | -                        |
| **LinkedIn Invite Accepted**       | Starts when the lead accepts your LinkedIn invitation.                                                                      | -        | -                        |
| **Meeting Booked**                 | Starts when the lead books a meeting: through your scheduler, a connected calendar, or a confirmation we detect in a reply. | -        | -                        |
| **Website Visited**                | Starts when a tracked lead visits your website. Anonymous visits we can only resolve to a company don’t start a run.        | -        | -                        |
| **WhatsApp Received**              | Starts when the lead sends you a WhatsApp message.                                                                          | -        | a connected whatsapp     |
| **Instagram DM Received**          | Starts when the lead sends you an Instagram DM.                                                                             | -        | a connected instagram    |
| **Instagram Comment Received**     | Starts when someone comments on one of your Instagram posts. Comments are checked periodically: not instant.                | -        | a connected instagram    |
| **MercadoLibre Question Received** | Starts when a buyer asks a question on one of your MercadoLibre listings.                                                   | -        | a connected mercadolibre |
| **Manual / Test**                  | Run the workflow on a chosen lead: handy for testing.                                                                       | -        | -                        |

### Outreach

| Block                             | What it does                                                                                                                                                                | Branches              | Needs                    |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------------------------ |
| **Send Email**                    | First outbound touch: starts a new thread and marks the lead Contacted.                                                                                                     | -                     | -                        |
| **Send Follow-up**                | Automatic bump on the same thread when the lead hasn’t replied. Stops after a few attempts.                                                                                 | -                     | -                        |
| **Send Reply**                    | Responds to the lead’s incoming reply. Respects out-of-office and can be saved as a draft.                                                                                  | -                     | -                        |
| **LinkedIn: View Profile**        | Visit the lead’s LinkedIn profile: the natural first touch that warms up the account before connecting.                                                                     | -                     | a connected linkedin     |
| **LinkedIn: Connect**             | Send a connection request to the lead on LinkedIn.                                                                                                                          | -                     | a connected linkedin     |
| **LinkedIn: Message**             | Send a direct message to the connected lead.                                                                                                                                | -                     | a connected linkedin     |
| **LinkedIn: Engage with post**    | React to or comment on the lead’s most recent post (warm-up).                                                                                                               | -                     | a connected linkedin     |
| **LinkedIn: Withdraw Invitation** | Cancel the lead’s still-pending connection request: the natural move when they never accepted.                                                                              | -                     | a connected linkedin     |
| **Send WhatsApp**                 | Message the lead on WhatsApp (uses the lead’s phone).                                                                                                                       | -                     | a connected whatsapp     |
| **Send Instagram DM**             | Message the lead on Instagram (uses the lead’s Instagram username).                                                                                                         | -                     | a connected instagram    |
| **Instagram: Reply to Comment**   | Reply to the comment that triggered this workflow, on your own post.                                                                                                        | -                     | a connected instagram    |
| **Answer MercadoLibre Question**  | AI answers the buyer question that started this workflow, using the complete listing: title, price, spec sheet, description: plus your instructions. Posts on MercadoLibre. | -                     | a connected mercadolibre |
| **Enroll in Campaign**            | Hand the lead off to an existing campaign.                                                                                                                                  | -                     | -                        |
| **Run Workflow**                  | Start another workflow on this lead as a reusable sub-flow. It runs on its own; this one carries straight on.                                                               | `Started` · `Skipped` | -                        |

### AI

| Block                    | What it does                                                                                                                               | Branches                                | Needs |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------- | ----- |
| **AI Decision (Branch)** | The AI answers a question about the lead; each answer is a branch.                                                                         | -                                       | -     |
| **AI Classify Message**  | Read the message that triggered this workflow and branch on its intent.                                                                    | -                                       | -     |
| **AI Conversation**      | The AI holds a natural conversation with the lead: warming them up, answering questions and gathering any fields you define along the way. | `Completed` · `Incomplete` · `No reply` | -     |
| **AI Qualify Lead**      | Score the lead against your criteria and branch on the result.                                                                             | `Qualified` · `Not qualified`           | -     |
| **AI Generate Content**  | Generate copy about the lead for later nodes.                                                                                              | -                                       | -     |

### Find & Enrich

| Block              | What it does                                                                                       | Branches                      | Needs |
| ------------------ | -------------------------------------------------------------------------------------------------- | ----------------------------- | ----- |
| **Enrich Company** | Scrape the lead’s company website and extract emails, phones, socials, description and logo.       | `Enriched` · `No data`        | -     |
| **Find Employees** | Find people at the lead’s company and add them as new leads. The current lead continues unchanged. | `Found people` · `None found` | -     |
| **Find Email**     | Look up the lead’s work email, job title, LinkedIn and phone.                                      | `Found` · `Not found`         | -     |
| **Verify Email**   | Check that the lead’s email is deliverable before you send.                                        | `Valid` · `Risky` · `Invalid` | -     |
| **Find Phone**     | Reveal the lead’s phone number for WhatsApp or calling.                                            | `Found` · `Not found`         | -     |

### Logic

| Block         | What it does                                             | Branches     | Needs |
| ------------- | -------------------------------------------------------- | ------------ | ----- |
| **If / Else** | Branch on a lead or company attribute.                   | `Yes` · `No` | -     |
| **Switch**    | Route the lead down a branch based on a field’s value.   | -            | -     |
| **A/B Split** | Randomly split leads into weighted variants for testing. | -            | -     |

### Timing

| Block                   | What it does                                                     | Branches                 | Needs |
| ----------------------- | ---------------------------------------------------------------- | ------------------------ | ----- |
| **Wait / Delay**        | Pause the lead’s journey for a set time.                         | -                        | -     |
| **Wait for Reply**      | Wait for the lead to respond, then branch on reply vs no-reply.  | `Replied` · `No reply`   | -     |
| **Business-Hours Gate** | Hold the lead until the next business-hours window.              | -                        | -     |
| **Loop**                | Repeat the connected steps a set number of times, then continue. | `Repeat` · `Max reached` | -     |

### CRM

| Block                    | What it does                                 | Branches | Needs |
| ------------------------ | -------------------------------------------- | -------- | ----- |
| **Change Lead Stage**    | Move the lead to a different pipeline stage. | -        | -     |
| **Tag Lead**             | Add or remove tags on the lead.              | -        | -     |
| **Set Possibility Rate** | Set the lead’s likelihood-to-convert score.  | -        | -     |
| **Pause Automation**     | Stop automated outreach to this lead.        | -        | -     |

### Integrations

| Block               | What it does                                                                                                            | Branches               | Needs                                                                     |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------- | ------------------------------------------------------------------------- |
| **Notify on Slack** | Post a message to your team in Slack.                                                                                   | -                      | a connected slack                                                         |
| **Send to CRM**     | Create or update the lead in one of your connected integrations (HubSpot, Salesforce, Odoo, Kommo, HeyReach, Webhook…). | `Sent` · `Rejected`    | a connected hubspot or salesforce or odoo or kommo or heyreach or webhook |
| **Send Webhook**    | Send the lead to any HTTP endpoint: a saved connector, or a one-off URL with your own fields.                           | `Delivered` · `Failed` | -                                                                         |

### Finish

| Block              | What it does                                | Branches | Needs |
| ------------------ | ------------------------------------------- | -------- | ----- |
| **Goal Reached**   | Mark the campaign goal as reached and stop. | -        | -     |
| **Mark Converted** | Mark the lead as converted (won) and stop.  | -        | -     |
| **Stop / Exit**    | Remove the lead from the workflow.          | -        | -     |

### Utility

| Block    | What it does                     | Branches | Needs |
| -------- | -------------------------------- | -------- | ----- |
| **Note** | A sticky note for documentation. | -        | -     |

## Logic blocks

Three blocks decide which way a lead goes, based on something already true about them: an attribute on the lead or their company, or a weighted coin flip.

### If / Else

**If / Else** compares one attribute against a value you set, then branches **Yes** or **No**. The attribute comes from the builder's shared lead catalog ([Merge variables and lead fields](/en/workflows/merge-variables-and-lead-fields) lists it in full): the lead's identity and contact details, lifecycle fields like **Lead · stage**, location, their company's profile and scores, and the lead's tags.

<Screenshot id="workflows/logic-timing-and-finish-blocks--if-else" url="/workflows/new" alt="The If/Else inspector: a Lead field select, a Condition select defaulting to equals, a Value box, and the Yes and No branch handles on the block itself" caption="Yes and No are the only two exits an If/Else ever has." />

Which conditions you can pick from depends on what kind of attribute you chose. Every scalar attribute, a name, a stage, a score, offers the same seven:

| Condition                              | True when                                                                                       |
| -------------------------------------- | ----------------------------------------------------------------------------------------------- |
| **equals**                             | The value matches, case-insensitive. Two numbers compare as numbers, not text.                  |
| **does not equal**                     | It doesn't match, or the lead has no value there at all.                                        |
| **contains**                           | The value contains your text, case-insensitive. Leave the value blank and nothing ever matches. |
| **is greater than** / **is less than** | Compared as numbers when both sides look numeric, as text otherwise.                            |
| **is empty** / **is not empty**        | Nothing there at all, or a blank string. A literal 0 counts as a value, not empty.              |

A lead with nothing in that attribute satisfies exactly two of those conditions: **is empty** and **does not equal**. Every other one reads a missing value as false, **contains** and the two comparisons included.

Tags are the one attribute that's a set rather than a single value, so they get their own five conditions:

| Condition                         | True when                                             |
| --------------------------------- | ----------------------------------------------------- |
| **includes any of**               | The lead carries at least one of the tags you picked. |
| **includes all of**               | The lead carries every tag you picked.                |
| **does not include**              | The lead carries none of the tags you picked.         |
| **has no tags** / **has any tag** | The lead's tag set is empty, or it isn't.             |

Tags themselves are picked from your workspace's real list, never typed, so a condition can't be armed with a name that will silently never match anything. When the attribute you chose maps to a fixed set of values instead, like **Lead · stage**, the value box becomes a picklist of exactly those values, for the same reason.

### Switch

**Switch** reads one attribute (tags aren't offered here: a lead can carry several, and a switch needs a single value to compare against) and routes it down whichever case's value matches, case-insensitively. Each case you add becomes its own labeled exit on the canvas.

If nothing matches, there's no default branch to fall back on: the run ends there. Build a case for every value you actually expect if that isn't what you want. The builder also requires at least two cases, each with a distinct label and a distinct value, before it lets you activate: two cases sharing a value would collapse into one branch and leave the other permanently unreachable.

<Note>
  That "the run just ends" behavior isn't specific to Switch. Any branch on any block, left unconnected to anything on the canvas, ends a lead's run the moment they take it, and the enrollment is marked Completed, the same status reaching **Goal Reached** or **Mark Converted** leaves it in.
</Note>

### A/B Split

**A/B Split** sends a lead down one of several variants at random, weighted by the percentage you set on each. The builder requires at least two variants whose weights add up to 100 before you can activate. The engine underneath is more forgiving of a hand-edited graph: positive weights still pick proportionally even if they don't total exactly 100, and if every weight comes out to 0, it falls back to picking evenly rather than getting stuck.

## Timing blocks

Four blocks decide when a lead moves on. Three of them park the run where it is: for a fixed span, until a reply arrives, or until a daily window opens. The fourth, **Loop**, never waits at all; it counts trips around a cycle and branches on the count.

### Wait / Delay

**Wait / Delay** pauses for a fixed span: an amount and a unit, Minutes, Hours, Days or Weeks. It's a plain delay, not a clock. It doesn't know your timezone or your sending hours; it just adds that span to the moment a lead reaches it. Set the amount to 0 and it does nothing, the lead moves straight through. A lead that passes through the same Wait / Delay twice, inside a loop, waits the full span again each time.

### Wait for Reply

**Wait for Reply** pauses until a lead responds, or until a deadline passes, then branches **Replied** or **No reply**. Which response counts is one of five: **Email reply**, **WhatsApp reply**, **Instagram reply**, **LinkedIn invite accepted** or **MercadoLibre question**, defaulting to **Email reply**. The deadline defaults to 4 days.

<Screenshot id="workflows/logic-timing-and-finish-blocks--wait-for-reply" url="/workflows/new" alt="The Wait for Reply inspector: a Wait for select defaulting to Email reply, a Give up after duration defaulting to 4 days, and the Replied and No reply branch handles on the block" caption="Only these five events resume the wait. An email open, a link click and a booked meeting are separate triggers elsewhere, not a reply this block recognizes." />

An event this block doesn't know how to resume on, or a run with no lead to wait on, fails straight to **No reply** rather than waiting forever.

### Business-Hours Gate

**Business-Hours Gate** doesn't wait a fixed span: it holds a lead until a time-of-day window opens. Reach it inside the window, in the timezone you set, and it passes straight through; reach it outside, and it waits until the window next opens. A window whose end is earlier than its start is read as an overnight one, running past midnight and closing the following morning.

<Screenshot id="workflows/logic-timing-and-finish-blocks--wait" url="/workflows/new" alt="The Business-Hours Gate inspector: a time window defaulting to 09:00 to 17:00, and a Timezone select showing UTC" caption="A new gate defaults to UTC, not your workspace's own timezone." />

A block you just dropped onto the canvas defaults its timezone to **UTC**, not **Auto · workspace timezone**. That's not an oversight: the product keeps it that way on purpose, because switching the default would silently move every gate already live, including runs already in progress. Pick **Auto · workspace timezone** yourself if you want this one to follow your workspace's own clock instead. Either way, the gate only ever checks the time of day: there's no day-of-week setting, so it doesn't skip weekends by itself. An incomplete or invalid window never traps a lead; it fails open and lets them straight through instead.

### Loop

**Loop** repeats whatever you wire back into it, up to a maximum you set, then continues. A new block starts at 3, and the count has to be at least 1. Wire its **Repeat** exit back to an earlier step to close the cycle; wire **Max reached** onward to whatever should happen once the count runs out. The canvas card shows the cap on its own, "Up to 3 times" at the default, so you can read it without opening the inspector.

<Screenshot id="workflows/logic-timing-and-finish-blocks--loop" url="/workflows/new" alt="A Loop block on the canvas, its Repeat exit wired back into an earlier AI Decision (Branch) block on an edge labeled Re-evaluate, and its Max reached exit leading to a Stop / Exit block on an edge labeled Max rounds" caption="What makes this cycle legal is the Repeat edge: it is the one that closes the loop, so the count bounds it." />

The count resets once it's used up, so a Loop nested inside another cycle starts counting fresh every time the outer cycle re-enters it.

<Warning>
  A cycle with nothing in it that can ever stop it blocks activation outright. Two things count as a stop: a **Wait / Delay**, **Wait for Reply**, **Business-Hours Gate** or **AI Conversation** block sitting anywhere in the cycle, or a **Loop** whose **Repeat** edge is the one that closes it. A Loop that the cycle only passes through by way of **Max reached** does not bound anything. The validation panel says so in these words: "This loop never exits — add a Loop block with a max count (or a wait) so it can end." It's the single most common way to build a flow that can't be turned on.
</Warning>

Even a properly bounded loop still adds one warning to the validation panel, worded just "The workflow contains a loop.": the checker flags every cycle it finds, on principle, whether or not something bounds it. A warning never blocks Activate; only an error does.

As a last resort against a hand-edited graph that still finds a way around all of this, every enrollment carries a hard lifetime cap of 500 steps. A lead that hits it stops there and the enrollment is marked Failed. It's a runaway backstop, not a number to design a flow around.

## Finish blocks

Three blocks end a run on purpose. None of them has an outgoing branch: reaching one is always the last thing that happens to a lead in this workflow.

### Goal Reached

**Goal Reached** records which outcome this run achieved: **Meeting booked**, **WhatsApp conversation**, **Website link visited** or **Custom goal**. It feeds the conversion rate a workflow reports; it doesn't touch the lead's stage or any other field on its own.

### Mark Converted

**Mark Converted** sets the lead's stage to Converted, unless it's Converted already, then stops. Setting the stage this way triggers the same side effects a manual stage change does anywhere else in the product, a CRM push, the converted timestamp, rather than a separate mechanism just for this block.

### Stop / Exit

**Stop / Exit** removes the lead from this run. Whatever you type as the reason is stored with that step, for your own records; it's never sent to the lead. It is the one Finish block that does not leave the enrollment Completed: a lead that reaches it is marked Exited instead.

## Related

<CardGroup cols={2}>
  <Card title="Validate, test with AI and activate" icon="circle-check" href="/en/workflows/validate-test-and-activate">
    Every error and warning the validation panel can show, and what turns Activate on.
  </Card>

  <Card title="Enrollments and the lead journey" icon="route" href="/en/workflows/enrollments-and-lead-journey">
    Follow one lead through a workflow: where it is now, which branch it took, and why it stopped.
  </Card>

  <Card title="How a workflow's sends are scheduled" icon="hourglass" href="/en/workflows/how-sends-are-scheduled">
    Why a send waits: a busy mailbox, a schedule window, a resting day or a holiday, and how long it keeps trying.
  </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 condition or a message, and the exact name to pick or type.
  </Card>
</CardGroup>
