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

# Run a workflow from chat

> Trigger a saved workflow from a ModuleX chat and watch it run live: send your inputs as a message, follow each step as it happens, answer any approval the run asks for, and read the result inline.

export const MediaEmbed = ({id, type = 'screenshot', caption = '', ext, ratio = '16 / 9'}) => {
  const isVideo = type === 'video' || type === 'app_video';
  const resolvedExt = ext || (isVideo ? 'mp4' : type === 'screenshot' ? 'webp' : 'svg');
  const src = 'https://media.modulex.dev/' + id + '.' + resolvedExt;
  const [status, setStatus] = useState('loading');
  const [isDev, setIsDev] = useState(false);
  const [inView, setInView] = useState(false);
  const boxRef = useRef(null);
  useEffect(() => {
    if (typeof window === 'undefined') return;
    const h = window.location.hostname;
    setIsDev(h === 'localhost' || h === '127.0.0.1' || h.endsWith('.mintlify.app'));
  }, []);
  useEffect(() => {
    if (inView) return;
    if (typeof IntersectionObserver === 'undefined') {
      setInView(true);
      return;
    }
    const el = boxRef.current;
    if (!el) return;
    const io = new IntersectionObserver(entries => {
      if (entries.some(e => e.isIntersecting)) {
        setInView(true);
        io.disconnect();
      }
    }, {
      rootMargin: '300px'
    });
    io.observe(el);
    return () => io.disconnect();
  }, [inView]);
  if (status === 'missing') {
    if (!isDev) return null;
    return <div style={{
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'center',
      gap: '0.4rem',
      padding: '1rem 1.25rem',
      margin: '1.25rem 0',
      width: '100%',
      aspectRatio: ratio,
      boxSizing: 'border-box',
      border: '1px dashed rgba(128,128,128,0.45)',
      borderRadius: '0.75rem',
      background: 'rgba(128,128,128,0.06)',
      color: 'currentColor',
      fontSize: '0.85rem',
      lineHeight: 1.45
    }}>
        <div style={{
      display: 'flex',
      alignItems: 'center',
      gap: '0.5rem',
      opacity: 0.75
    }}>
          <span aria-hidden="true">🎬</span>
          <code style={{
      fontSize: '0.75rem'
    }}>{id}</code>
          <span style={{
      fontSize: '0.65rem',
      textTransform: 'uppercase',
      letterSpacing: '0.04em',
      padding: '0.1rem 0.4rem',
      borderRadius: '0.4rem',
      background: 'rgba(128,128,128,0.18)'
    }}>
            {type}
          </span>
        </div>
        <div style={{
      opacity: 0.9
    }}>{caption || 'Media not uploaded yet.'}</div>
        <div style={{
      fontSize: '0.7rem',
      opacity: 0.5
    }}>
          Upload to R2 as <code>{id}.{resolvedExt}</code> — preview only, hidden in production.
        </div>
      </div>;
  }
  const mediaStyle = {
    display: status === 'loaded' ? 'block' : 'none',
    width: '100%',
    height: 'auto',
    borderRadius: '0.75rem'
  };
  const media = isVideo ? <video src={inView ? src : undefined} autoPlay loop muted playsInline preload="metadata" onLoadedData={() => setStatus('loaded')} onError={() => setStatus('missing')} style={mediaStyle} /> : <img src={inView ? src : undefined} alt={caption} onLoad={() => setStatus('loaded')} onError={() => setStatus('missing')} style={mediaStyle} />;
  return <figure style={{
    margin: '1.25rem 0'
  }}>
      <div ref={boxRef} style={status === 'loaded' ? {
    width: '100%'
  } : {
    width: '100%',
    aspectRatio: ratio,
    borderRadius: '0.75rem',
    background: 'rgba(128,128,128,0.06)'
  }}>
        {media}
      </div>
      {status === 'loaded' && caption ? <figcaption style={{
    marginTop: '0.5rem',
    textAlign: 'center',
    fontSize: '0.85rem',
    opacity: 0.7
  }}>
          {caption}
        </figcaption> : null}
    </figure>;
};

You can run a saved workflow without leaving the chat. You type your inputs as a message, ModuleX starts the run, and the steps stream back into the same conversation as the run works through them. When it finishes, the result sits right there in the thread, next to the inputs you sent.

This is one of the three ways to start a workflow in ModuleX, alongside running it [from the builder](/workflow-builder/execution/running) and [from the API or an SDK](/workflow-builder/execution/api-endpoint). Running from chat is the most conversational of the three: every run becomes a turn in a chat thread you can scroll back through later.

