Implementation:FlowiseAI Flowise CreateNewChatflow
| Attribute | Value |
|---|---|
| Source Repository | FlowiseAI/Flowise |
| Source File | packages/ui/src/api/chatflows.js
|
| Domain | Chatflow_Creation |
| Workflow | Chatflow_Creation |
| Last Updated | 2026-02-12 |
Overview
Concrete API client methods for creating and updating chatflow configurations on the Flowise server. The createNewChatflow function sends a POST request to create a new chatflow record, while updateChatflow sends a PUT request to modify an existing one. Together, they implement the persistence layer for the visual flow editor's save functionality.
Code Reference
Source Location
- File:
packages/ui/src/api/chatflows.js - Lines: L11 (
createNewChatflow), L13 (updateChatflow)
Signature
const createNewChatflow = (body) => client.post(`/chatflows`, body)
const updateChatflow = (id, body) => client.put(`/chatflows/${id}`, body)
Import
import chatflowsApi from '@/api/chatflows'
I/O Contract
Inputs (createNewChatflow)
| Parameter | Type | Required | Description |
|---|---|---|---|
| body | object |
Yes | The chatflow creation payload |
| body.name | string |
Yes | User-defined name for the chatflow |
| body.flowData | string |
Yes | JSON-serialized flow graph from reactFlowInstance.toObject()
|
| body.type | string |
Yes | Flow type: "CHATFLOW" or "MULTIAGENT"
|
| body.deployed | boolean |
No | Whether the chatflow is deployed (defaults to false)
|
| body.isPublic | boolean |
No | Whether the chatflow is publicly accessible (defaults to false)
|
Inputs (updateChatflow)
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string |
Yes | The server-assigned chatflow ID |
| body | object |
Yes | Partial update payload |
| body.name | string |
No | Updated chatflow name |
| body.flowData | string |
No | Updated JSON-serialized flow graph |
| body.deployed | boolean |
No | Updated deployment status |
Outputs
| Field | Type | Description |
|---|---|---|
| data | Chatflow |
The created or updated chatflow record with server-assigned fields |
| data.id | string |
Server-assigned unique chatflow identifier |
| data.name | string |
Chatflow name |
| data.flowData | string |
Serialized flow graph JSON |
| data.type | string |
Flow type |
| data.deployed | boolean |
Deployment status |
| data.createdDate | string |
ISO timestamp of creation |
| data.updatedDate | string |
ISO timestamp of last update |
Implementation Details
Save Flow Orchestration (in Canvas component)
The handleSaveFlow function in packages/ui/src/views/canvas/index.jsx (L211-245) orchestrates the save:
const handleSaveFlow = async (chatflowName) => {
if (reactFlowInstance) {
// 1. Preprocess nodes: extract credentials, reset selection
const nodes = reactFlowInstance.getNodes().map((node) => {
const nodeData = cloneDeep(node.data)
if (Object.prototype.hasOwnProperty.call(nodeData.inputs, FLOWISE_CREDENTIAL_ID)) {
nodeData.credential = nodeData.inputs[FLOWISE_CREDENTIAL_ID]
nodeData.inputs = omit(nodeData.inputs, [FLOWISE_CREDENTIAL_ID])
}
node.data = { ...nodeData, selected: false }
return node
})
// 2. Serialize graph state
const rfInstanceObject = reactFlowInstance.toObject()
rfInstanceObject.nodes = nodes
const flowData = JSON.stringify(rfInstanceObject)
// 3. Create or update
if (!chatflow.id) {
const newChatflowBody = {
name: chatflowName,
deployed: false,
isPublic: false,
flowData,
type: isAgentCanvas ? 'MULTIAGENT' : 'CHATFLOW'
}
createNewChatflowApi.request(newChatflowBody)
} else {
// Check for concurrent modifications before updating
getHasChatflowChangedApi.request(chatflow.id, lastUpdatedDateTime)
}
}
}
Concurrency Check
Before updating an existing chatflow, the system calls:
const getHasChatflowChanged = (id, lastUpdatedDateTime) =>
client.get(`/chatflows/has-changed/${id}/${lastUpdatedDateTime}`)
If the server reports { hasChanged: true }, the user is shown a confirmation dialog before the update proceeds.
Usage Examples
Creating a new chatflow
import chatflowsApi from '@/api/chatflows'
const flowData = JSON.stringify(reactFlowInstance.toObject())
const response = await chatflowsApi.createNewChatflow({
name: 'My Customer Support Bot',
flowData,
type: 'CHATFLOW',
deployed: false,
isPublic: false
})
const newChatflow = response.data
console.log('Created chatflow with ID:', newChatflow.id)
Updating an existing chatflow
import chatflowsApi from '@/api/chatflows'
const flowData = JSON.stringify(reactFlowInstance.toObject())
const response = await chatflowsApi.updateChatflow('abc-123', {
name: 'Updated Bot Name',
flowData
})
const updatedChatflow = response.data
console.log('Updated at:', updatedChatflow.updatedDate)
Using the useApi hook (as done in Canvas)
import chatflowsApi from '@/api/chatflows'
import useApi from '@/hooks/useApi'
const createNewChatflowApi = useApi(chatflowsApi.createNewChatflow)
const updateChatflowApi = useApi(chatflowsApi.updateChatflow)
// Create
createNewChatflowApi.request({ name: 'New Flow', flowData, type: 'CHATFLOW' })
// Handle success
useEffect(() => {
if (createNewChatflowApi.data) {
const chatflow = createNewChatflowApi.data
dispatch({ type: SET_CHATFLOW, chatflow })
// Update URL with new chatflow ID
window.history.replaceState(state, null, `/canvas/${chatflow.id}`)
}
}, [createNewChatflowApi.data])
Related API Functions
Other chatflow API functions in the same module:
getAllChatflows(params)-- List chatflows with pagination (L3)getSpecificChatflow(id)-- Fetch a single chatflow by ID (L7)deleteChatflow(id)-- Delete a chatflow (L15)getIsChatflowStreaming(id)-- Check if a chatflow supports streaming (L17)getHasChatflowChanged(id, lastUpdatedDateTime)-- Concurrency check (L21)