Workflow Structure
A workflow has two layers: the record FlowMint stores (id, title, whether
it is enabled) and the config, the JSON that says what triggers it and
which steps run.
The workflow record
Section titled “The workflow record”| Field | What it is | Rules and default |
|---|---|---|
id | The workflow’s permanent identifier. | Lowercase letters, digits, - and _ only. Cannot be reused. |
title | The name shown on the Workflows and Run History screens. | Defaults to the id. |
enabled | Whether the trigger starts runs. | Off unless you set it to true. |
form_id | Shortcut for a form trigger when config has no trigger block. | Optional. |
config | The definition below, sent as a JSON string. | Required. |
managed_by | Who maintains it: admin or connector:cowork. | Set on creation, never changed. |
connector_version | A counter that rises by one on every update. | Read-only. |
An update that includes config replaces the whole definition, so send
every step you want to keep.
The config
Section titled “The config”{ "trigger": { "type": "form", "form_id": "contact" }, "steps": [ { "name": "find_folder", "type": "drive_find_or_create_folder", "config": { "parent_id": "1aVp…", "name": "{{ labels.company }}" } }, { "name": "upload", "type": "drive_upload_file", "config": { "parent_id": "{{ steps.find_folder.id }}", "file_field": "artwork" } } ]}| Key | What it does |
|---|---|
trigger | Required. { "type": "form", "form_id": "…" } runs on each stored submission of that form. { "type": "schedule", "interval": "daily", … } runs on a timer; see Scheduled workflows. A top-level form_id with no trigger is read as a form trigger. |
settings.max_retries | How many times a step with on_error: retry is retried after a retryable error. Default 3; 0 turns retries off. See Retries. |
steps | Required. The steps, run in order. |
Each step
Section titled “Each step”| Key | Required | What it does |
|---|---|---|
name | Yes | A name unique within the workflow. Later steps read this step’s output through it. Use snake_case. |
type | Yes | One of the step types in the Step library. |
config | No | The step’s settings, an object. Any string in it may contain {{ … }} placeholders. |
skip_if | No | An expression; when it is true the step is skipped. See Conditions and errors. |
on_error | No | fail (default), continue or retry. |
There is no when key. A step given when ignores it and runs every time.
How steps pass values
Section titled “How steps pass values”Each step that succeeds stores its output under its name. A later step
reads it as {{ steps.<name>.<field> }}: in the example, upload reads
the folder id from {{ steps.find_folder.id }}. Each step’s output fields
are listed on its page in the Step library.
- Use the step’s name, not its type:
steps.find_folder.id, notsteps.drive_find_or_create_folder.id. - A skipped step has no output, so paths into it are empty.
- A step that failed with
on_error: continuehas the output{ "failed": true, "error": "<error code>" }. - Steps inside a
conditionalortry_catchstore their output the same way, under their own names, so give them names unique across the whole workflow.
What is checked when you save
Section titled “What is checked when you save”FlowMint rejects a workflow when the id is malformed or taken, the config is
not valid JSON, the trigger is missing or invalid, a top-level step has no
name or type, two top-level steps share a name, a type is not registered,
on_error is not one of the three values, or a form trigger names a form
that does not exist in Promptless Forms.
It saves with a warning when a file step comes after fre_delete_entry
(the files are gone by then) and when a scheduled workflow reads data,
entry or entry_files, which are empty in a scheduled run.
Step settings themselves (a missing to, a wrong folder id) and the steps
inside conditional and try_catch are not checked until the step runs.
One workflow per form
Section titled “One workflow per form”Each submission starts at most one run. If several enabled workflows are
bound to the same form, only the most recently updated one runs. Put
everything a form needs into one workflow, using conditional for the
parts that differ.