Workflows

Build visual automation workflows using a drag-and-drop DAG (directed acyclic graph) editor. Workflows connect trigger nodes to action nodes, enabling complex email operations without code.

Create a workflow

POST
/v1/workflows

Create a new workflow in draft status.

Request body

ParameterTypeDescription
namerequiredstringWorkflow name.
descriptionstringOptional description of what the workflow does.
Response — 201 Created
{
  "id": "wf_abc123",
  "name": "Bounce Handler",
  "description": "Suppress permanently bounced emails and notify Slack",
  "status": "draft",
  "nodes": [],
  "connections": [],
  "created_at": "2026-03-21T00:00:00Z"
}

List workflows

GET
/v1/workflows

List all workflows for the current team.

Get a workflow

GET
/v1/workflows/{id}

Retrieve a workflow with its full node and connection graph.

Update a workflow

PATCH
/v1/workflows/{id}

Update workflow name, description, nodes, or connections.

Delete a workflow

DELETE
/v1/workflows/{id}

Delete a workflow. Active workflows must be deactivated first.

Activate or deactivate

POST
/v1/workflows/{id}/activate

Toggle a workflow between active and inactive. Active workflows respond to their trigger events.

Manually trigger execution

POST
/v1/workflows/{id}/execute

Manually trigger a workflow execution. Optionally pass trigger data in the request body.

List execution history

GET
/v1/workflows/{id}/executions

List all executions for a workflow, with status and duration.

Get execution detail

GET
/v1/workflows/{id}/executions/{exec_id}

Get detailed execution results including per-node status, input/output data, and errors.

Workflow status

ParameterTypeDescription
draftstatusWorkflow is being designed. Does not respond to triggers.
activestatusWorkflow is live and will execute when triggered.
inactivestatusWorkflow is paused. Will not respond to triggers until reactivated.

Trigger nodes

Every workflow starts with a trigger node that defines when the workflow runs:

ParameterTypeDescription
email_eventtriggerFires on email events: delivered, bounced, opened, clicked, complained.
webhook_receivedtriggerFires when an external HTTP POST hits the workflow unique URL.
scheduletriggerFires on a recurring cron schedule (e.g. daily digest, weekly report).
manualtriggerTriggered manually from the dashboard or via the API.
contact_eventtriggerFires when a contact is created, updated, unsubscribed, or added to a segment.
broadcast_completetriggerFires when a broadcast finishes sending.

Action nodes

Action nodes define the steps in your workflow:

ParameterTypeDescription
send_emailactionSend a transactional email via the Txtly API.
send_broadcastactionTrigger a broadcast to a segment.
http_requestactionMake an external HTTP call (any method, headers, body).
delayactionWait for a specified duration before continuing.
conditionactionBranch based on a condition. Outputs: true and false paths.
filteractionContinue only if a condition is met, otherwise stop this branch.
add_segmentactionAdd a contact to a segment.
remove_segmentactionRemove a contact from a segment.
update_contactactionModify contact properties.
suppress_emailactionAdd an email address to the suppression list.
slack_notificationactionSend a message to a Slack channel via webhook.
discord_notificationactionSend a message to a Discord webhook.
transform_dataactionMap and transform data between nodes using JSONPath or templates.
codeactionRun custom C# code for advanced logic.

Execution engine

Workflows are executed as a DAG using topological sort to determine execution order. Independent branches run in parallel, while nodes within a branch run sequentially. Each node's output is available to downstream nodes as input data. Execution state is persisted at each step for observability and resume capability.

Example: Bounce Handler

[Email Bounced] --> [Condition: bounce_type == 'permanent'?]
  --> true:  [Suppress Email] --> [Slack: "Permanent bounce: {{email}}"]
  --> false: [Delay: 1 hour]  --> [Send Email: retry original]