Update an onboarding flow
/onboarding-flows/{id}Changes what you send and returns the flow. routes replaces the whole routing graph, and [] clears it; send it as GET returns it, listing each route after the route that reaches its from_form_id. A graph that cannot be read back exactly is refused with 422. definition is kept unless sent. A published flow can still be changed. dry_run shows the result without saving it. Emits onboarding_flow.updated and sends no email. Sending the old values undoes it.
Path parameters
The onboarding flow's id, a uuid. An unknown or deleted id returns 404.
Query parameters
Validate and run the call without committing it, returning what the real call would return with
meta.dry_runset.
Request body
application/json, required · OnboardingFlowUpdate
The flow's display name.
- One of:
How often a respondent completes the flow again:
daily,one_month,three_month,six_month,twelve_monthornever_expire.daily,one_month,three_month,six_month,twelve_month,never_expire - One of:
continuouslets a respondent change answers at any time;versionedkeeps each completion as it was.continuous,versioned - One of:
The user types the flow can onboard:
investor,advisoror both.investor,advisor The editor's layout for the flow. It is kept as sent and never read by the API. Left alone when you do not send it.
The whole routing graph. It replaces the stored one, and an empty list clears it. List each route after the route that reaches its
from_form_id; the start form is the only form no route has to reach. Left alone when you do not send it.
{
"name": "Investor suitability v2",
"routes": [
{
"from_form_id": "0b6c7c0e-1f0a-4b6c-8d0e-5f0f4a7a3c21",
"to_form_id": "6d8f3a52-9a41-4d6c-b7a1-2c9e5d1b7f33",
"condition_sets": [
{
"condition_type": "AND",
"condition_value": null,
"conditions": [
{
"form_field_id": "2f1d9a77-3c1e-4e85-a0b3-7d6c4e8b9a55",
"operator": "=",
"value": "yes"
}
],
"custom_conditions": []
},
{
"condition_type": "OTHER",
"condition_value": null,
"conditions": [],
"custom_conditions": []
}
]
}
]
}Responses
{
"data": {
"id": "48e0c1a6-6f3b-4d44-9d49-0a5a0b8f2d11",
"name": "Investor suitability",
"status": "draft",
"expiry_type": "twelve_month",
"mode_type": "continuous",
"user_types": [
"investor"
],
"routes": [
{
"from_form_id": "0b6c7c0e-1f0a-4b6c-8d0e-5f0f4a7a3c21",
"to_form_id": "6d8f3a52-9a41-4d6c-b7a1-2c9e5d1b7f33",
"condition_sets": [
{
"condition_type": "AND",
"condition_value": null,
"conditions": [
{
"form_field_id": "2f1d9a77-3c1e-4e85-a0b3-7d6c4e8b9a55",
"operator": "=",
"value": "yes"
}
],
"custom_conditions": []
},
{
"condition_type": "OTHER",
"condition_value": null,
"conditions": [],
"custom_conditions": []
}
]
}
],
"definition": null,
"form_count": 2,
"start_form_id": "0b6c7c0e-1f0a-4b6c-8d0e-5f0f4a7a3c21",
"created_at": "2026-11-08T10:30:00Z",
"updated_at": "2026-11-08T10:30:00Z"
}
}Authorization failed. error.code is one of org_disabled,
ip_blocked, missing_scope, scope_disabled, user_disabled.
The request conflicts with existing state (error.code = conflict),
e.g. a compliance flow with the requested name already exists.
The request can't be processed (HTTP 422): validation_failed with one ErrorDetail per
problem, or a code documented on the operation.
Examples
curl -X PATCH https://your-org-domain/kong/core/api/v2/onboarding-flows/{id}\
-H "Authorization: Bearer $HELM_API_KEY"\
-H "Content-Type: application/json"\
-d '{
"name": "Investor suitability v2",
"routes": [
{
"from_form_id": "0b6c7c0e-1f0a-4b6c-8d0e-5f0f4a7a3c21",
"to_form_id": "6d8f3a52-9a41-4d6c-b7a1-2c9e5d1b7f33",
"condition_sets": [
{
"condition_type": "AND",
"condition_value": null,
"conditions": [
{
"form_field_id": "2f1d9a77-3c1e-4e85-a0b3-7d6c4e8b9a55",
"operator": "=",
"value": "yes"
}
],
"custom_conditions": []
},
{
"condition_type": "OTHER",
"condition_value": null,
"conditions": [],
"custom_conditions": []
}
]
}
]
}'