Search documentation

Search for pages in the documentation

Actions

Nodes that take actions in external systems

Action nodes perform operations in external systems—sending messages, creating records, and updating data. They're the "do something" nodes that make your workflows impactful.

Available Actions

Communication

NodeDescriptionIntegration
Slack PostSend messages to Slack channelsSlack
Email SendSend emails to recipientsNone (built-in)
SMS SendSend text messagesNone (built-in)

CRM

NodeDescriptionIntegration
Create HubSpot TaskCreate tasks in HubSpotHubSpot
Create Salesforce TaskCreate tasks in SalesforceSalesforce
CRM Update OpportunityUpdate deal/opportunity recordsHubSpot/Salesforce

Side Effects and Idempotency

Action nodes are side-effecting—they modify external systems. This has important implications:

What "Side-Effecting" Means

  • Action nodes change state outside the workflow
  • A Slack message, once sent, cannot be unsent
  • CRM records are created/modified permanently

Idempotency Protection

To prevent duplicate actions during retries, action nodes use idempotency keys:

text
Key = hash(executionId + nodeId + attempt)

If a retry occurs, the same key ensures:

  • Slack messages aren't sent twice
  • CRM tasks aren't created twice
  • Emails aren't duplicated

When Idempotency Doesn't Help

  • If you run the workflow multiple times (different executions)
  • If you have multiple action nodes doing similar things
  • Manual workflow runs always create new executions

Common Configuration

All action nodes share these characteristics:

SettingValue
Timeout30 seconds
Retry StrategyExponential, 3 attempts
Error OutputYes (handle failures gracefully)

Dynamic Content with Liquid

Action nodes use Liquid templates for dynamic content:

liquid
Hello {{ json.attendee.name }},

Thank you for joining {{ json.meeting.title }}.

Best,
{{ author.name }}

Expressions with CEL

Configuration parameters often use CEL expressions:

cel
trigger.dealRoomId           // Access trigger data
json.contact.email           // Access upstream data
json.attendees[0].email      // Array access

Execution Modes

Action nodes support both execution modes:

Per-Item Mode

Sends one message/creates one record per input item.

Example: If 3 attendees flow through, sends 3 separate Slack messages.

Batch Mode

Processes all items together (but typically still creates one action).

Example: Send one Slack message summarizing all 3 attendees.

Error Handling

Action nodes have error outputs for handling failures:

text
[Slack Post]
    ├── Success ──▶ [Continue workflow]
    └── Error ────▶ [Log failure] ──▶ [Sink]

Common Error Scenarios

ErrorCauseHandling
AuthenticationToken expired, permissions changedReconnect integration
Rate limitToo many requestsAdd delays, reduce frequency
Invalid recipientBad email/channel/phoneValidate upstream
TimeoutExternal service slowRetry handles this

Best Practices

1. Always Handle Errors

Never leave error outputs disconnected for critical actions:

text
[Email Send]
    ├── Success ──▶ [Continue]
    └── Error ────▶ [Slack Alert: "Email failed"] ──▶ [Sink]

2. Validate Recipients

Use If nodes to validate before sending:

text
[If: email is valid?]
    ├── Yes ──▶ [Email Send]
    └── No ───▶ [Log: "Invalid email"] ──▶ [Sink]

3. Be Mindful of Volume

Consider the impact:

  • Don't spam channels with high-frequency messages
  • Batch related updates when possible
  • Use appropriate urgency (not everything needs SMS)

4. Include Context in Messages

Recipients should understand without digging:

Good:

liquid
📋 Meeting Summary: {{ json.meeting.title }}

Date: {{ json.meeting.startTime | date: "%B %d" }}
Attendees: {% for a in json.meeting.attendees %}{{ a.name }}{% unless forloop.last %}, {% endunless %}{% endfor %}

Key Points:
{{ json.summary }}

Bad:

liquid
{{ json.summary }}

5. Test Before Releasing

Use MANUAL trigger to test actions:

  • Verify recipients are correct
  • Check message formatting
  • Confirm CRM records look right

Integration Requirements

Before using action nodes, ensure integrations are connected:

NodeRequires
Slack PostSlack integration + bot in channel
Email SendNone (zero config)
SMS SendNone (zero config)
HubSpot TaskHubSpot integration
Salesforce TaskSalesforce integration
CRM UpdateHubSpot or Salesforce integration

See Setup Guide for integration configuration.

Common Patterns

Pattern: Notify on Completion

text
[Process Data] ──▶ [Slack Post: "Processing complete"]

Pattern: Multi-Channel Notification

text
                   ┌──▶ [Email Send]
[AI Analysis] ──▶ [Broadcast] ──▶ [Slack Post]
                   └──▶ [SMS Send] (for urgent)

Pattern: CRM Sync

text
[Load Meeting] ──▶ [AI: Extract insights] ──▶ [CRM Update Opportunity]
                                           ──▶ [Create HubSpot Task]

Pattern: Conditional Actions

text
[AI: Classify urgency]
         │
         ▼
[If: urgent?]
    ├── Yes ──▶ [SMS Send] + [Slack Post]
    └── No ───▶ [Email Send]

Next Steps