<Note>
  Running a **workflow** from chat is different from talking to the [Assistant](/assistant/overview). A workflow is a graph you built and deployed; it runs your fixed steps in order. The Assistant is an agent that decides its own next step. This page is about running a workflow you already built. For a side-by-side of the two, see [Chat overview](/platform/chat/overview).
</Note>

<MediaEmbed id="MX-MEDIA-3330" type="app_video" caption={"A full run of a workflow from inside a ModuleX chat, start to finish."} />

## What you need first

A workflow can only be run from chat once it has a live deployment. Deploying takes a snapshot of the current canvas and marks it as the version that runs.

<CardGroup cols={2}>
  <Card title="A built workflow" icon="diagram-project" href="/workflow-builder/overview">
    Build it on the visual canvas, or generate it from a prompt with the [AI Composer](/concepts/ai-composer).
  </Card>

  <Card title="A live deployment" icon="rocket" href="/workflow-builder/execution/deploy">
    Deploy the workflow so chat has a fixed version to run. A workflow with no live deployment cannot be run from chat yet.
  </Card>
</CardGroup>

<Note>
  You need the **owner** or **admin** role in the organization to run a workflow. The older `member` role has been retired. If you do not see the option to run, ask an organization owner about your role. See [Roles and permissions](/security/roles-permissions).
</Note>

## Start a run from chat

