Build an automation
You need the permissions automations:read and automations:write to read and to prepare a draft. Switching an automation on needs automations:run (a key with the level Draft cannot do it), and so does changing the trigger, the steps or the rules of an automation that is already running. Steps that call an address need webhooks:write, steps in connected apps need connections:run.
#1. Read the catalog
The catalog lists the triggers, actions and rules you can use. Build only from what is in the catalog.
curl "https://api.smartchat.marketing/v1/automation-catalog" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY"import os
import requests
response = requests.get(
"https://api.smartchat.marketing/v1/automation-catalog",
headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/automation-catalog", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
},
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (200):
{
"object": "automation_catalog",
"version": "2d26379cee484580",
"triggers": [
{
"type": "signup",
"group": "contact",
"description": "Starts when a contact signs up.",
"fields": [],
"allowed_as_further_trigger": true
}
]
}#2. Create it as a draft
An automation without a status is a draft. It does nothing yet.
curl -X POST "https://api.smartchat.marketing/v1/automations" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome after signup",
"trigger": {
"type": "signup"
},
"steps": [
{
"type": "send_message",
"text": "Hello {{name}}, nice to have you with us."
},
{
"type": "wait",
"minutes": 1440
},
{
"type": "add_tag",
"tag": "welcomed"
}
]
}'import os
import uuid
import requests
response = requests.post(
"https://api.smartchat.marketing/v1/automations",
headers={
"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"name": "Welcome after signup",
"trigger": {
"type": "signup",
},
"steps": [
{
"type": "send_message",
"text": "Hello {{name}}, nice to have you with us.",
},
{
"type": "wait",
"minutes": 1440,
},
{
"type": "add_tag",
"tag": "welcomed",
},
],
},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/automations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "Welcome after signup",
"trigger": {
"type": "signup"
},
"steps": [
{
"type": "send_message",
"text": "Hello {{name}}, nice to have you with us."
},
{
"type": "wait",
"minutes": 1440
},
{
"type": "add_tag",
"tag": "welcomed"
}
]
}),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (201):
{
"object": "automation",
"id": "aut_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
"name": "Welcome after signup",
"status": "draft",
"draft": true,
"trigger": {
"type": "signup"
},
"steps": [
{
"type": "send_message",
"id": "s_1",
"text": "Hello {{name}}, nice to have you with us.",
"template": {
"id": null,
"status": "draft"
}
},
{
"type": "wait",
"id": "s_2",
"minutes": 1440
},
{
"type": "add_tag",
"id": "s_3",
"tag": "welcomed"
}
],
"rules": {
"max_per_contact": null,
"excluded_names": []
},
"has_inbound_webhook": false,
"notices": [],
"run_count": 0,
"last_run_at": null,
"created_at": "2026-10-30T09:41:07Z",
"updated_at": "2026-10-30T09:41:07Z"
}If the automation breaks a rule of the catalog (for example it has too many steps), the answer is automation_invalid and lists every problem in errors.
#3. Switch it on
This step needs the permission automations:run. Without it the answer is 403 insufficient_scope and required_scope is automations:run. Create a key with the level All or tick the permission.
curl -X PUT "https://api.smartchat.marketing/v1/automations/aut_0f8c1a2e4b7d4c3e9a5b6d7e8f901234/status" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "active"
}'import os
import requests
response = requests.put(
"https://api.smartchat.marketing/v1/automations/aut_0f8c1a2e4b7d4c3e9a5b6d7e8f901234/status",
headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
json={
"status": "active",
},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/automations/aut_0f8c1a2e4b7d4c3e9a5b6d7e8f901234/status", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"status": "active"
}),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (200):
{
"object": "automation",
"id": "aut_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
"name": "Welcome after signup",
"status": "active",
"draft": false,
"trigger": {
"type": "signup"
},
"steps": [
{
"type": "send_message",
"id": "s_1",
"text": "Hello {{name}}, nice to have you with us.",
"template": {
"id": null,
"status": "draft"
}
},
{
"type": "wait",
"id": "s_2",
"minutes": 1440
},
{
"type": "add_tag",
"id": "s_3",
"tag": "welcomed"
}
],
"rules": {
"max_per_contact": null,
"excluded_names": []
},
"has_inbound_webhook": false,
"notices": [],
"run_count": 0,
"last_run_at": null,
"created_at": "2026-10-30T09:41:07Z",
"updated_at": "2026-10-30T09:41:07Z"
}You may switch on an automation even if a template in it is not approved yet. Messages that need the template wait until it is approved. See Drafts and activation.
#4. Watch the runs
curl "https://api.smartchat.marketing/v1/automations/aut_0f8c1a2e4b7d4c3e9a5b6d7e8f901234/runs?limit=1" \
-H "Authorization: Bearer $SMARTCHAT_API_KEY"import os
import requests
response = requests.get(
"https://api.smartchat.marketing/v1/automations/aut_0f8c1a2e4b7d4c3e9a5b6d7e8f901234/runs",
headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
params={
"limit": "1",
},
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.smartchat.marketing/v1/automations/aut_0f8c1a2e4b7d4c3e9a5b6d7e8f901234/runs?limit=1", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
},
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());Response (200):
{
"object": "list",
"data": [
{
"object": "automation_run",
"id": "run_1a2b3c4d5e6f40718293a4b5c6d7e8f9",
"automation_id": "aut_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
"status": "executed",
"created_at": "2026-10-30T09:41:07Z"
}
],
"has_more": false,
"next_cursor": null,
"url": "/v1/automations/aut_0f8c1a2e4b7d4c3e9a5b6d7e8f901234/runs"
}