Flows
List Flows
Returns all flows belonging to a chatbot.
GET /api/dev/v1/chatbots/{chatbot_id}/flows
Authorization: Bearer <api-key>
- cURL
- Python
- JavaScript
curl -X GET https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows \
-H "Authorization: Bearer <your-api-key>"
import requests
response = requests.get(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows",
headers={"Authorization": "Bearer <your-api-key>"},
)
print(response.json())
const response = await fetch(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows",
{ headers: { "Authorization": "Bearer <your-api-key>" } },
);
const data = await response.json();
Response - 200 OK
{
"items": [
{
"id": "01JNA...",
"chatbot_id": "01JMXYZ...",
"name": "Main Conversation Flow",
"type": "conversation",
"status": "published",
"created_at": "2026-01-20T08:00:00Z"
}
],
"total": 2
}
Create Flow
Creates a new flow for the specified chatbot.
POST /api/dev/v1/chatbots/{chatbot_id}/flows
Authorization: Bearer <api-key>
Content-Type: application/json
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name for the flow. |
type | string | yes | Flow type: conversation (state-machine) or meta (WhatsApp UI Flows). |
flow | object | no | Initial flow definition JSON. If omitted, a blank flow is created. |
- cURL
- Python
- JavaScript
curl -X POST https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "Onboarding Flow",
"type": "conversation"
}'
import requests
response = requests.post(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows",
headers={"Authorization": "Bearer <your-api-key>"},
json={"name": "Onboarding Flow", "type": "conversation"},
)
print(response.json())
const response = await fetch(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows",
{
method: "POST",
headers: {
"Authorization": "Bearer <your-api-key>",
"Content-Type": "application/json",
},
body: JSON.stringify({ name: "Onboarding Flow", type: "conversation" }),
},
);
const data = await response.json();
Response - 201 Created
{
"id": "01JNA456...",
"chatbot_id": "01JMXYZ123...",
"name": "Onboarding Flow",
"type": "conversation",
"status": "draft",
"flow": {},
"created_at": "2026-02-05T14:00:00Z",
"updated_at": null
}
Get Flow
Retrieves a specific flow by ID including its full flow definition.
GET /api/dev/v1/chatbots/{chatbot_id}/flows/{flow_id}
Authorization: Bearer <api-key>
- cURL
- Python
- JavaScript
curl -X GET https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id> \
-H "Authorization: Bearer <your-api-key>"
import requests
response = requests.get(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>",
headers={"Authorization": "Bearer <your-api-key>"},
)
print(response.json())
const response = await fetch(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>",
{ headers: { "Authorization": "Bearer <your-api-key>" } },
);
const data = await response.json();
Update Flow
Updates a flow's name or its flow definition JSON.
PATCH /api/dev/v1/chatbots/{chatbot_id}/flows/{flow_id}
Authorization: Bearer <api-key>
Content-Type: application/json
Request Body (all fields optional)
| Field | Type | Description |
|---|---|---|
name | string | New display name. |
flow | object | Updated flow definition JSON. Replaces the existing definition entirely. |
- cURL
- Python
- JavaScript
curl -X PATCH https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id> \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Onboarding Flow",
"flow": { "states": [] }
}'
import requests
response = requests.patch(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>",
headers={"Authorization": "Bearer <your-api-key>"},
json={"name": "Updated Onboarding Flow", "flow": {"states": []}},
)
print(response.json())
const response = await fetch(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>",
{
method: "PATCH",
headers: {
"Authorization": "Bearer <your-api-key>",
"Content-Type": "application/json",
},
body: JSON.stringify({ name: "Updated Onboarding Flow", flow: { states: [] } }),
},
);
const data = await response.json();
Validate Flow
Runs backend validation on the flow definition and returns any errors or warnings. Does not change the flow's status.
POST /api/dev/v1/chatbots/{chatbot_id}/flows/{flow_id}/validate
Authorization: Bearer <api-key>
- cURL
- Python
- JavaScript
curl -X POST https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>/validate \
-H "Authorization: Bearer <your-api-key>"
import requests
response = requests.post(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>/validate",
headers={"Authorization": "Bearer <your-api-key>"},
)
print(response.json())
const response = await fetch(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>/validate",
{
method: "POST",
headers: { "Authorization": "Bearer <your-api-key>" },
},
);
const data = await response.json();
Response - 200 OK
{
"valid": true,
"errors": [],
"warnings": [
{
"path": "states.greeting.transitions",
"message": "No fallback transition defined - users may get stuck."
}
]
}
Validate before publishing
Always validate a flow before publishing. The publish endpoint will reject flows with errors.
Publish Flow
Publishes a validated flow, making it live for end users.
POST /api/dev/v1/chatbots/{chatbot_id}/flows/{flow_id}/publish
Authorization: Bearer <api-key>
- cURL
- Python
- JavaScript
curl -X POST https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>/publish \
-H "Authorization: Bearer <your-api-key>"
import requests
response = requests.post(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>/publish",
headers={"Authorization": "Bearer <your-api-key>"},
)
print(response.json())
const response = await fetch(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>/publish",
{
method: "POST",
headers: { "Authorization": "Bearer <your-api-key>" },
},
);
const data = await response.json();
Response - 200 OK
{
"id": "01JNA456...",
"status": "published",
"published_at": "2026-02-10T09:15:00Z"
}
Delete Flow
Permanently deletes a flow. Published flows can still be deleted - active conversations using that flow will not receive new messages.
DELETE /api/dev/v1/chatbots/{chatbot_id}/flows/{flow_id}
Authorization: Bearer <api-key>
- cURL
- Python
- JavaScript
curl -X DELETE https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id> \
-H "Authorization: Bearer <your-api-key>"
import requests
requests.delete(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>",
headers={"Authorization": "Bearer <your-api-key>"},
)
# 204 No Content
await fetch(
"https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/flows/<flow-id>",
{
method: "DELETE",
headers: { "Authorization": "Bearer <your-api-key>" },
},
);
// 204 No Content
Response - 204 No Content
Flow Object
| Field | Type | Description |
|---|---|---|
id | string | Flow ULID. |
chatbot_id | string | Parent chatbot ID. |
name | string | Flow display name. |
type | string | conversation or meta. |
status | string | draft or published. |
flow | object | The flow definition JSON (states, transitions, screens, etc.). |
created_at | string | Creation timestamp. |
updated_at | string | Last update timestamp. |