v1

latestOpenAPI 3.1.0MIT2026-07-243952451019.0 KB
Workflows::Step

List Steps

List all visible (displayable) steps for a workflow using standard collection sorting. Internal container nodes are not included. sort_order is container-local and not globally unique; use GET /workflows/{id}/structure when clients need execution order.

get/workflows/{workflow_id}/steps

Path parameters

workflow_idstring required

Integer id or obfuscated public_id of the workflow.

Query parameters

afterstring

ID of item after which the collection should be returned. More examples and info about pagination in our guides.

sort_order'asc' | 'desc'

Sort order of a list response. Use 'desc' to reverse the default 'asc' (ascending) sort order. Examples in our guides.

sort_property'id' | 'updated_at'

Sort property of a list response. The default is id and thus the created_at order. If you sort by other properties, we additionally sort by id implicitly as a secondary sort property, so that you can rely on the sort order to be deterministic even if the main sort property ends up with the same values.

Response

OK

idinteger

Step ID

public_idstring nullable

Obfuscated step ID

workflow_idinteger

Integer ID of the parent workflow

step_typestring

The step class key (same as the single key in step_type_settings).

namestring

Human-readable step name.

sort_orderinteger

Zero-based position within this step's own container (the trunk, or a split's branch/convergence sequence). It is therefore container-local, not globally unique — it restarts at 0 for steps after a split. In /structure, follow the steps array order for execution flow, not sort_order.

state'active' | 'notSetup' | 'notDefined'

Setup state of the step.

parent_step_idinteger nullable

Raw integer id of the parent split step when this step lives inside a branch. Null for trunk steps.

branchstring nullable

For conditional splits — matched or unmatched. For split tests — the 0-based variant index as a string. Null for trunk steps.

convergence_step_idinteger nullable

Id of the step a split's branches reconverge at — the first step that runs after the split, which every branch continues to. Example: a conditional_split_step (id 203) whose matched/unmatched branches both lead to the same next step (id 206) → convergence_step_id 206. It is null in two cases: a split that ends the flow (nothing follows it), and any non-split step (the field only applies to conditional_split_step / split_test_step). Use step_type to tell them apart — a null on a non-split step just means the field does not apply. When non-null, the referenced step always appears in this response.

step_type_settingsobject

A single-key map: the one key is the step type (identical to step_type) and its value carries that type's settings. This is the canonical reference for step settings — the Create Step and Update Step request bodies point here.

Available types —

Action steps (non-branching): send_email_step, send_asset_step, send_chat_message_step, contact_tag_step, contact_custom_attribute_step, delay_step, notify_step, deliver_webhook_step, enroll_step, unenroll_contact_step, grant_community_access_step, revoke_community_access_step, create_opportunity_step, move_step

Split steps (branching): conditional_split_step, split_test_step

Per-type fields

  • send_email_step: subject, preheadline, template_id, from_address_id, reply_to_address_id, plus write-only html_body/text_body (see "send_email_step inline body" below)
  • send_asset_step: asset_id
  • send_chat_message_step: inbox_key, message, subject, start_new_conversation
  • contact_tag_step: action ("Add Tags" or "Remove Tags"), contacts_tag_ids (array of raw integer tag ids)
  • contact_custom_attribute_step: action, value, field_id (a Forms::Field id — discoverable via the Forms API)
  • delay_step: delay_type (relative/day_of_week/day_of_month), duration, interval, time_zone, use_contact_time_zone, use_execution_window, day_of_week, date_of_month, start_time, end_time, execution_window_days
  • notify_step: message, notify_type (array), user_ids (array of user ids — must be team members; discover via GET /teams/{team_id}/membershipsuser_id. A non-member id is rejected 422.)
  • deliver_webhook_step: webhooks_outgoing_endpoint_id
  • enroll_step: course_ids (array), section_ids (array). Enrollment happens per section_ids — provide the section ids to enroll in (discover via GET /api/v2/courses/{course_id}/sections). course_ids alone is accepted and the step reads active, but enrolls nothing at run time.
  • unenroll_contact_step: course_ids (array), section_ids (array). Unenroll honors both course_ids and section_ids.
  • grant_community_access_step: space_ids (array)
  • revoke_community_access_step: space_ids (array)
  • create_opportunity_step: name, value, assignment_strategy, move_existing, sales_pipelines_stage_id, sales_pipeline_id, membership_id, membership_ids (array)
  • move_step: workflow_id
  • conditional_split_step: condition object with filter_id (raw integer RefineFilter id on read; integer id or public_id on write) and is_setup boolean
  • split_test_step: variants array, each with weight (0..100, two entries summing to 100)

send_email_step — template & inline body

A send_email_step always owns its email. On create, a provided template_id is copied into a fresh step-owned template (it is never a live reference to the original), and an inline html_body/text_body instead mints a new step-owned template. This deliberately mirrors the builder UI, which always makes its own copy so edits to a step's email never touch the source. template_id takes precedence when both a template_id and an inline body are supplied.

Because the step owns its template, template_id is create-only and cannot be changed on update — a PATCH that includes template_id returns 422. To change an existing step's email, edit it in place by sending html_body/text_body (this patches the step's own template — no new template is created); to use a different template, create a new step. html_body/text_body are write-only and are never returned in step_type_settings. Prefer a verified sending address for from_address_id/reply_to_address_id.

FK id serialization

Response FK values (*_id, *_ids) are serialized as raw integers. On write, those same FK fields accept either integer ids or obfuscated public_ids in the same workspace/team scope.

created_atstring date-time
updated_atstring date-time

Example response

[
  {
    "id": 201,
    "public_id": "StEm01",
    "workflow_id": 101,
    "step_type": "send_email_step",
    "name": "Send Email",
    "sort_order": 0,
    "state": "active",
    "parent_step_id": null,
    "branch": null,
    "convergence_step_id": null,
    "step_type_settings": {
      "send_email_step": {
        "subject": "Welcome!",
        "preheadline": "We're glad you're here.",
        "template_id": 3001,
        "from_address_id": 4001,
        "reply_to_address_id": null
      }
    },
    "created_at": "2025-06-01T00:00:00.000Z",
    "updated_at": "2025-06-01T00:00:00.000Z"
  }
]