<?php// Load the workflow payload (see the cURL or JavaScript example for the full structure).$data = json_decode(file_get_contents('automation.json'), true);$ch = curl_init('https://api.autosend.com/v1/automations');curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer AS_your-project-api-key', 'Content-Type: application/json']);echo curl_exec($ch);curl_close($ch);?>
package mainimport ( "bytes" "fmt" "io" "net/http" "os")func main() { // Load the workflow payload (see the cURL or JavaScript example for the full structure). body, _ := os.ReadFile("automation.json") req, _ := http.NewRequest("POST", "https://api.autosend.com/v1/automations", bytes.NewBuffer(body)) req.Header.Set("Authorization", "Bearer AS_your-project-api-key") req.Header.Set("Content-Type", "application/json") resp, err := (&http.Client{}).Do(req) if err != nil { fmt.Println("Error:", err) return } defer resp.Body.Close() out, _ := io.ReadAll(resp.Body) fmt.Println(string(out))}
import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.URL;import java.nio.file.Files;import java.nio.file.Paths;public class CreateWorkflow { public static void main(String[] args) throws Exception { // Load the workflow payload (see the cURL or JavaScript example for the full structure). byte[] body = Files.readAllBytes(Paths.get("automation.json")); HttpURLConnection con = (HttpURLConnection) new URL("https://api.autosend.com/v1/automations").openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Authorization", "Bearer AS_your-project-api-key"); con.setRequestProperty("Content-Type", "application/json"); con.setDoOutput(true); try (OutputStream os = con.getOutputStream()) { os.write(body); } System.out.println("Response Status: " + con.getResponseCode()); }}
require 'net/http'require 'uri'uri = URI('https://api.autosend.com/v1/automations')http = Net::HTTP.new(uri.host, uri.port)http.use_ssl = truerequest = Net::HTTP::Post.new(uri.path)request['Authorization'] = 'Bearer AS_your-project-api-key'request['Content-Type'] = 'application/json'# Load the workflow payload (see the cURL or JavaScript example for the full structure).request.body = File.read('automation.json')puts http.request(request).body
Creates a new workflow automation. By default the workflow is created in draft status. Pass active: true to validate and activate it as part of the create call.
A workflow runs steps in order. Without branch steps, steps must strictly alternate wait → email, starting with wait and ending with email. Workflows containing branch steps use a more flexible graph (each step references the next via nextStepId).
Every email step must be preceded by a wait step, including email steps inside a branch. Set the wait delay to { "value": 0, "unit": "mins" } if you want the email to send immediately.
curl --request POST \ --url https://api.autosend.com/v1/automations \ --header 'Authorization: Bearer AS_your-project-api-key' \ --header 'Content-Type: application/json' \ --data '{ "name": "Branch with guard - pro vs other", "description": "Pro plan gets a 2-email sequence with a guard that routes to a merged email if plan changes mid-flight. Other plans get a single welcome email.", "active": true, "entryCriteria": { "type": "contact_property_matches_with", "filterCriteria": { "logicalOperator": "AND", "groups": [ { "field": "contactProperties.plan", "operator": "is_not_empty", "id": "filter_1", "fieldType": "string" } ] } }, "unsubscribeGroupId": "60d5ec49f1b2c72d9c8b4444", "trackingOpen": true, "trackingClick": true, "exitCriteria": { "type": "workflow_complete" }, "tags": ["onboarding", "branch-guard"], "steps": [ { "type": "wait", "delay": { "value": 2, "unit": "mins" }, "checkExitCriteria": true, "stepId": "step_wait_intro", "nextStepId": "step_email_intro" }, { "type": "email", "email": { "senderEmail": "[email protected]", "senderName": "Example Team", "projectId": "60d5ec49f1b2c72d9c8b1111", "templateName": "Welcome - intro email", "subject": "Welcome to Example!", "previewText": "Glad to have you with us.", "htmlTemplate": "<!DOCTYPE html><html><body><h1>Welcome {{firstName}}!</h1><p>Thanks for joining.</p></body></html>" }, "checkExitCriteria": true, "stepId": "step_email_intro", "nextStepId": "step_branch" }, { "stepId": "step_branch", "type": "branch", "branches": [ { "branchId": "br_pro", "label": "Pro plan", "triggerType": "contact_property_matches_with", "appliesTo": "all_branch_steps", "filterCriteria": { "logicalOperator": "AND", "groups": [ { "field": "contactProperties.plan", "operator": "equals", "value": "pro", "id": "filter_2", "fieldType": "string" } ] }, "nextStepId": "step_wait_pro", "mergeStepId": "step_wait_merged" }, { "branchId": "br_other", "label": "Catch-all", "triggerType": "contact_property_matches_with", "appliesTo": "branch_entry", "filterCriteria": { "logicalOperator": "AND", "groups": [ { "field": "contactProperties.plan", "operator": "is_not_empty", "id": "filter_3", "fieldType": "string" } ] }, "nextStepId": "step_wait_other" } ] }, { "type": "wait", "delay": { "value": 2, "unit": "mins" }, "checkExitCriteria": true, "stepId": "step_wait_pro", "parentBranchStepId": "step_branch", "parentBranchId": "br_pro", "nextStepId": "step_email_pro" }, { "stepId": "step_email_pro", "type": "email", "email": { "senderEmail": "[email protected]", "senderName": "Example Team", "projectId": "60d5ec49f1b2c72d9c8b1111", "templateName": "Welcome - pro email", "subject": "Welcome to Pro, {{firstName}}", "previewText": "Your Pro perks are ready.", "htmlTemplate": "<!DOCTYPE html><html><body><h1>Welcome to Pro, {{firstName}}!</h1><p>Your perks are ready.</p></body></html>" }, "parentBranchStepId": "step_branch", "parentBranchId": "br_pro", "nextStepId": "step_wait_pro_followup" }, { "stepId": "step_wait_pro_followup", "type": "wait", "delay": { "value": 1, "unit": "minutes" }, "parentBranchStepId": "step_branch", "parentBranchId": "br_pro", "nextStepId": "step_email_pro_followup" }, { "stepId": "step_email_pro_followup", "type": "email", "email": { "senderEmail": "[email protected]", "senderName": "Example Team", "projectId": "60d5ec49f1b2c72d9c8b1111", "templateName": "Welcome - pro follow-up", "subject": "A quick follow-up on your Pro plan", "previewText": "Tips to get the most out of Pro.", "htmlTemplate": "<!DOCTYPE html><html><body><h1>Hi {{firstName}}</h1><p>Here are a few Pro tips.</p></body></html>" }, "parentBranchStepId": "step_branch", "parentBranchId": "br_pro" }, { "stepId": "step_wait_other", "type": "wait", "delay": { "value": 2, "unit": "mins" }, "checkExitCriteria": true, "parentBranchStepId": "step_branch", "parentBranchId": "br_other", "nextStepId": "step_email_other" }, { "stepId": "step_email_other", "type": "email", "email": { "senderEmail": "[email protected]", "senderName": "Example Team", "projectId": "60d5ec49f1b2c72d9c8b1111", "templateName": "Welcome - standard email", "subject": "Welcome to Example!", "previewText": "Glad to have you with us.", "htmlTemplate": "<!DOCTYPE html><html><body><h1>Welcome {{firstName}}!</h1><p>Thanks for joining.</p></body></html>" }, "parentBranchStepId": "step_branch", "parentBranchId": "br_other" }, { "stepId": "step_wait_merged", "type": "wait", "delay": { "value": 2, "unit": "mins" }, "checkExitCriteria": true, "nextStepId": "step_email_merged" }, { "stepId": "step_email_merged", "type": "email", "email": { "senderEmail": "[email protected]", "senderName": "Example Team", "projectId": "60d5ec49f1b2c72d9c8b1111", "templateName": "Welcome - merged email", "subject": "Thanks for sticking with us, {{firstName}}", "previewText": "A wrap-up note from the team.", "htmlTemplate": "<!DOCTYPE html><html><body><h1>Thanks {{firstName}}!</h1><p>Here is your wrap-up.</p></body></html>" } } ]}'
import requestsurl = "https://api.autosend.com/v1/automations"headers = { "Authorization": "Bearer AS_your-project-api-key", "Content-Type": "application/json"}email_defaults = { "senderEmail": "[email protected]", "senderName": "Example Team", "projectId": "60d5ec49f1b2c72d9c8b1111"}payload = { "name": "Branch with guard - pro vs other", "description": "Pro plan gets a 2-email sequence with a guard. Other plans get a single welcome email.", "active": True, "entryCriteria": { "type": "contact_property_matches_with", "filterCriteria": { "logicalOperator": "AND", "groups": [ {"field": "contactProperties.plan", "operator": "is_not_empty", "id": "filter_1", "fieldType": "string"} ] } }, "unsubscribeGroupId": "60d5ec49f1b2c72d9c8b4444", "trackingOpen": True, "trackingClick": True, "exitCriteria": {"type": "workflow_complete"}, "tags": ["onboarding", "branch-guard"], "steps": [ {"type": "wait", "delay": {"value": 2, "unit": "mins"}, "checkExitCriteria": True, "stepId": "step_wait_intro", "nextStepId": "step_email_intro"}, {"type": "email", "email": {**email_defaults, "templateName": "Welcome - intro email", "subject": "Welcome to Example!", "previewText": "Glad to have you with us.", "htmlTemplate": "<!DOCTYPE html><html><body><h1>Welcome {{firstName}}!</h1></body></html>"}, "checkExitCriteria": True, "stepId": "step_email_intro", "nextStepId": "step_branch"}, {"stepId": "step_branch", "type": "branch", "branches": [ {"branchId": "br_pro", "label": "Pro plan", "triggerType": "contact_property_matches_with", "appliesTo": "all_branch_steps", "filterCriteria": {"logicalOperator": "AND", "groups": [ {"field": "contactProperties.plan", "operator": "equals", "value": "pro", "id": "filter_2", "fieldType": "string"}]}, "nextStepId": "step_wait_pro", "mergeStepId": "step_wait_merged"}, {"branchId": "br_other", "label": "Catch-all", "triggerType": "contact_property_matches_with", "appliesTo": "branch_entry", "filterCriteria": {"logicalOperator": "AND", "groups": [ {"field": "contactProperties.plan", "operator": "is_not_empty", "id": "filter_3", "fieldType": "string"}]}, "nextStepId": "step_wait_other"} ]}, {"type": "wait", "delay": {"value": 2, "unit": "mins"}, "checkExitCriteria": True, "stepId": "step_wait_pro", "parentBranchStepId": "step_branch", "parentBranchId": "br_pro", "nextStepId": "step_email_pro"}, {"stepId": "step_email_pro", "type": "email", "email": {**email_defaults, "templateName": "Welcome - pro email", "subject": "Welcome to Pro, {{firstName}}", "previewText": "Your Pro perks are ready.", "htmlTemplate": "<!DOCTYPE html><html><body><h1>Welcome to Pro!</h1></body></html>"}, "parentBranchStepId": "step_branch", "parentBranchId": "br_pro", "nextStepId": "step_wait_pro_followup"}, {"stepId": "step_wait_pro_followup", "type": "wait", "delay": {"value": 1, "unit": "minutes"}, "parentBranchStepId": "step_branch", "parentBranchId": "br_pro", "nextStepId": "step_email_pro_followup"}, {"stepId": "step_email_pro_followup", "type": "email", "email": {**email_defaults, "templateName": "Welcome - pro follow-up", "subject": "A quick follow-up on your Pro plan", "previewText": "Tips to get the most out of Pro.", "htmlTemplate": "<!DOCTYPE html><html><body><h1>Hi {{firstName}}</h1></body></html>"}, "parentBranchStepId": "step_branch", "parentBranchId": "br_pro"}, {"stepId": "step_wait_other", "type": "wait", "delay": {"value": 2, "unit": "mins"}, "checkExitCriteria": True, "parentBranchStepId": "step_branch", "parentBranchId": "br_other", "nextStepId": "step_email_other"}, {"stepId": "step_email_other", "type": "email", "email": {**email_defaults, "templateName": "Welcome - standard email", "subject": "Welcome to Example!", "previewText": "Glad to have you with us.", "htmlTemplate": "<!DOCTYPE html><html><body><h1>Welcome {{firstName}}!</h1></body></html>"}, "parentBranchStepId": "step_branch", "parentBranchId": "br_other"}, {"stepId": "step_wait_merged", "type": "wait", "delay": {"value": 2, "unit": "mins"}, "checkExitCriteria": True, "nextStepId": "step_email_merged"}, {"stepId": "step_email_merged", "type": "email", "email": {**email_defaults, "templateName": "Welcome - merged email", "subject": "Thanks for sticking with us, {{firstName}}", "previewText": "A wrap-up note from the team.", "htmlTemplate": "<!DOCTYPE html><html><body><h1>Thanks {{firstName}}!</h1></body></html>"}} ]}response = requests.post(url, json=payload, headers=headers)print(response.json())
<?php// Load the workflow payload (see the cURL or JavaScript example for the full structure).$data = json_decode(file_get_contents('automation.json'), true);$ch = curl_init('https://api.autosend.com/v1/automations');curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer AS_your-project-api-key', 'Content-Type: application/json']);echo curl_exec($ch);curl_close($ch);?>
package mainimport ( "bytes" "fmt" "io" "net/http" "os")func main() { // Load the workflow payload (see the cURL or JavaScript example for the full structure). body, _ := os.ReadFile("automation.json") req, _ := http.NewRequest("POST", "https://api.autosend.com/v1/automations", bytes.NewBuffer(body)) req.Header.Set("Authorization", "Bearer AS_your-project-api-key") req.Header.Set("Content-Type", "application/json") resp, err := (&http.Client{}).Do(req) if err != nil { fmt.Println("Error:", err) return } defer resp.Body.Close() out, _ := io.ReadAll(resp.Body) fmt.Println(string(out))}
import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.URL;import java.nio.file.Files;import java.nio.file.Paths;public class CreateWorkflow { public static void main(String[] args) throws Exception { // Load the workflow payload (see the cURL or JavaScript example for the full structure). byte[] body = Files.readAllBytes(Paths.get("automation.json")); HttpURLConnection con = (HttpURLConnection) new URL("https://api.autosend.com/v1/automations").openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Authorization", "Bearer AS_your-project-api-key"); con.setRequestProperty("Content-Type", "application/json"); con.setDoOutput(true); try (OutputStream os = con.getOutputStream()) { os.write(body); } System.out.println("Response Status: " + con.getResponseCode()); }}
require 'net/http'require 'uri'uri = URI('https://api.autosend.com/v1/automations')http = Net::HTTP.new(uri.host, uri.port)http.use_ssl = truerequest = Net::HTTP::Post.new(uri.path)request['Authorization'] = 'Bearer AS_your-project-api-key'request['Content-Type'] = 'application/json'# Load the workflow payload (see the cURL or JavaScript example for the full structure).request.body = File.read('automation.json')puts http.request(request).body
One of contact_created, contact_added_to_list, contact_property_matches_with, contact_property_changes_from_to, or event_trigger. Defaults to contact_created.
Optional filter tree applied on top of the base type. Use event.name and event.properties.* paths in event_trigger workflows; otherwise reference contact properties.
Ordered steps that contacts walk through. Each step must include a type. Linear workflows alternate wait and email; workflows containing a branch step form a graph where each step references the next via nextStepId. Every email step must be preceded by a wait step (use a delay of 0 to send immediately), including email steps inside a branch.
Required for email steps. Provide either templateId (existing template) or htmlTemplate (inline HTML, subject is required when using htmlTemplate). Optional fields: subject, previewText, senderEmail, senderName, senderReplyToEmail, senderReplyToName.
Required for branch steps. Each branch defines a triggerType (contact_property_matches_with or event_property), a filterCriteria tree, an appliesTo scope (branch_entry or all_branch_steps), a nextStepId that points to the first step on that branch, and an optional mergeStepId where the branch rejoins the main flow.
A branch step splits the workflow into multiple paths based on filterCriteria. Each branch points at its first step via nextStepId, and steps inside the branch reference back via parentBranchStepId and parentBranchId. Branches can rejoin the main flow at a shared mergeStepId.
When true, the workflow is validated and activated as part of the create call. When false or omitted, the workflow is created in draft status and must be activated separately.
Returned when the request body fails validation. Common codes include NAME_REQUIRED, INVALID_STEP_SEQUENCE, EMAIL_TEMPLATE_REQUIRED, BRANCH_BRANCHES_REQUIRED, EVENT_NAME_REQUIRED.
{ "success": false, "error": { "message": "Steps must strictly alternate wait → email starting with wait and ending with email", "code": "INVALID_STEP_SEQUENCE" }}
<?php// Load the workflow payload (see the cURL or JavaScript example for the full structure).$data = json_decode(file_get_contents('automation.json'), true);$ch = curl_init('https://api.autosend.com/v1/automations');curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer AS_your-project-api-key', 'Content-Type: application/json']);echo curl_exec($ch);curl_close($ch);?>
package mainimport ( "bytes" "fmt" "io" "net/http" "os")func main() { // Load the workflow payload (see the cURL or JavaScript example for the full structure). body, _ := os.ReadFile("automation.json") req, _ := http.NewRequest("POST", "https://api.autosend.com/v1/automations", bytes.NewBuffer(body)) req.Header.Set("Authorization", "Bearer AS_your-project-api-key") req.Header.Set("Content-Type", "application/json") resp, err := (&http.Client{}).Do(req) if err != nil { fmt.Println("Error:", err) return } defer resp.Body.Close() out, _ := io.ReadAll(resp.Body) fmt.Println(string(out))}
import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.URL;import java.nio.file.Files;import java.nio.file.Paths;public class CreateWorkflow { public static void main(String[] args) throws Exception { // Load the workflow payload (see the cURL or JavaScript example for the full structure). byte[] body = Files.readAllBytes(Paths.get("automation.json")); HttpURLConnection con = (HttpURLConnection) new URL("https://api.autosend.com/v1/automations").openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Authorization", "Bearer AS_your-project-api-key"); con.setRequestProperty("Content-Type", "application/json"); con.setDoOutput(true); try (OutputStream os = con.getOutputStream()) { os.write(body); } System.out.println("Response Status: " + con.getResponseCode()); }}
require 'net/http'require 'uri'uri = URI('https://api.autosend.com/v1/automations')http = Net::HTTP.new(uri.host, uri.port)http.use_ssl = truerequest = Net::HTTP::Post.new(uri.path)request['Authorization'] = 'Bearer AS_your-project-api-key'request['Content-Type'] = 'application/json'# Load the workflow payload (see the cURL or JavaScript example for the full structure).request.body = File.read('automation.json')puts http.request(request).body