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

# The builder: canvas, blocks palette and inspector

> Add and connect blocks, configure one in the inspector, and read what the toolbar is telling you.

export const Kbd = ({children}) => <kbd className="pl-kbd">{children}</kbd>;

export const UiPath = ({children}) => {
  const parts = String(children).split(/\s*(?:→|>)\s*/).filter(Boolean);
  return <span className="pl-path">
      {parts.map((part, index) => <span key={`${index}-${part}`}>
          {index > 0 && <span className="pl-path__sep">→</span>}
          {part}
        </span>)}
    </span>;
};

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

By the end you'll be able to add a block by hand, wire it into the flow, configure it in the inspector, and read what the toolbar, the palette and a disabled block are each telling you.

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

## Before you begin

* You need the `update-workflows` permission to save or activate anything you build here. Without it the canvas, palette and inspector all still work; **Save** and **Activate** just stay disabled and say why on hover.
* This assumes a workflow is already open, new or existing, from <UiPath>Outreach → Workflows</UiPath>.

## Steps

<Steps>
  <Step title="Open a workflow and read the toolbar">
    Opening a workflow, new or existing, drops you onto a full-bleed panel: no breadcrumb, no
    footer, the canvas fills the space below the header on its own. The toolbar sits across the
    top. From the left: a back arrow, the workflow's name (1), and the **Saved** / **Unsaved** /
    **Saving…** status right next to it (2). On the right: **Undo**, **Redo**, a full screen
    toggle, a validation pill (3) that reads **Valid** or counts what it found, **Save**, and
    **Activate** / **Deactivate** (4).

    <Screenshot id="workflows/canvas-palette-and-inspector--canvas" url="/workflows/12" alt="The workflow builder's toolbar across the top of a full-bleed canvas, with the blocks palette open on the left and a small graph of connected blocks in the middle" caption="No breadcrumb, no footer: the canvas fills everything below the header while you're in here." marks={[{ n: 1, x: 14, y: 10 }, { n: 2, x: 27, y: 10 }, { n: 3, x: 74, y: 10 }, { n: 4, x: 94, y: 10 }]} />
  </Step>

  <Step title="Add a block from the palette">
    The palette on the left lists every block the engine can run, grouped into categories:
    **Triggers**, **Outreach**, **AI**, **Find & Enrich**, **Logic**, **Timing**, **CRM**,
    **Integrations**, **Finish** and **Utility**. Click a category's header to collapse it out of
    the way.

    Type into the search field and it filters every category at once, matching a block's name or
    its description. Drag a card onto the canvas, or click it and it drops in the middle of what
    you're currently looking at.

    The palette waits on one thing before it draws anything: which block types the engine can
    actually run right now. A block still being built never appears here at all, in any category.
    That's different from a block that exists but whose integration you haven't connected,
    covered in the last step below.

    <Screenshot id="workflows/canvas-palette-and-inspector--palette-search" url="/workflows/12" alt="The blocks palette with a search term typed into its search field, showing a filtered list of matching cards under their categories" caption="Search matches a block's name and its description, across every category at once." marks={[{ n: 1, x: 15, y: 16 }]} />
  </Step>

  <Step title="Connect it to the flow">
    Drag from the small circle on the right edge of a block onto another block's left edge to
    wire them directly. Drop that same connection on empty canvas instead, and a small menu opens
    offering the blocks that usually come next after the one you started from, plus a search box
    for anything else. Whatever you pick gets added and wired in right where you let go.

    That suggestion list only ever offers a block you could use immediately: nothing still being
    built, nothing gated on a connection you don't have, and never another trigger.
  </Step>

  <Step title="Configure it in the inspector">
    Click a block on the canvas and a panel opens on the right, the inspector. It exists only
    while a block is selected: click the empty canvas and it closes again. Fields are listed under
    the block's name and description; some blocks group a few of them under their own labeled
    section.

    Take a fresh **Send Email** block as an example. Its first field is **Sender**, set to rotate
    across your email accounts unless you pick one by name, then a **Message** toggle between
    **AI** and **Custom template**. A new block starts on **AI**, which shows a **Prompt** field:
    what you write there, plus the full lead and company record, is what gets sent. Switch to
    **Custom template** and **Prompt** is replaced by a subject and body you write yourself.

    A block that writes its message with AI gets a **Test generation** button directly under its
    prompt field, which generates a live sample without leaving the canvas. On **Send Email** it
    stays disabled until you've written a **Prompt**.

    The header's expand icon opens the same fields larger, in a dialog; it's the same live data
    either way, so closing it doesn't discard or apply anything separately. The footer holds
    **Duplicate** and **Delete**. **Duplicate** is the one that's sometimes disabled, on a block
    the graph can only ever hold one of, like **Manual / Test**.

    <Screenshot id="workflows/canvas-palette-and-inspector--inspector" url="/workflows/12" alt="The inspector panel open on a Send Email block: a Message toggle set to AI, a Prompt field below it, and a Test generation button under that" caption="A fresh Send Email block starts in AI mode. Switching it to Custom template swaps the Prompt field for a subject and body you write yourself." marks={[{ n: 1, x: 82, y: 22 }, { n: 2, x: 82, y: 38 }, { n: 3, x: 82, y: 56 }]} />
  </Step>

  <Step title="Connect an integration if a block asks for one">
    Some blocks need an account connected before they can be used at all. The five LinkedIn
    action blocks (**LinkedIn: View Profile**, **LinkedIn: Connect**, **LinkedIn: Message**,
    **LinkedIn: Engage with post** and **LinkedIn: Withdraw Invitation**) need a LinkedIn account;
    the **LinkedIn Invite Accepted** trigger does not. Every WhatsApp, Instagram and MercadoLibre
    block needs its own connected account, trigger and action alike. **Notify on Slack** needs a
    Slack connection, and **Send to CRM** needs at least one of HubSpot, Salesforce, Odoo, Kommo,
    HeyReach or a webhook connector.

    Until that connection exists, the block stays right where it is in its category, so you know
    it's there, but dimmed and impossible to drag: a small badge names what it needs, and the
    tooltip repeats the same thing. On a block that accepts any of several connections, like
    **Send to CRM**, the badge names only the first of them. Connect the account it's asking for
    and the same card becomes usable the next time the palette loads. LinkedIn, WhatsApp,
    Instagram and MercadoLibre each have their own setup screen; a CRM or webhook connector lives
    under <UiPath>Integrations → Apps & CRM</UiPath>.

    This is a different situation from a block that hasn't shipped yet: that one is left out of
    the palette completely instead of shown disabled, because a workflow holding it would be
    rejected the moment you tried to turn it on.

    <Screenshot id="workflows/canvas-palette-and-inspector--connect-block" url="/workflows/12" alt="A palette card shown dimmed, with a small badge naming the integration it needs and a tooltip repeating what unlocks it" caption="This is the only kind of disabled block you can do anything about yourself. One the engine can't run yet is left out of the palette entirely." marks={[{ n: 1, x: 22, y: 30 }]} />
  </Step>