<Steps>
  <Step title="Open a chat and choose the workflow">
    Start a new chat or open an existing one, then pick the workflow you want to run. Chat loads the workflow's live deployment, so you always run the deployed version, not whatever is open on the canvas.
  </Step>

  <Step title="Type your inputs and send">
    Your message is the run's input. Fill in the values the workflow expects, such as a question to research or a customer name to look up, then send. ModuleX writes your input into the conversation as the turn you just sent.
  </Step>

  <Step title="Watch the run work">
    A working indicator appears and the steps stream into the thread as they complete. You do not refresh or wait for a page to reload; updates arrive on their own. See [Watch the run](#watch-the-run-happen).
  </Step>

  <Step title="Read the result">
    When the run finishes, its output renders inline below your input as the reply for that turn. The whole exchange stays in the chat history so you can revisit it. See [Read the result](#read-the-result).
  </Step>
</Steps>

<MediaEmbed id="MX-MEDIA-3331" type="screenshot" caption={"The chat composer set up to run a workflow."} />

## What happens when you send

When you send a workflow run from chat, ModuleX records the whole exchange as a turn in the conversation so nothing is lost. Three things appear in the thread:

<CardGroup cols={3}>
  <Card title="Your inputs" icon="user">
    What you sent is saved as your message in the thread, so you can always see exactly what the run was asked to do.
  </Card>

  <Card title="A reply placeholder" icon="loader">
    A reply slot appears right away and shows the run as working, then fills in with steps and the final result as they arrive.
  </Card>

  <Card title="A live stream" icon="radio">
    ModuleX opens a live connection so step updates flow into that reply without you doing anything.
  </Card>
</CardGroup>

The run itself executes in the background. The chat does not freeze while it works; you see progress arrive in the reply as the run moves from step to step.

## Watch the run happen

While the run is in progress, the chat shows a working state and updates the reply as each step finishes. You can keep scrolling, read earlier turns, or jump back to the latest activity. If your connection drops mid-run, ModuleX reconnects on its own and replays what you missed, so you do not lose track of where the run got to.

A run ends in one of three ways:

<CardGroup cols={3}>
  <Card title="Finished" icon="circle-check">
    The run completed and its result is in the reply. This is the normal, successful ending.
  </Card>

  <Card title="Paused for you" icon="hand">
    The run reached a step that needs your input or approval before it can continue. See [When a run pauses for you](#when-a-run-pauses-for-you).
  </Card>

  <Card title="Stopped or failed" icon="circle-x">
    You stopped the run, or a step ran into a problem. The reply shows that it stopped, and you can send it again. See [If a run stops or fails](#if-a-run-stops-or-fails).
  </Card>
</CardGroup>

### Stop a run

If a run is taking too long or you sent the wrong inputs, you can stop it from the chat. Stopping is graceful: the step that is already running finishes first, then the run halts and the reply shows it as stopped. You can then send a fresh run with corrected inputs.

## When a run pauses for you

Some workflows include an [interrupt step](/workflow-builder/nodes/interrupt) that pauses the run to ask a human something, such as approving a plan or choosing between options before the run continues. This is called human-in-the-loop.

When a run pauses, the chat shows a question or an approval card right inside the thread, and the run waits for you. Answer it in chat and the same run picks up where it left off; you do not start over and you are not charged a second time. If you close the chat and come back later, the open question is still there waiting for your answer.

<CardGroup cols={2}>
  <Card title="Interrupt step" icon="hand" href="/workflow-builder/nodes/interrupt">
    How a workflow author adds a pause-for-a-human step to a workflow.
  </Card>

  <Card title="Human-in-the-loop resume" icon="reply" href="/realtime/hitl">
    The technical detail of how a paused run is resumed once you answer.
  </Card>
</CardGroup>

## Read the result

When the run finishes, its output becomes the reply for that turn, sitting directly below the inputs you sent. The exchange stays in the conversation, so you can scroll back to any earlier run and re-read both the inputs and the result.

Because every run is a turn in a thread, you can keep going. Send another message to run the workflow again as the next turn in the same conversation, building up a history of runs you can compare side by side. To organize these conversations later, see [History and folders](/platform/chat/history-folders).

## Private and shared runs

By default, a workflow run you start in a shared chat is visible to your organization, the same as any other chat. You can also keep a run private to yourself. For who can see what, and the difference between personal and organization chats, see [Private and org chat](/platform/chat/private-org-chat).

## Runs use credits

Running a workflow from chat uses credits. Each run is charged a single run credit, no matter how many steps it has. Pausing and then resuming a run is still one run, so answering an in-chat question does not cost you a second credit.

If your organization is out of credits or has hit a usage limit, the run is refused before it starts, and the chat tells you why instead of creating an empty reply. To understand what a credit is and what uses them, see [Credits and metering](/billing/credits); for the limits that can block a run, see [Usage gating and limits](/billing/usage-gating).

<Note>
  A run that is refused for billing reasons is stopped before anything is created: there is no half-finished reply to clean up. The most common reasons are running out of plan credits, hitting a rate limit, or a wallet that cannot cover overage. See [Errors and troubleshooting](/help/errors-troubleshooting).
</Note>

## If a run stops or fails

If a step runs into a problem, the run stops and the reply shows that it failed rather than a result. A few things to try:

<AccordionGroup>
  <Accordion title="The run says the workflow has no deployment" icon="rocket">
    The workflow has not been deployed yet, so chat has no fixed version to run. Open the workflow and deploy it, then try again. See [Deploy and versions](/workflow-builder/execution/deploy).
  </Accordion>

  <Accordion title="A step failed partway through" icon="triangle-alert">
    A step hit an error, for example a connected service was unreachable. Send the run again. If it keeps failing, open the workflow in the builder to inspect the failing step. See [Error handling and retries](/workflow-builder/error-handling-retries).
  </Accordion>

  <Accordion title="The run was refused before it started" icon="ban">
    This usually means a billing or usage limit. Check your plan and credits, then try again. See [Usage gating and limits](/billing/usage-gating) and [Errors and troubleshooting](/help/errors-troubleshooting).
  </Accordion>

  <Accordion title="You do not see an option to run" icon="lock">
    Running a workflow requires the owner or admin role. Ask an organization owner to check your role. See [Roles and permissions](/security/roles-permissions).
  </Accordion>
</AccordionGroup>

## Run it from code instead

Everything on this page happens through one underlying operation, and you can call it yourself from a script or app. The developer guide covers the exact request, the inputs you send, the live event stream you read to watch the run, and every error you can hit.

<CardGroup cols={2}>
  <Card title="Run from chat (developer reference)" icon="terminal" href="/workflow-builder/execution/run-on-chat">
    The technical contract for the same feature: request body, identities returned, the event stream, and errors.
  </Card>

  <Card title="Run via API" icon="code" href="/workflow-builder/execution/api-endpoint">
    Trigger a workflow programmatically, with or without attaching it to a chat thread.
  </Card>
</CardGroup>

## Related

<CardGroup cols={2}>
  <Card title="Chat overview" icon="messages-square" href="/platform/chat/overview">
    The chat surface: talking to the Assistant, running workflows, and querying knowledge.
  </Card>

  <Card title="Model selection" icon="sliders-horizontal" href="/platform/chat/model-selection">
    Choose the model a chat uses, including managed models and your own keys.
  </Card>

  <Card title="Chat with your knowledge" icon="book-open" href="/platform/chat/knowledge-chat">
    Ask questions answered from your connected knowledge bases.
  </Card>

  <Card title="Workflows and runs" icon="circle-play" href="/concepts/workflows-and-runs">
    What a workflow is, what a run is, and how they relate.
  </Card>
</CardGroup>
