API

Guides

Messages

Voice

WhatsApp Business

Groups

Contacts

Outbox

Account

Sender IDs

Teammate/Subaccount

Conversations

Workflows

Message Templates

Birthday Message

Opt-out

Other

Webhooks (v2)

Create workflow

Creates a workflow as a draft (version 1). The definition is validated strictly; see Workflows for the node, edge, trigger, condition and action reference. A draft does not run yet: call Publish workflow to activate it. Nested group and team member IDs are sent as public IDs (gid_..., sub_...) and checked against your account. An account can have at most 100 workflows.

Base URL:

POST: https://api.smsgatewayapi.com/v1/flows
ParameterInputDescription
client_idAPI client IDDeveloper › API & Webhooks › API credentials
Required
client_secretAPI client secretA cs_ credential, shown once when you create it under Developer › API & Webhooks › API credentials
Required
namename of the workflow1 to 255 characters
Required
nodeslist of node objects1 to 200 nodes; a draft may have zero or one trigger node
Required
edgeslist of edge objects0 to 400 edges; always sent together with nodes
Required
viewport{ x, y, zoom }Position and zoom of the builder canvas
Optional
metaobjectFree-form data that is stored with the version
Optional
<?php
	//PHP - cURL
	$ch = curl_init();
	$url = "https://api.smsgatewayapi.com/v1/flows";
	$client_id = "XXX"; // Your API client ID (required)
	$client_secret = "YYY"; // Your API client secret (required)
	$data = [
		'name' => "STOP = opt-out", //Name of the workflow (required)
		'nodes' => [ //Nodes (required)
			["id" => "trigger", "type" => "triggerNode", "position" => ["x" => 0, "y" => 0], "data" => ["title" => "Inbound message", "config" => ["triggerType" => "inbound_message", "inboxId" => 0]]],
			["id" => "is_stop", "type" => "conditionNode", "position" => ["x" => 0, "y" => 150], "data" => ["title" => "Message is STOP?", "config" => ["conditionType" => "if", "field" => "message.body", "operator" => "equals", "value" => "STOP"]]],
			["id" => "opt_out", "type" => "actionNode", "position" => ["x" => 0, "y" => 300], "data" => ["title" => "Opt out", "config" => ["actionType" => "opt_out", "editMethod" => "opt_out"]]]
		],
		'edges' => [ //Edges (required, together with nodes)
			["id" => "e1", "source" => "trigger", "sourceHandle" => "out", "target" => "is_stop", "targetHandle" => "in"],
			["id" => "e2", "source" => "is_stop", "sourceHandle" => "true", "target" => "opt_out", "targetHandle" => "in"]
		]
]; curl_setopt($ch, CURLOPT_URL, "$url"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "X-Client-Id: $client_id", "X-Client-Secret: $client_secret", "Content-Type: application/json", ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); $response = curl_exec($ch); ?>

Example request:

{
	"name": "STOP = opt-out",
	"nodes": [
		{
			"id": "trigger",
			"type": "triggerNode",
			"position": { "x": 0, "y": 0 },
			"data": {
				"title": "Inbound message",
				"config": { "triggerType": "inbound_message", "inboxId": 0 }
			}
		},
		{
			"id": "is_stop",
			"type": "conditionNode",
			"position": { "x": 0, "y": 150 },
			"data": {
				"title": "Message is STOP?",
				"config": { "conditionType": "if", "field": "message.body", "operator": "equals", "value": "STOP" }
			}
		},
		{
			"id": "opt_out",
			"type": "actionNode",
			"position": { "x": 0, "y": 300 },
			"data": {
				"title": "Opt out",
				"config": { "actionType": "opt_out", "editMethod": "opt_out" }
			}
		}
	],
	"edges": [
		{ "id": "e1", "source": "trigger", "sourceHandle": "out", "target": "is_stop", "targetHandle": "in" },
		{ "id": "e2", "source": "is_stop", "sourceHandle": "true", "target": "opt_out", "targetHandle": "in" }
	]
}

Example success response (http status 201):

{
	"id": "flw_5d41402abc4b2a76b9719d911017c592",
	"uuid": "c0a8012e-4f5b-4d6c-8e9f-1a2b3c4d5e6f",
	"name": "STOP = opt-out",
	"status": "draft",
	"trigger_type": "inbound_message",
	"trigger_config": {
		"triggerType": "inbound_message",
		"inboxId": 0
	},
	"published_version_number": null,
	"draft_version_number": 1,
	"has_draft_changes": true,
	"published_at": null,
	"updated_at": "2026-09-08T10:15:00+02:00",
	"nodes": [
		{
			"id": "trigger",
			"type": "triggerNode",
			"position": { "x": 0, "y": 0 },
			"data": {
				"title": "Inbound message",
				"config": { "triggerType": "inbound_message", "inboxId": 0 }
			}
		},
		{
			"id": "is_stop",
			"type": "conditionNode",
			"position": { "x": 0, "y": 150 },
			"data": {
				"title": "Message is STOP?",
				"config": { "conditionType": "if", "field": "message.body", "operator": "equals", "value": "STOP" }
			}
		},
		{
			"id": "opt_out",
			"type": "actionNode",
			"position": { "x": 0, "y": 300 },
			"data": {
				"title": "Opt out",
				"config": { "actionType": "opt_out", "editMethod": "opt_out", "groupid": null }
			}
		}
	],
	"edges": [
		{ "id": "e1", "source": "trigger", "sourceHandle": "out", "target": "is_stop", "targetHandle": "in" },
		{ "id": "e2", "source": "is_stop", "sourceHandle": "true", "target": "opt_out", "targetHandle": "in" }
	],
	"viewport": null,
	"meta": null,
	"version_number": 1,
	"version_status": "draft"
}

The nodes and edges come back normalised: defaults are filled in and builder-only keys are stripped.

Example error response:

{
	"error": 164,
	"errorMsg": "Invalid flow definition: nodes.1.data.config.operator: must be one of equals, not_equals, contains, not_contains, starts_with, ends_with, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, in, not_in, is_empty, is_not_empty, is_true, is_false (+1 more, see error_info)",
	"error_info": [
		{
			"path": "nodes.1.data.config.operator",
			"message": "must be one of equals, not_equals, contains, not_contains, starts_with, ends_with, greater_than, greater_than_or_equal, less_than, less_than_or_equal, between, in, not_in, is_empty, is_not_empty, is_true, is_false"
		},
		{
			"path": "edges.1.target",
			"message": "must be the id of a node in the flow"
		}
	]
}

SMS API

Smstools
Integrate our SMS Gateway by implementing our SMS API, and add text messaging to your platform in minutes. Free trial. SMS API
5 out of 5 based on 3302 user ratings.
SMSGATEWAYAPI API1

REGISTER NOW

Discover our SMS platform today!

REGISTER