save_automation
Creates an automation. Without status it is a draft and never runs; status active runs it at once and needs the permission automations:run. Steps that call an address need webhooks:write, steps in connected apps need connections:run.
| Tool name | save_automation |
| Permission | automations:write |
readOnlyHint | false |
destructiveHint | false |
idempotentHint | true |
openWorldHint | true |
| REST call | POST /v1/automations, PATCH /v1/automations/{automation_id} |
#What it does
- Changes data in your account. It does not send messages to contacts.
- May start automations of the account, and an automation may send messages. The call itself sends nothing.
- Setting it active lets messages go to contacts later. The call itself sends nothing.
- Safe to repeat with the same idempotency_key.
#Input
The tool takes one flat object. Path, query and body fields of the REST call are merged into it.
Create automation (POST /v1/automations)
| Name | Type | Required | Description |
|---|---|---|---|
name | string | yes | Name of the automation (unique in the account, up to 60 characters). length 1 to 60 |
trigger | object | yes | What starts the automation. See get_automation_catalog for the fields of each trigger type. |
trigger.type | string | yes | Kind of trigger. one of: signup, keyword, message_received, message_sent, link_clicked, tag_added, tag_removed, contact_created, contact_updated, status_changed, note_added, date, inactivity, purchase, inbound_webhook, api_call |
trigger.keyword | string | no | keyword: the word to react to. up to 40 characters |
trigger.tag | string | no | tag_added: the tag. up to 60 characters |
trigger.link | string | no | link_clicked: part of the link address (empty means any link). up to 200 characters |
trigger.days | integer | no | inactivity: days without activity. 1 to 365 |
trigger.run_at | string | no | date: when to start, ISO 8601. up to 40 characters; format date-time |
trigger.provider | string | no | purchase: shopify or generic. one of: shopify, generic |
trigger.filters | array of object | no | inbound_webhook: only events where the field at 'path' equals 'equals' start the automation. up to 5 items |
trigger.filters[].path | string | yes | Path of the field in the event, for example values.status. up to 120 characters |
trigger.filters[].equals | string | yes | Required value. up to 200 characters |
trigger.also | array of object | no | Further triggers: any of them starts the automation (OR). up to 5 items |
trigger.also[].type | string | yes | Kind of trigger. one of: signup, message_received, message_sent, link_clicked, tag_added, tag_removed, contact_created, contact_updated, status_changed, note_added |
trigger.also[].tag | string | no | tag_added: the tag. up to 60 characters |
trigger.also[].link | string | no | link_clicked: part of the link. up to 200 characters |
steps | array of object | yes | The flow after the trigger, in the order of execution. up to 30 items |
steps[].type | string | yes | Kind of step. See get_automation_catalog for the fields of each kind. one of: send_message, wait, add_tag, remove_tag, start_followup, send_webhook, condition, order_filter, split, app_action, contact_match |
steps[].id | string | no | ID of the step. Keep it when you change a list of steps; new steps get one from the server. up to 64 characters |
steps[].text | string | no | send_message: the message text. Variables like {{name}} are allowed. up to 4096 characters |
steps[].title | string | no | send_message: name of the message (3 to 40 characters, unique in the automation). up to 40 characters |
steps[].button | object | no | send_message: one button. |
steps[].button.type | string | yes | quick_reply sends a reply back (up to 25 characters), url opens a link (up to 40 characters). one of: quick_reply, url |
steps[].button.text | string | yes | Label of the button. up to 40 characters |
steps[].button.url | string | no | Address for a url button (https). up to 2000 characters |
steps[].system | boolean | no | send_message: read-only. True for the confirmation message (double opt-in) that the server puts first. Ignored when you send it back. |
steps[].role | string | no | send_message: read-only. opt_in_confirmation for the message the server put first. Ignored when you send it back. up to 40 characters |
steps[].template | object | no | send_message: read-only status of the template. Ignored when you send it back. |
steps[].template.id | string or null | no | Template ID. up to 40 characters |
steps[].template.status | string | no | Approval status. up to 20 characters |
steps[].minutes | integer | no | wait: minutes to wait (1 to 525600, which is 365 days). 1 to 525600 |
steps[].only_daytime | boolean | no | wait: send only between 8 and 20 o'clock local time of the account. |
steps[].tag | string | no | add_tag, remove_tag: the tag. up to 60 characters |
steps[].sequence_id | string | no | start_followup: ID of the follow-up sequence. |
steps[].url | string | no | send_webhook: the address to call (https). Shown without secret parts (query, deeper path, user) when you read it; {{secret.NAME}} is not allowed in the address. Needs the permission webhooks:write. up to 2000 characters |
steps[].method | string | no | send_webhook: HTTP method (default POST). one of: GET, POST, PUT, PATCH, DELETE |
steps[].headers | object | no | send_webhook: extra headers. Values may use {{secret.NAME}} from the vault (names only, the value is never shown). Plain values are shown as when you read the automation (unless the key has hooks:read_secret); send back with the step id to keep the stored value. |
steps[].body | object | no | send_webhook: content with {{variables}}. Without it the call carries the automation ID, contact ID, email and phone. |
steps[].condition | object | no | Condition on a field of the event or the contact. |
steps[].condition.field | string | yes | Name of the field, for example total. up to 100 characters |
steps[].condition.op | string | yes | Comparison. gt, lt, gte, lte compare numbers; eq, neq, contains, not_contains compare text; exists checks that the field is filled; has_tag and not_has_tag check the tags of the contact. one of: gt, lt, gte, lte, eq, neq, contains, not_contains, exists, has_tag, not_has_tag |
steps[].condition.value | string or number | no | Value to compare with. Not needed for exists, has_tag and not_has_tag with the tag in 'field'. up to 200 characters; -1000000000000 to 1000000000000 |
steps[].shop | string | no | order_filter: the connected shop. one of: shopify, woocommerce |
steps[].expect | string | no | order_filter: yes continues only if the contact has ordered, no continues only if not. one of: yes, no |
steps[].since_days | integer | no | order_filter: count only orders of the last N days (0 means no time limit). 0 to 365 |
steps[].mode | string | no | split: percent distributes by share, rule takes the first branch whose condition is true, event and tag choose by event or tag. one of: percent, rule, event, tag |
steps[].app | string | no | app_action: name of the connected app. up to 40 characters |
steps[].tool | string | no | app_action: ID of the action of the app. up to 100 characters |
steps[].intent | string | no | app_action: the wish in a few words, if you do not know the tool. up to 200 characters |
steps[].args | object | no | app_action: fields of the action with {{variables}}. |
steps[].match_key | string | no | contact_match: the field used to find the contact in the app. one of: phone, email |
steps[].data | object | no | contact_match: fields to write in the app with {{variables}}. |
steps[].note | string | no | contact_match: optional note with {{variables}}. up to 500 characters |
steps[].branches | array of object | no | split: 2 to 6 branches. up to 6 items |
steps[].branches[].name | string | yes | Name of the branch. up to 60 characters |
steps[].branches[].percent | integer | no | mode percent: share of this branch (the shares add up to 100). 0 to 100 |
steps[].branches[].event | string | no | mode event: the event that selects this branch. up to 60 characters |
steps[].branches[].tag | string | no | mode tag: the tag that selects this branch. up to 60 characters |
steps[].branches[].condition | object | no | Condition on a field of the event or the contact. |
steps[].branches[].steps | array of object | yes | Steps of this branch (no split, no condition, no filter). up to 10 items |
rules | object | no | Rules of the automation. |
rules.max_per_contact | integer | no | Each person passes the automation at most this many times. 1 to 1000 |
rules.excluded_names | array of string | no | Contacts with these names (first name or full name) get nothing. up to 50 items |
status | string | no | draft (default when you leave it out), active or paused. one of: draft, active, paused |
Update automation (PATCH /v1/automations/{automation_id})
| Name | Type | Required | Description |
|---|---|---|---|
automation_id | string | yes | Automation ID. |
name | string | no | New name. length 1 to 60 |
trigger | object | no | What starts the automation. See get_automation_catalog for the fields of each trigger type. |
trigger.type | string | yes | Kind of trigger. one of: signup, keyword, message_received, message_sent, link_clicked, tag_added, tag_removed, contact_created, contact_updated, status_changed, note_added, date, inactivity, purchase, inbound_webhook, api_call |
trigger.keyword | string | no | keyword: the word to react to. up to 40 characters |
trigger.tag | string | no | tag_added: the tag. up to 60 characters |
trigger.link | string | no | link_clicked: part of the link address (empty means any link). up to 200 characters |
trigger.days | integer | no | inactivity: days without activity. 1 to 365 |
trigger.run_at | string | no | date: when to start, ISO 8601. up to 40 characters; format date-time |
trigger.provider | string | no | purchase: shopify or generic. one of: shopify, generic |
trigger.filters | array of object | no | inbound_webhook: only events where the field at 'path' equals 'equals' start the automation. up to 5 items |
trigger.filters[].path | string | yes | Path of the field in the event, for example values.status. up to 120 characters |
trigger.filters[].equals | string | yes | Required value. up to 200 characters |
trigger.also | array of object | no | Further triggers: any of them starts the automation (OR). up to 5 items |
trigger.also[].type | string | yes | Kind of trigger. one of: signup, message_received, message_sent, link_clicked, tag_added, tag_removed, contact_created, contact_updated, status_changed, note_added |
trigger.also[].tag | string | no | tag_added: the tag. up to 60 characters |
trigger.also[].link | string | no | link_clicked: part of the link. up to 200 characters |
steps | array of object | no | The flow after the trigger, in the order of execution. up to 30 items |
steps[].type | string | yes | Kind of step. See get_automation_catalog for the fields of each kind. one of: send_message, wait, add_tag, remove_tag, start_followup, send_webhook, condition, order_filter, split, app_action, contact_match |
steps[].id | string | no | ID of the step. Keep it when you change a list of steps; new steps get one from the server. up to 64 characters |
steps[].text | string | no | send_message: the message text. Variables like {{name}} are allowed. up to 4096 characters |
steps[].title | string | no | send_message: name of the message (3 to 40 characters, unique in the automation). up to 40 characters |
steps[].button | object | no | send_message: one button. |
steps[].button.type | string | yes | quick_reply sends a reply back (up to 25 characters), url opens a link (up to 40 characters). one of: quick_reply, url |
steps[].button.text | string | yes | Label of the button. up to 40 characters |
steps[].button.url | string | no | Address for a url button (https). up to 2000 characters |
steps[].system | boolean | no | send_message: read-only. True for the confirmation message (double opt-in) that the server puts first. Ignored when you send it back. |
steps[].role | string | no | send_message: read-only. opt_in_confirmation for the message the server put first. Ignored when you send it back. up to 40 characters |
steps[].template | object | no | send_message: read-only status of the template. Ignored when you send it back. |
steps[].template.id | string or null | no | Template ID. up to 40 characters |
steps[].template.status | string | no | Approval status. up to 20 characters |
steps[].minutes | integer | no | wait: minutes to wait (1 to 525600, which is 365 days). 1 to 525600 |
steps[].only_daytime | boolean | no | wait: send only between 8 and 20 o'clock local time of the account. |
steps[].tag | string | no | add_tag, remove_tag: the tag. up to 60 characters |
steps[].sequence_id | string | no | start_followup: ID of the follow-up sequence. |
steps[].url | string | no | send_webhook: the address to call (https). Shown without secret parts (query, deeper path, user) when you read it; {{secret.NAME}} is not allowed in the address. Needs the permission webhooks:write. up to 2000 characters |
steps[].method | string | no | send_webhook: HTTP method (default POST). one of: GET, POST, PUT, PATCH, DELETE |
steps[].headers | object | no | send_webhook: extra headers. Values may use {{secret.NAME}} from the vault (names only, the value is never shown). Plain values are shown as when you read the automation (unless the key has hooks:read_secret); send back with the step id to keep the stored value. |
steps[].body | object | no | send_webhook: content with {{variables}}. Without it the call carries the automation ID, contact ID, email and phone. |
steps[].condition | object | no | Condition on a field of the event or the contact. |
steps[].condition.field | string | yes | Name of the field, for example total. up to 100 characters |
steps[].condition.op | string | yes | Comparison. gt, lt, gte, lte compare numbers; eq, neq, contains, not_contains compare text; exists checks that the field is filled; has_tag and not_has_tag check the tags of the contact. one of: gt, lt, gte, lte, eq, neq, contains, not_contains, exists, has_tag, not_has_tag |
steps[].condition.value | string or number | no | Value to compare with. Not needed for exists, has_tag and not_has_tag with the tag in 'field'. up to 200 characters; -1000000000000 to 1000000000000 |
steps[].shop | string | no | order_filter: the connected shop. one of: shopify, woocommerce |
steps[].expect | string | no | order_filter: yes continues only if the contact has ordered, no continues only if not. one of: yes, no |
steps[].since_days | integer | no | order_filter: count only orders of the last N days (0 means no time limit). 0 to 365 |
steps[].mode | string | no | split: percent distributes by share, rule takes the first branch whose condition is true, event and tag choose by event or tag. one of: percent, rule, event, tag |
steps[].app | string | no | app_action: name of the connected app. up to 40 characters |
steps[].tool | string | no | app_action: ID of the action of the app. up to 100 characters |
steps[].intent | string | no | app_action: the wish in a few words, if you do not know the tool. up to 200 characters |
steps[].args | object | no | app_action: fields of the action with {{variables}}. |
steps[].match_key | string | no | contact_match: the field used to find the contact in the app. one of: phone, email |
steps[].data | object | no | contact_match: fields to write in the app with {{variables}}. |
steps[].note | string | no | contact_match: optional note with {{variables}}. up to 500 characters |
steps[].branches | array of object | no | split: 2 to 6 branches. up to 6 items |
steps[].branches[].name | string | yes | Name of the branch. up to 60 characters |
steps[].branches[].percent | integer | no | mode percent: share of this branch (the shares add up to 100). 0 to 100 |
steps[].branches[].event | string | no | mode event: the event that selects this branch. up to 60 characters |
steps[].branches[].tag | string | no | mode tag: the tag that selects this branch. up to 60 characters |
steps[].branches[].condition | object | no | Condition on a field of the event or the contact. |
steps[].branches[].steps | array of object | yes | Steps of this branch (no split, no condition, no filter). up to 10 items |
rules | object | no | Rules of the automation. |
rules.max_per_contact | integer | no | Each person passes the automation at most this many times. 1 to 1000 |
rules.excluded_names | array of string | no | Contacts with these names (first name or full name) get nothing. up to 50 items |
Arguments added by the MCP server (see Special arguments)
| Name | Type | Required | Description |
|---|---|---|---|
idempotency_key | string | no | Optional. Unique key, for example a UUID. Same key and arguments within 24 hours: first result. Without a key only an identical call within 1 minute counts as a repeat. up to 255 characters |
#Result
The result has the same content as the REST answer. Lists have at most 50 items per page (default 20); use cursor for the next page.
Errors come back as a tool result with isError: true. The error codes are the ones in Errors.