Automations
Create, read, change and activate automations programmatically. An automation runs **actions** (apply a tag, move a stage, send a WhatsApp message, create a task, call a webhook…) when a **trigger** happens (lead created, message received, stage changed, date, recurrence…). Reading requires the `automations:read` permission; writing requires `automations:write`.
https://app.syncro.chat/api/v1AuthX-API-Key: crm_SUA_CHAVE_AQUIKey concepts
- Two write formats. You can send the automation as flat (recommended) —
{name, trigger_type, trigger_config, conditions, actions}— and the server builds the graph; or as graph —{name, nodes, edges}— faithful to the visual editor.GET /automations/{id}always returns both insidespec, and that same object is accepted back on POST/PUT. - It starts inactive. Every automation created through the API starts disabled (
is_active: false). Activating it is a separate step (PATCH /automations/{id}/toggle) — activation has real-world effects (the automation starts sending WhatsApp messages to customers). Confirm with the user before activating. - Dry-run with
validate_only. Send"validate_only": trueon any POST/PUT for a dry-run: the API validates and returnserrors/warningswithout saving anything (always answers200). - Strict validation. An invalid spec returns 422 with
errors: [{ path, code, message }]pointing at the exact field to fix (e.g.actions[0].config.tags).
List automations
/automationsautomations:readPaginated. Filters via query string.
Query parameters
is_activebooleanoptionaltrigger_typestringoptionalGET /automations/capabilities)searchstringoptionalpageintegeroptionalper_pageintegeroptional30, max 100)curl "https://app.syncro.chat/api/v1/automations?is_active=true" \ -H "X-API-Key: crm_SUA_CHAVE_AQUI"
{
"success": true,
"data": [
{
"id": 42,
"name": "Etiquetar novos leads",
"trigger_type": "lead_created",
"is_active": true,
"run_count": 128,
"last_run_at": "2026-07-19T14:03:11-03:00",
"updated_at": "2026-07-18T09:20:00-03:00"
}
],
"meta": {
"total": 1,
"per_page": 30,
"current_page": 1,
"last_page": 1,
"has_more": false
}
}Fetch one automation
/automations/42automations:readReturns the status + the re-importable spec (flat + graph).
curl "https://app.syncro.chat/api/v1/automations/42" \ -H "X-API-Key: crm_SUA_CHAVE_AQUI"
{
"success": true,
"data": {
"id": 42,
"is_active": true,
"run_count": 128,
"last_run_at": "2026-07-19T14:03:11-03:00",
"updated_at": "2026-07-18T09:20:00-03:00",
"spec": {
"name": "Etiquetar novos leads",
"trigger_type": "lead_created",
"trigger_config": {},
"conditions": [],
"actions": [
{
"type": "add_tag_lead",
"config": {
"tags": [
"Novo"
]
}
}
],
"nodes": [],
"edges": []
}
}
}Create an automation
/automationsautomations:writeFlat format (recommended). The automation starts inactive.
Body parameters
namestringrequiredtrigger_typestringrequiredlead_created)actionsarrayrequired{ "type": "...", "config": { ... } }trigger_configobjectoptionalGET /automations/capabilities)conditionsarrayoptional{ "field": "...", "operator": "...", "value": "..." }validate_onlybooleanoptionalerrors/warnings without saving anythingEach action is shaped as { "type": "...", "config": { ... } }.
Each condition (optional) is shaped as { "field": "message_body", "operator": "contains", "value": "orçamento" }.
Sending a name that already exists returns 422 name_conflict — POST never overwrites; use PUT to change it.
curl -X POST "https://app.syncro.chat/api/v1/automations" \
-H "X-API-Key: crm_SUA_CHAVE_AQUI" \
-H "Content-Type: application/json" \
-d '{
"name": "Etiquetar novos leads",
"trigger_type": "lead_created",
"trigger_config": {},
"conditions": [],
"actions": [
{
"type": "add_tag_lead",
"config": {
"tags": [
"Novo"
]
}
}
]
}'{
"success": true,
"warnings": [],
"data": {
"id": 57,
"is_active": false,
"run_count": 0,
"last_run_at": null,
"updated_at": "2026-07-20T10:00:00-03:00",
"spec": {}
}
}Simulate before saving (`validate_only`)
Send "validate_only": true on any POST/PUT: the API validates the spec and returns errors/warnings without saving anything (always answers 200).
curl -X POST "https://app.syncro.chat/api/v1/automations" \
-H "X-API-Key: crm_SUA_CHAVE_AQUI" -H "Content-Type: application/json" \
-d '{ "name": "Teste", "trigger_type": "lead_created",
"actions": [ { "type": "add_tag_lead", "config": {} } ],
"validate_only": true }'
{
"success": true,
"valid": false,
"mode": "flat",
"errors": [
{ "path": "actions[0].config.tags", "code": "missing_config_key", "message": "Action \"add_tag_lead\" requires config key \"tags\" (string[])." }
],
"warnings": []
}
Update an automation
/automations/42automations:writeReplaces the whole spec (send the complete object; do a GET first). It does not change is_active (activation happens only through the toggle).
curl -X PUT "https://app.syncro.chat/api/v1/automations/42" \
-H "X-API-Key: crm_SUA_CHAVE_AQUI" \
-H "Content-Type: application/json" \
-d '{
"name": "Etiquetar novos leads",
"trigger_type": "lead_created",
"trigger_config": {},
"conditions": [],
"actions": [
{
"type": "add_tag_lead",
"config": {
"tags": [
"Novo"
]
}
}
]
}'Activate / deactivate
/automations/57/toggleautomations:writeOptional body { "is_active": true } (omitted = flips the current state).
Activation has real-world effects: the automation starts sending messages to customers. Confirm with the user beforehand.
curl -X PATCH "https://app.syncro.chat/api/v1/automations/57/toggle" \
-H "X-API-Key: crm_SUA_CHAVE_AQUI" \
-H "Content-Type: application/json" \
-d '{
"is_active": true
}'{
"success": true,
"id": 57,
"is_active": true
}Delete
/automations/57automations:writecurl -X DELETE "https://app.syncro.chat/api/v1/automations/57" \ -H "X-API-Key: crm_SUA_CHAVE_AQUI"
{
"success": true
}Discover what is valid
/automations/capabilitiesautomations:readReturns, in a machine-readable form, all accepted triggers, actions and config keys (the same source the validator uses — the docs never go stale). Always check this endpoint before assembling an automation.
curl "https://app.syncro.chat/api/v1/automations/capabilities" \ -H "X-API-Key: crm_SUA_CHAVE_AQUI"
Available triggers and actions
Available triggers (17): message_received, conversation_created, lead_created, lead_stage_changed, lead_won, lead_lost, date_field, recurring, task_created, task_due_soon, calendar_event_created, calendar_event_canceled, calendar_event_starting_soon, appointment_confirmed, appointment_declined, stage_no_reply, stage_recurring.
Available actions (27): add_tag_lead, remove_tag_lead, add_tag_conversation, move_to_stage, set_lead_source, assign_to_user, assign_random_user, add_note, assign_ai_agent, assign_chatbot_flow, transfer_to_department, close_conversation, set_utm_params, create_task, enroll_sequence, ai_extract_fields, send_webhook, notify_user, send_whatsapp_message, send_whatsapp_group_message, schedule_whatsapp_message, send_whatsapp_notification, transfer_conversation, send_whatsapp_list, send_whatsapp_template (Official API only), send_whatsapp_buttons (Official API only), send_instagram_message.
List ready-made templates
/automations/templatesautomations:readLists the official templates.
curl "https://app.syncro.chat/api/v1/automations/templates" \ -H "X-API-Key: crm_SUA_CHAVE_AQUI"
Install a template
/automations/templates/etiquetar-novos-leads/installautomations:writeInstalls an official template (idempotent by name; installed inactive).
curl -X POST "https://app.syncro.chat/api/v1/automations/templates/etiquetar-novos-leads/install" \ -H "X-API-Key: crm_SUA_CHAVE_AQUI"
Error format
Every rejected write returns 422 with:
{
"success": false,
"message": "Automation spec failed validation. Fix the errors and retry (or use validate_only:true to iterate).",
"errors": [ { "path": "actions[0].config.tags", "code": "missing_config_key", "message": "…" } ],
"warnings": []
}
Common codes: invalid_trigger, unknown_action, missing_config_key, fk_not_found, name_conflict, duplicate_handle, limit_reached. Warnings (non-blocking): unknown_token, unreachable_node.