</Steps>

## What happens next

<Check>
  Everything you just did, adding a block, wiring it up, editing its fields, deleting it, lives
  only in the browser until you press **Save** (or <Kbd>⌘S</Kbd> / <Kbd>Ctrl+S</Kbd>): the status
  next to the name flips from **Unsaved** to **Saved**, and a brand-new workflow gets its own URL
  at that moment.
</Check>

**Undo** and **Redo** cover changes to the shape of the graph: adding, moving, connecting,
deleting and duplicating blocks. Editing a field in the inspector does not add a step of its own,
renaming the workflow is not undoable at all, and the history is capped, so the oldest steps drop
off on a long editing session.

Leaving with something unsaved raises a warning first, whichever way you try to leave: the back
arrow offers **Keep editing**, **Discard changes** or **Save and leave**; closing or reloading the
tab raises the browser's own prompt instead.

Saving on its own changes nothing about whether the workflow runs.
[Validate, test with AI and activate](/en/workflows/validate-test-and-activate) covers turning it
on.

## Troubleshooting

<AccordionGroup>
  <Accordion title="A block won't drag onto the canvas">
    A block still being built is left out of the palette entirely, so if you can see the card at
    all, it's disabled for a simpler reason: an integration it needs isn't connected yet. Hover it
    for exactly what it's waiting on, connect that account, and it becomes draggable the next time
    the palette loads.

    A card that drags but never lands is a different case. **Manual / Test** is limited to one per
    workflow, so dropping a second one does nothing at all, with no message.
  </Accordion>

  <Accordion title="Test generation stays disabled">
    The button needs a prompt to work from, and the tooltip on it says so. Type something into
    **Prompt** and it enables.

    If there is no **Test generation** button at all, the block is not in AI mode. **Send
    WhatsApp** and **Send Instagram DM** start on **Custom template**, and the button only appears
    once you switch **Message** to **AI**.
  </Accordion>

  <Accordion title="Save and Activate are greyed out for me">
    Three different things grey these out. **Save** is inert while there is nothing to save, so it
    comes back the moment you change something. **Activate** is inert while validation is counting
    errors, and its tooltip tells you to fix them first; warnings on their own don't block it. If
    both stay dead whatever you do, your role doesn't hold the `update-workflows` permission;
    hovering either button says so, and a workspace admin can grant it.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Triggers reference" icon="zap" href="/en/workflows/triggers-reference">
    Every way a lead can enter a workflow, and the fields each trigger takes.
  </Card>

  <Card title="Outreach and AI blocks" icon="send" href="/en/workflows/outreach-and-ai-blocks">
    The blocks that send something (email, LinkedIn, WhatsApp, Instagram, MercadoLibre), and the
    AI blocks that decide what to say.
  </Card>

  <Card title="Validate, test with AI and activate" icon="circle-check" href="/en/workflows/validate-test-and-activate">
    Read the validation panel, preview what the AI would write, and turn the flow on.
  </Card>

  <Card title="Workflow troubleshooting" icon="life-buoy" href="/en/workflows/troubleshooting">
    A block that is missing, a workflow that will not activate, a lead that has not moved: what
    each one actually means.
  </Card>
</CardGroup>
