> Source: https://wexa.ai/docs/automation/promote-flow

# promote-flow

[Can be held for approval](/docs/sdks-and-apis/how-every-tool-call-works#lifecycle-and-governance)

Snapshot a process flow as it stands now and record that snapshot as its next version, which becomes the live one. Needs the `fabric:orchestrate.write` grant and an admin role.

**Promote a process flow**

**Wexa MCP server**

```bash
curl -sS -X POST https://fabric.wexa.ai/mcp/$FABRIC_PROJECT_ID \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "Mcp-Session-Id: $MCP_SESSION_ID" \
  -H "content-type: application/json" -H "accept: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"promote-flow","arguments":{"process_flow_id":"6ab1945e7566f41b5c28e308"}}}'
```

```json
{
  "content": [
    {
      "type": "text",
      "text": "{\"lifecycle_id\":\"qlc_000181\",\"result\":{\"id\":\"fver_9f3fc6a6-4f55-44d6-b7ba-c2329a8e0461\",\"agentflowId\":\"6ab1945e7566f41b5c28e308\",\"version\":2,\"status\":\"promoted\",\"agentCount\":1,\"parentVersion\":1}}"
    }
  ],
  "isError": false
}
```

**REST API**

```bash
curl -sS https://fabric.wexa.ai/v1/promote-flow \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "content-type: application/json" \
  -d '{"process_flow_id":"6ab1945e7566f41b5c28e308"}'
```

```json
{
  "lifecycle_id": "qlc_000181",
  "result": {
    "id": "fver_9f3fc6a6-4f55-44d6-b7ba-c2329a8e0461",
    "agentflowId": "6ab1945e7566f41b5c28e308",
    "version": 2,
    "status": "promoted",
    "agentCount": 1,
    "parentVersion": 1
  }
}
```

**TypeScript SDK**

```ts
import { Fabric } from '@wexa-fabric/sdk'

const fabric = new Fabric()
const result = await fabric.promoteFlow({
  process_flow_id: '6ab1945e7566f41b5c28e308'
})
```

```ts
// result is the payload itself, with no `.result` to read
{
  id: 'fver_9f3fc6a6-4f55-44d6-b7ba-c2329a8e0461',
  agentflowId: '6ab1945e7566f41b5c28e308',
  version: 2,
  status: 'promoted',
  agentCount: 1,
  parentVersion: 1
}
```

**Python SDK**

```python
from wexa import Fabric

fabric = Fabric()
out = fabric.promote_flow(
    process_flow_id="6ab1945e7566f41b5c28e308",
)
```

```python
# out is the result, already unwrapped
{
    "id": "fver_9f3fc6a6-4f55-44d6-b7ba-c2329a8e0461",
    "agentflowId": "6ab1945e7566f41b5c28e308",
    "version": 2,
    "status": "promoted",
    "agentCount": 1,
    "parentVersion": 1
}
```

## Parameters

| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| `process_flow_id` | string | Required | Process flow id. A process flow in this project. |

**Errors**

- `ValidationError`: the credential's role is not owner, organization admin or project admin; promoting needs an admin role.

**Show full response**

A real response, captured from a live call to `promote-flow`:

`snapshot` came back populated and is shown as `…` here, because the real value runs to
thousands of characters. Read it from your own call rather than from this page.

**Result of promote-flow**

**REST API**

```json
{
  "lifecycle_id": "qlc_000181",
  "result": {
    "id": "fver_9f3fc6a6-4f55-44d6-b7ba-c2329a8e0461",
    "agentflowId": "6ab1945e7566f41b5c28e308",
    "version": 2,
    "status": "promoted",
    "snapshot": "\u2026",
    "agentCount": 1,
    "promotedBy": "6a79a770b6c128ccc24bfca7",
    "promotedAt": "2026-09-21T20:41:37.225918542Z",
    "parentVersion": 1
  }
}
```

**TypeScript SDK**

```ts
// the object you get back IS the result — there is no `.result` to read
{
  id: 'fver_9f3fc6a6-4f55-44d6-b7ba-c2329a8e0461',
  agentflowId: '6ab1945e7566f41b5c28e308',
  version: 2,
  status: 'promoted',
  snapshot: '…',
  agentCount: 1,
  promotedBy: '6a79a770b6c128ccc24bfca7',
  promotedAt: '2026-09-21T20:41:37.225918542Z',
  parentVersion: 1
}

// The TS SDK names these camelCase — lifecycleId, traceId — where Python uses
// lifecycle_id and trace_id. Both are non-enumerable: readable, but omitted by
// Object.keys() and JSON.stringify(). `result.lifecycleId` here is undefined.
result.lifecycleId // 'qlc_000181'
```

**Python SDK**

```python
# a dict subclass; `result` is already unwrapped
{
 "id": "fver_9f3fc6a6-4f55-44d6-b7ba-c2329a8e0461",
 "agentflowId": "6ab1945e7566f41b5c28e308",
 "version": 2,
 "status": "promoted",
 "snapshot": "\u2026",
 "agentCount": 1,
 "promotedBy": "6a79a770b6c128ccc24bfca7",
 "promotedAt": "2026-09-21T20:41:37.225918542Z",
 "parentVersion": 1
}

out.lifecycle_id  # 'qlc_000181' — an attribute, not a key
```

**More details**

Use this when a process flow's structure is where you want it. Editing a process flow records nothing on its own, so without a promote there is no history to return to. The previous live version becomes `superseded`, and version numbers only ever increase.

List the versions with [`flow-versions`](/docs/automation/flow-versions); change which one is live with [`rollback-flow-version`](/docs/automation/rollback-flow-version).

Marked consequential: it is audited in full, and a policy rule may hold it for a person to approve. See [Policy and approvals](/docs/governance/policy-and-approvals).

Every tool call works the same way: [How every tool call works](/docs/sdks-and-apis/how-every-tool-call-works).
