---
title: "Workflows & bots"
description: "Render Gleap workflow steps in your own UI and answer them"
url: https://docs.gleap.ai/en/articles/721-workflows-and-bots
collection: "Guide"
updated: 2026-11-01
language: en
---

# Workflows & bots

Render Gleap workflow steps in your own UI and answer them

A conversation created with `workflowId` (or picked up by your project's automation) runs the configured workflow. Steps that wait for the customer surface in three ways: as a `BOT` message in the conversation, as a `workflow.step.presented` event, and via the pending-step endpoint.

## Read the pending step

```bash
curl https://api.gleap.io/v3/s2s/conversations/cnv_…/workflow \
  -H "Authorization: Bearer $TOKEN"
```

```json
{ "step": { "workflowId": "wf_…", "stepType": "buttons",
            "actionFlowId": "node-3", "actionId": 0,
            "action": { "type": "buttons", "options": ["Block card", "Talk to a human"], "…": "…" } } }
```

`step` is `null` when nothing is waiting for the customer (internal steps auto-run). `action` carries the same structure the Gleap widget renders from — text, options, input configuration, attribute definitions for form steps.

## Answer the step

```bash
curl -X POST https://api.gleap.io/v3/s2s/conversations/cnv_…/workflow/answer \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{ "selected": "Block card" }'
```

One field per step kind:

<table style="min-width: 50px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Step</p></th><th colspan="1" rowspan="1"><p>Body</p></th></tr><tr><td colspan="1" rowspan="1"><p>Free-text / input / chat input</p></td><td colspan="1" rowspan="1"><p><code>{ "text": "12345" }</code></p></td></tr><tr><td colspan="1" rowspan="1"><p>Buttons / selection</p></td><td colspan="1" rowspan="1"><p><code>{ "selected": "Block card" }</code></p></td></tr><tr><td colspan="1" rowspan="1"><p>Conversation rating step</p></td><td colspan="1" rowspan="1"><p><code>{ "rating": 5 }</code></p></td></tr><tr><td colspan="1" rowspan="1"><p>Attachments alongside an answer</p></td><td colspan="1" rowspan="1"><p><code>{ "text": "…", "attachments": [{ "url": "…", "name": "…", "contentType": "…" }] }</code></p></td></tr><tr><td colspan="1" rowspan="1"><p>Ask for a human (no bot run)</p></td><td colspan="1" rowspan="1"><p><code>{ "botAction": "humanHandoff" }</code></p></td></tr></tbody></table>

The endpoint returns `202` — the workflow advances asynchronously; follow it via `workflow.step.presented` / `message.created` events or by re-reading the pending step.

## Run a workflow on an existing conversation

```bash
curl -X POST https://api.gleap.io/v3/s2s/conversations/cnv_…/workflow/wf_…/run \
  -H "Authorization: Bearer $TOKEN"
```

Replaces any active workflow on the conversation and reopens it for the customer. Only **live** workflows can run; drafts return `workflow_not_found`.

## List available workflows

```bash
curl https://api.gleap.io/v3/s2s/workflows -H "Authorization: Bearer $TOKEN"
# → [ { "id": "wf_…", "name": "Card issues" }, … ]
```

> **Note:** `workflow.completed` fires when a workflow ends — `reason: "completed"` for a normal end (including close steps) or `reason: "handed_off"` when it passed the conversation to an AI agent or your team.

## Related

- [Overview](https://docs.gleap.ai/en/articles/718-overview.md)
- [Authentication](https://docs.gleap.ai/en/articles/719-authentication.md)
- [Quickstart](https://docs.gleap.ai/en/articles/720-quickstart.md)
- [Webhooks & events](https://docs.gleap.ai/en/articles/722-webhooks-and-events.md)
- [Realtime stream](https://docs.gleap.ai/en/articles/723-realtime-stream.md)
