These docs cover the S6S workflow engine — the developer playground layer underneath the product. For the main AI Visibility product (brand monitoring, the unified Report, fix actions), start at /docs/ai-visibility.
Node Types
Every workflow is a series of steps connected in a flow. Each step has an action type that determines what it does. This is the comprehensive reference for all built-in node types.
Triggers
Triggers define how a workflow starts. Every workflow needs exactly one trigger.
trigger.webhook
Start a workflow when an HTTP request hits a specific path.
| Config | Type | Default | Description |
|---|---|---|---|
| path | string | /my-webhook | URL path (e.g. /new-lead) |
| method | string | POST | HTTP method to accept |
{ body, headers, query, method, path, receivedAt }https://s6s.ai/api/webhooks/{path}?token={secret}- {{trigger.output.body.*}}
- {{trigger.output.headers.*}}
- {{trigger.output.query.*}}
- {{trigger.output.method}}
trigger.schedule
Run a workflow on a recurring schedule using cron expressions.
| Config | Type | Default | Description |
|---|---|---|---|
| cronExpression | string | 0 * * * * | Cron expression (minute, hour, day, month, weekday) |
| timezone | string | UTC | IANA timezone name |
{ scheduledTime, timezone }- */5 * * * * — every 5 minutes
- 0 9 * * 1-5 — weekdays at 9 AM
- 0 0 * * * — daily at midnight
- 0 0 1 * * — first of every month
trigger.manual
Start a workflow manually via the UI "Run" button or the POST /api/workflows/{id}/run API. No configuration needed.
{ payload, triggeredAt, triggeredBy }payload — the input object from the run request body (or {} if none)
triggeredAt — ISO timestamp
triggeredBy — "api" or "ui"
{
"trigger": { "type": "manual" }
}Actions
Actions do work — call APIs, send messages, transform data, run code.
action.http
Make an HTTP request to any URL.
| Config | Type | Default | Description |
|---|---|---|---|
| url | string | — | Full URL |
| method | string | GET | HTTP method |
| headers | object | {} | Request headers |
| body | string | — | Request body (for POST/PUT/PATCH) |
{ status, headers, body }Supports expression templates in all fields: {{steps.prev.output.url}}
action.transform
Reshape data between steps using a JSON template with expressions.
| Config | Type | Default | Description |
|---|---|---|---|
| template | object | {} | JSON template with {{expression}} placeholders |
Output: The evaluated template object.
{
"template": {
"message": "Hello, {{trigger.output.body.name}}!",
"timestamp": "{{trigger.output.timestamp}}"
}
}action.code
Execute a JavaScript expression and return the result.
| Config | Type | Default | Description |
|---|---|---|---|
| expression | string | ({ result: 'hello' }) | JavaScript expression to evaluate |
| language | string | javascript | Language (currently only javascript) |
Output: The return value of the expression.
action.email
Send an email via SMTP.
| Config | Type | Default | Description |
|---|---|---|---|
| to | string | — | Recipient email |
| subject | string | — | Email subject |
| bodyTemplate | string | — | Email body (supports expressions) |
Requires credential: smtp
action.slack
Post a message to a Slack channel.
| Config | Type | Default | Description |
|---|---|---|---|
| channel | string | #general | Channel name or ID |
| textTemplate | string | — | Message text (supports expressions) |
Requires credential: slack
action.discord
Send a message or perform an action in Discord.
| Config | Type | Default | Description |
|---|---|---|---|
| action | string | send_message | send_message, send_embed, add_reaction |
| channelId | string | — | Discord channel ID |
| content | string | — | Message content |
Requires credential: discord
action.telegram
Send a message or perform an action in Telegram.
| Config | Type | Default | Description |
|---|---|---|---|
| action | string | send_message | send_message, send_photo, send_document |
| chatId | string | — | Telegram chat ID |
| text | string | — | Message text |
Requires credential: telegram
Auto-chunking: Messages longer than 4096 characters are automatically split at newline boundaries and sent as multiple messages.
action.imap
Fetch, search, or read mailbox content over IMAP.
| Config | Type | Default | Description |
|---|---|---|---|
| action | string | fetch_recent | fetch_recent, search, read_message |
| query | string | — | Search query for search mode |
| messageId | string | — | Message identifier for read_message mode |
| maxResults | number | 20 | Maximum messages to return |
| since | string | — | Relative time filter like 1h or 7d |
| folder | string | INBOX | Mailbox folder |
| markAsRead | boolean | false | Mark fetched messages as read |
Requires credential: imap
action.rss
Fetch and parse an RSS feed.
| Config | Type | Default | Description |
|---|---|---|---|
| feedUrl | string | — | RSS feed URL |
| maxItems | number | 10 | Maximum items to return |
{ items: [{ title, link, description, pubDate }] }action.twitter
Post a tweet or interact with the Twitter API.
| Config | Type | Default | Description |
|---|---|---|---|
| action | string | post_tweet | post_tweet, search, get_user |
| text | string | — | Tweet content |
Requires credential: twitter
action.google_sheets
Read from or write to Google Sheets.
| Config | Type | Default | Description |
|---|---|---|---|
| action | string | read_rows | read_rows, append_row, update_cell |
| spreadsheetId | string | — | Spreadsheet ID from the URL |
| range | string | Sheet1!A:Z | Cell range |
Requires credential: google
action.google_drive
List, upload, or download files from Google Drive.
| Config | Type | Default | Description |
|---|---|---|---|
| action | string | list | list, upload, download, create_folder |
| maxResults | number | 10 | Max files to return |
Requires credential: google
action.gmail
Search, read, or send email via the Gmail API.
| Config | Type | Default | Description |
|---|---|---|---|
| action | string | search_messages | search_messages, read_message, send_message |
| query | string | — | Gmail search query (for search_messages) |
| messageId | string | — | Message ID (for read_message) |
| maxResults | number | 10 | Max results for search |
| to | string | — | Recipient (for send_message) |
| subject | string | — | Email subject (for send_message) |
| body | string | — | Email body (for send_message) |
Requires credential: google
action.database
Execute a SQL query against a connected database.
| Config | Type | Default | Description |
|---|---|---|---|
| query | string | — | SQL query |
| operation | string | select | select, insert, update, delete |
Requires credential: database
action.filter
Filter or transform arrays.
| Config | Type | Default | Description |
|---|---|---|---|
| arrayExpression | string | — | Expression that resolves to an array |
| condition | string | true | Filter condition |
| mode | string | filter | filter or map |
action.ai
Send a prompt to an LLM and get a response.
| Config | Type | Default | Description |
|---|---|---|---|
| prompt | string | — | The prompt (supports expressions) |
| responseFormat | string | text | text or json |
action.buffer
Full Buffer publishing pipeline: create/edit/delete posts, view queue & sent history, and publish immediately across X, Instagram, TikTok, and more.
| Config | Type | Default | Description |
|---|---|---|---|
| action | string | create_post | create_post, list_channels, get_queue, get_sent, share_now, delete_post, update_post |
| text | string | — | Post text (create_post, update_post) |
| mediaUrl | string | — | URL of media to attach |
| channelIds | array | [] | Buffer channel IDs to publish to (create_post) |
| scheduledAt | string | — | ISO timestamp to schedule the post |
| shorten | boolean | true | Shorten links in post text |
| profileId | string | — | Profile/channel ID (get_queue, get_sent) |
| updateId | string | — | Buffer update ID (share_now, delete_post, update_post) |
| count | number | 20 | Results per page (get_queue, get_sent) |
| page | number | — | Page number for pagination |
| since | string | — | Unix timestamp — only return updates after this time |
Requires credential: buffer
action.webhook_response
Return a custom HTTP response to the webhook caller.
| Config | Type | Default | Description |
|---|---|---|---|
| statusCode | number | 200 | HTTP status code |
| body | string | — | Response body |
action.execute_workflow
Trigger another S6S workflow by slug.
| Config | Type | Default | Description |
|---|---|---|---|
| slug | string | — | Target workflow slug |
| waitForCompletion | boolean | true | Wait for the child workflow to finish |
action.stop_and_error
Immediately stop the workflow and report an error. Useful for guardrails.
| Config | Type | Default | Description |
|---|---|---|---|
| message | string | Workflow stopped | Error message surfaced in the run summary |
action.youtube
Upload videos, list channel videos, get video details, and update video metadata via the YouTube Data API.
| Config | Type | Default | Description |
|---|---|---|---|
| action | string | list_videos | upload_video, list_videos, get_video, update_video |
| videoUrl | string | — | URL of the video to upload |
| title | string | — | Video title |
| description | string | — | Video description |
| tags | array | [] | Video tags for discovery |
| privacyStatus | string | private | public, unlisted, or private |
| categoryId | string | — | YouTube video category ID |
| videoId | string | — | Video ID (for get_video / update_video) |
| maxResults | number | 10 | Max videos to return (for list_videos) |
Requires credential: google
Logic
Logic nodes control execution flow — branching, looping, timing, and parallelism.
logic.condition
Branch execution based on a condition. Has two output handles: true (green) and false (red).
| Config | Type | Default | Description |
|---|---|---|---|
| expression | string | — | Left-hand value (supports expressions) |
| operator | string | eq | Comparison operator (see below) |
| value | string | — | Right-hand value |
eqneqgtgteltltecontainsexistsnot_existsmatchesinlogic.switch
Route to different branches based on an expression's value.
| Config | Type | Default | Description |
|---|---|---|---|
| expression | string | — | Value to switch on |
| cases | array | [] | [{ value, target }] case definitions |
| defaultTarget | string | — | Fallback target if no case matches |
logic.loop
Iterate over an array, executing downstream nodes for each item.
| Config | Type | Default | Description |
|---|---|---|---|
| arrayExpression | string | — | Expression resolving to an array |
| itemVariable | string | item | Variable name for current item |
| maxIterations | number | 100 | Safety limit to prevent infinite loops |
logic.wait
Pause execution for a specified duration.
| Config | Type | Default | Description |
|---|---|---|---|
| seconds | number | 60 | Wait time in seconds |
logic.merge
Combine outputs from parallel branches into a single object. Place after parallel groups in the flow array.
| Config | Type | Default | Description |
|---|---|---|---|
| mode | string | wait_all | Merge strategy (currently wait_all) |
{ branch_a: {...}, branch_b: {...} }{
"flow": [
"fetch_data",
["branch_a", "branch_b"],
"combine",
"send_result"
]
}
// "combine" is a merge step — it waits for both
// parallel branches and merges their outputs.Conditional Execution
Any node can include a run_if expression in its config. When present, the engine evaluates it at runtime: truthy executes the node normally, falsy skips it with status skipped. Skipped nodes do not fail the run.
{
"ref": "send_alert",
"action": "telegram",
"config": {
"action": "send_message",
"chatId": "123456",
"text": "Alert: threshold exceeded",
"run_if": "{{steps.check.output.amount > 1000}}"
}
}Dynamic Integrations
Beyond the built-in action types, S6S supports a provider.action syntax for any API integration. Use this to connect to services like Notion, Pinterest, HubSpot, or any other API — S6S learns the API automatically.
| Action | Description |
|---|---|
| notion.create_page | Create a page in Notion |
| pinterest.create_pin | Create a pin on Pinterest |
| hubspot.create_contact | Create a contact in HubSpot |
| stripe.create_invoice | Create a Stripe invoice |
S6S resolves the provider and action, fetches the API schema, and handles authentication, pagination, and error retries. Learn more about dynamic integrations.
Expressions
Use {{expression}} syntax in any config field to reference data from previous steps:
| Expression | Description |
|---|---|
| {{trigger.output.body.name}} | Webhook request body field |
| {{steps.format.output.message}} | A previous step's output by ref name |
| {{steps.fetch.output.body.items[0]}} | Nested array access |
| {{run.id}} | Current run ID |
Expressions are evaluated at runtime with full access to the workflow execution context.
Need help choosing node types?
Describe what you want to automate in the chat UI and S6S will generate the right workflow for you.