Back to site
Syncro

Chatbots (flows)

Read, create, update and activate chatbot flows for WhatsApp, Instagram and website chat. A flow is a graph of nodes (message, question with options, condition, business hours, action, delay, end…). Reading requires `chatbots:read`; writing requires `chatbots:write`.

Base URLhttps://app.syncro.chat/api/v1AuthX-API-Key: crm_SUA_CHAVE_AQUI

Key concepts

  • Versioned envelope. The flow travels inside a single envelope object — { syncro_chatbot_flow, schema_version, channel, flow, graph } — the same one GET returns and POST/PUT accepts back.
  • Created inactive. Flows created through the API start disabled. Activating one (PATCH /chatbots/{id}/toggle) makes the bot start replying to real conversations — confirm with the user first.
  • Immutable channel. Once created, the flow's channel cannot change. A PUT with a different channel returns channel_mismatch.
  • PUT replaces the whole graph. Do a GET first and send the complete envelope.
  • validate_only: true performs a dry-run (always 200, with errors/warnings, without saving).
  • Plan features. Requires the chatbot feature enabled; the website channel also requires website_chat.

List flows

GET/chatbots
Permission: chatbots:read

Paginated. Accepts filters by channel, status and name search.

Query parameters

channelstringoptional
whatsapp, instagram or website
is_activebooleanoptional
Only active or inactive flows
searchstringoptional
Search by name
pageintegeroptional
Page
per_pageintegeroptional
Items per page
Request
curl "https://app.syncro.chat/api/v1/chatbots?channel=whatsapp&is_active=true" \
  -H "X-API-Key: crm_SUA_CHAVE_AQUI"
Response
{
  "success": true,
  "data": [
    {
      "id": 12,
      "name": "Boas-vindas",
      "channel": "whatsapp",
      "is_active": true,
      "is_catch_all": false,
      "trigger_type": "keyword",
      "trigger_keywords": [
        "oi",
        "menu"
      ],
      "whatsapp_instance_id": null,
      "completions_count": 340,
      "updated_at": "2026-07-19T18:00:00-03:00"
    }
  ],
  "meta": {
    "total": 1,
    "per_page": 30,
    "current_page": 1,
    "last_page": 1,
    "has_more": false
  }
}

Fetch a flow

GET/chatbots/12
Permission: chatbots:read

Returns the flow status plus the re-importable envelope.

Request
curl "https://app.syncro.chat/api/v1/chatbots/12" \
  -H "X-API-Key: crm_SUA_CHAVE_AQUI"
Response
{
  "success": true,
  "data": {
    "id": 12,
    "is_active": true,
    "is_catch_all": false,
    "whatsapp_instance_id": null,
    "completions_count": 340,
    "updated_at": "2026-07-19T18:00:00-03:00",
    "envelope": {
      "syncro_chatbot_flow": true,
      "schema_version": 1,
      "channel": "whatsapp",
      "flow": {
        "name": "Boas-vindas",
        "channel": "whatsapp",
        "trigger_type": "keyword",
        "trigger_keywords": [
          "oi",
          "menu"
        ]
      },
      "graph": {
        "nodes": [],
        "edges": []
      }
    }
  }
}

Create a flow

POST/chatbots
Permission: chatbots:write

The flow is created inactive. Use PATCH /chatbots/{id}/toggle to activate it afterwards.

Body parameters

envelopeobjectrequired
Versioned envelope { syncro_chatbot_flow, schema_version, channel, flow, graph }
whatsapp_instance_idintegeroptional
WhatsApp instance linked to the flow
is_catch_allbooleanoptional
Fallback flow for the channel
validate_onlybooleanoptional
*Dry-run*: validates and returns errors/warnings without saving
Request
curl -X POST "https://app.syncro.chat/api/v1/chatbots" \
  -H "X-API-Key: crm_SUA_CHAVE_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "envelope": {
      "syncro_chatbot_flow": true,
      "schema_version": 1,
      "channel": "whatsapp",
      "flow": {
        "name": "Boas-vindas",
        "channel": "whatsapp",
        "trigger_type": "keyword",
        "trigger_keywords": [
          "oi",
          "menu"
        ]
      },
      "graph": {
        "nodes": [
          {
            "id": "n1",
            "type": "message",
            "position": {
              "x": 300,
              "y": 200
            },
            "data": {
              "text": "Olá! Como posso ajudar?"
            }
          },
          {
            "id": "n2",
            "type": "end",
            "position": {
              "x": 600,
              "y": 200
            },
            "data": {}
          }
        ],
        "edges": [
          {
            "id": "e1",
            "source": "n1",
            "sourceHandle": "default",
            "target": "n2"
          }
        ]
      }
    }
  }'

