Skip to main content
A workflow defines what happens automatically when a form event occurs — such as sending a confirmation email when a submission arrives, or posting to a Slack channel when a specific answer is submitted. Each workflow has a trigger that specifies when it fires and an ordered list of actions to execute.

List workflows

GET /workflows Returns a paginated list of workflows in your account.

Query parameters

limit
integer
default:"20"
Number of workflows to return per page. Maximum 100.
cursor
string
Pagination cursor from a previous response’s next_cursor.
form_id
string
Filter to workflows that are attached to a specific form.

Response

data
object[]
Array of workflow objects.
next_cursor
string
Cursor for the next page. null on the last page.
has_more
boolean
true if more workflows exist beyond this page.
curl --request GET \
  --url "https://api.formflows.ai/v1/workflows?form_id=frm_8kQmP2xNvL" \
  --header "Authorization: Bearer sk_live_your_api_key"

Create a workflow

POST /workflows Creates a new workflow attached to a form.

Body parameters

name
string
required
Display name for the workflow.
form_id
string
required
The ID of the form that this workflow is attached to.
trigger
object
required
Defines the event that starts the workflow.
actions
object[]
required
Ordered list of actions to execute when the trigger fires.

Action type reference

Sends an email when the workflow fires.
Config keyTypeRequiredDescription
tostringYesRecipient email. Supports {{field_id}} template variables.
subjectstringYesEmail subject line. Supports template variables.
bodystringYesEmail body in plain text or HTML. Supports template variables.
from_namestringNoSender display name. Defaults to your account name.
Sends an HTTP POST request to a URL with the submission data as the body.
Config keyTypeRequiredDescription
urlstringYesDestination URL. Must use HTTPS.
headersobjectNoAdditional HTTP headers to include.
Posts a message to a Slack channel. Requires a connected Slack integration.
Config keyTypeRequiredDescription
channelstringYesSlack channel ID or name (e.g., #sales-leads).
messagestringYesMessage text. Supports template variables.
Appends a new row to a Google Sheet. Requires a connected Google integration.
Config keyTypeRequiredDescription
spreadsheet_idstringYesGoogle Sheets spreadsheet ID.
sheet_namestringYesTab name within the spreadsheet.
row_mappingobjectYesMap of column headers to field IDs or static values.

Response

Returns the created workflow object with a 201 Created status.
curl --request POST \
  --url "https://api.formflows.ai/v1/workflows" \
  --header "Authorization: Bearer sk_live_your_api_key" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "New registration — email confirmation",
    "form_id": "frm_8kQmP2xNvL",
    "trigger": {
      "type": "submission.created"
    },
    "actions": [
      {
        "type": "send_email",
        "config": {
          "to": "{{fld_e5F6g7H8}}",
          "subject": "You are registered for the 2025 Annual Conference",
          "body": "Hi {{fld_a1B2c3D4}},\n\nThank you for registering. We look forward to seeing you!\n\nThe Events Team"
        }
      },
      {
        "type": "slack_message",
        "config": {
          "channel": "#event-registrations",
          "message": "New registration from {{fld_a1B2c3D4}} ({{fld_e5F6g7H8}})"
        }
      }
    ]
  }'
Example response:
{
  "id": "wfl_4nRsT6uVwX",
  "name": "New registration — email confirmation",
  "form_id": "frm_8kQmP2xNvL",
  "enabled": true,
  "trigger": {
    "type": "submission.created",
    "config": {}
  },
  "actions": [
    {
      "id": "act_yZ0aB1cD2e",
      "type": "send_email",
      "config": {
        "to": "{{fld_e5F6g7H8}}",
        "subject": "You are registered for the 2025 Annual Conference",
        "body": "Hi {{fld_a1B2c3D4}},\n\nThank you for registering. We look forward to seeing you!\n\nThe Events Team"
      }
    },
    {
      "id": "act_fG3hI4jK5l",
      "type": "slack_message",
      "config": {
        "channel": "#event-registrations",
        "message": "New registration from {{fld_a1B2c3D4}} ({{fld_e5F6g7H8}})"
      }
    }
  ],
  "created_at": "2025-01-15T11:30:00Z",
  "updated_at": "2025-01-15T11:30:00Z"
}

Get a workflow

GET /workflows/{id} Returns a single workflow by ID, including its full trigger and actions configuration.

Path parameters

id
string
required
The workflow ID, e.g. wfl_4nRsT6uVwX.

Response

Returns the full workflow object.
curl --request GET \
  --url "https://api.formflows.ai/v1/workflows/wfl_4nRsT6uVwX" \
  --header "Authorization: Bearer sk_live_your_api_key"

Update a workflow

PATCH /workflows/{id} Updates a workflow. Use this to enable or disable a workflow, rename it, or modify its trigger and actions. Only the fields you include are changed.

Path parameters

id
string
required
The workflow ID to update.

Body parameters

name
string
New display name.
enabled
boolean
Set to false to pause the workflow without deleting it. Set to true to re-enable it.
trigger
object
Replaces the workflow trigger configuration.
actions
object[]
Replaces the entire actions array. Include existing action IDs to preserve them.

Response

Returns the updated workflow object.
curl --request PATCH \
  --url "https://api.formflows.ai/v1/workflows/wfl_4nRsT6uVwX" \
  --header "Authorization: Bearer sk_live_your_api_key" \
  --header "Content-Type: application/json" \
  --data '{"enabled": false}'

Delete a workflow

DELETE /workflows/{id} Permanently deletes a workflow. In-progress executions are allowed to finish before the workflow is removed.

Path parameters

id
string
required
The workflow ID to delete.

Response

Returns a 204 No Content response on success.
curl --request DELETE \
  --url "https://api.formflows.ai/v1/workflows/wfl_4nRsT6uVwX" \
  --header "Authorization: Bearer sk_live_your_api_key"