Graph rules

  • A single start node — exactly one node with no incoming edge (it is the beginning of the flow).
  • Branches (options) use branch-N handles (hyphenated: branch-0, branch-1…), unique per node, and every branch edge needs a matching sourceHandle.
  • Runtime limits: delay from 1 to 30s; native buttons ≤ 3 (label ≤ 20 characters); lists ≤ 10 items (label ≤ 24, description ≤ 72); at most 200 nodes / 400 edges; payload ≤ 2 MB.

Update a flow

PUT/chatbots/12
Permission: chatbots:write

Replaces the whole graph. Do a GET first and send the complete envelope.

Body parameters

envelopeobjectrequired
Complete envelope — replaces all nodes and edges
validate_onlybooleanoptional
*Dry-run*: validates and returns errors/warnings without saving
i

The channel is immutable: a PUT with a channel different from the original returns channel_mismatch.

Request
curl -X PUT "https://app.syncro.chat/api/v1/chatbots/12" \
  -H "X-API-Key: crm_SUA_CHAVE_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "envelope": {
      "syncro_chatbot_flow": true,
      "schema_version": 1,
      "channel": "whatsapp",
      "flow": {
        "name": "Boas-vindas",
        "channel": "whatsapp",
        "trigger_type": "keyword",
        "trigger_keywords": [
          "oi",
          "menu"
        ]
      },
      "graph": {
        "nodes": [
          {
            "id": "n1",
            "type": "message",
            "position": {
              "x": 300,
              "y": 200
            },
            "data": {
              "text": "Olá! Como posso ajudar?"
            }
          },
          {
            "id": "n2",
            "type": "end",
            "position": {
              "x": 600,
              "y": 200
            },
            "data": {}
          }
        ],
        "edges": [
          {
            "id": "e1",
            "source": "n1",
            "sourceHandle": "default",
            "target": "n2"
          }
        ]
      }
    }
  }'

Activate / deactivate flow

PATCH/chatbots/12/toggle
Permission: chatbots:write

Send { "is_active": true }. If is_active is omitted, the current state is toggled. Activating makes the bot start replying to real conversations.

Body parameters

is_activebooleanoptional
Desired state; omitted toggles the current state
i

Activating re-checks the plan features: returns 403 if chatbot (or website_chat, on the website channel) is missing.

Request
curl -X PATCH "https://app.syncro.chat/api/v1/chatbots/12/toggle" \
  -H "X-API-Key: crm_SUA_CHAVE_AQUI" \
  -H "Content-Type: application/json" \
  -d '{
    "is_active": true
  }'

Delete flow

DELETE/chatbots/12
Permission: chatbots:write
Request
curl -X DELETE "https://app.syncro.chat/api/v1/chatbots/12" \
  -H "X-API-Key: crm_SUA_CHAVE_AQUI"
Response
{
  "success": true
}

Discover what is valid

GET/chatbots/capabilities
Permission: chatbots:read

Returns node types per channel, action subtypes, handle rules, limits and a sample envelope — it is the single source of truth for the validator. Check it before building a flow.

Request
curl "https://app.syncro.chat/api/v1/chatbots/capabilities" \
  -H "X-API-Key: crm_SUA_CHAVE_AQUI"

Node types and actions

Node types (9): message, input, condition, business_hours, action, delay, end, disable_chatbot, cards (website only).

Action subtypes (action node): change_stage, save_variable, close_conversation, send_whatsapp, add_tag, remove_tag, assign_human, assign_random_user, send_webhook, set_custom_field, assign_ai_agent, create_task, enroll_sequence, transfer_conversation, create_lead (website), redirect (website).

Error format

422 with errors: [{ path, code, message }]. E.g.: path: "graph.nodes[3].data.branches[1].handle", code: "invalid_handle".

Common codes: feature_missing, limit_reached, channel_mismatch, no_start_node, multiple_start_nodes, invalid_handle, duplicate_handle, cap_exceeded, fk_not_found, payload_too_large.