Skip to main content
POST
/
external
/
v1
/
ai
/
agent_graph
/
invoke
Invoke Sofia AI
curl --request POST \
  --url https://api.example.com/external/v1/ai/agent_graph/invoke \
  --header 'Content-Type: application/json' \
  --data '
{
  "businessId": "<string>",
  "clientKey": "<string>",
  "sessionId": "<string>",
  "agentId": "<string>",
  "inputEvents": [
    {}
  ]
}
'
import requests

url = "https://api.example.com/external/v1/ai/agent_graph/invoke"

payload = {
"businessId": "<string>",
"clientKey": "<string>",
"sessionId": "<string>",
"agentId": "<string>",
"inputEvents": [{}]
}
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
businessId: '<string>',
clientKey: '<string>',
sessionId: '<string>',
agentId: '<string>',
inputEvents: [{}]
})
};

fetch('https://api.example.com/external/v1/ai/agent_graph/invoke', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/external/v1/ai/agent_graph/invoke",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'businessId' => '<string>',
'clientKey' => '<string>',
'sessionId' => '<string>',
'agentId' => '<string>',
'inputEvents' => [
[

]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.example.com/external/v1/ai/agent_graph/invoke"

payload := strings.NewReader("{\n \"businessId\": \"<string>\",\n \"clientKey\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"agentId\": \"<string>\",\n \"inputEvents\": [\n {}\n ]\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.example.com/external/v1/ai/agent_graph/invoke")
.header("Content-Type", "application/json")
.body("{\n \"businessId\": \"<string>\",\n \"clientKey\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"agentId\": \"<string>\",\n \"inputEvents\": [\n {}\n ]\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.example.com/external/v1/ai/agent_graph/invoke")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"businessId\": \"<string>\",\n \"clientKey\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"agentId\": \"<string>\",\n \"inputEvents\": [\n {}\n ]\n}"

response = http.request(request)
puts response.read_body
Sofia AI is built on the Agent Graph infrastructure. Invoking it uses the standard Agent Graph invoke endpoint — the only Sofia-specific value you supply is the agentId (your agent_descriptor_id) that Connectly provides during onboarding.
To set up Sofia AI for production, contact your Connectly Account Manager. They will configure your knowledge base and product catalog, then provide your agent_descriptor_id, business_id, and api_key.

Endpoint

POST https://api.connectly.ai/external/v1/ai/agent_graph/invoke

Authentication

Use the Sofia-specific API key provided by Connectly — not your general Connectly API key. Pass it in the x-api-key header (lowercase).
x-api-key: YOUR_SOFIA_API_KEY
Your Sofia api_key is scoped to inference only and is safe to use in client-side JavaScript — it cannot send WhatsApp messages or access campaign data.

Session lifecycle

Every Sofia AI conversation follows the standard Agent Graph three-step lifecycle:
1

Init

Call POST /agent_graph/init with your businessId and clientKey to receive a sessionId.
2

Invoke

Call this endpoint with the sessionId and your inputEvents to send a customer message and receive the agent’s reply.
3

Close

Call POST /agent_graph/close with the sessionId when the conversation ends.

Request body

businessId
string
required
The business_id provided by Connectly for your Sofia AI integration.
clientKey
string
required
A unique identifier for the customer. Use a stable ID from your system so you can correlate sessions with users.
sessionId
string
required
The session ID returned by the init endpoint.
agentId
string
Your agent_descriptor_id — provided by Connectly during onboarding. Identifies the Sofia agent configuration to use.
inputEvents
array
required
The events to send to the agent. For a standard text interaction, include a single messageEvent with the customer’s text.For the full list of supported event types — button responses, list replies, form submissions, store events — see Invoke (stream).

Response

The response is an NDJSON stream — one JSON object per line, each representing one agent response event.
Do not call response.json() on the raw response — it will throw a parse error. Parse each line individually. See NDJSON streaming for a complete guide.

Full example (Python)

import requests, json

BASE_URL = "https://api.connectly.ai/external/v1/ai/agent_graph"
HEADERS = {
    "x-api-key": "YOUR_SOFIA_API_KEY",
    "Content-Type": "application/json"
}
BUSINESS_ID = "your-sofia-business-id"
CLIENT_KEY  = "customer-456"
AGENT_ID    = "your-agent-descriptor-id"

# 1. Init session
init_res = requests.post(f"{BASE_URL}/init", headers=HEADERS,
    json={"businessId": BUSINESS_ID, "clientKey": CLIENT_KEY})
session_id = init_res.json()["response"]["sessionId"]

# 2. Invoke Sofia AI
invoke_res = requests.post(f"{BASE_URL}/invoke", headers=HEADERS,
    json={
        "businessId": BUSINESS_ID,
        "clientKey": CLIENT_KEY,
        "sessionId": session_id,
        "agentId": AGENT_ID,
        "inputEvents": [{
            "messageEvent": {
                "role": "USER",
                "content": {"textContent": {"text": "I'm looking for a running shoe under $100"}}
            }
        }]
    },
    stream=True
)

# 3. Parse NDJSON stream line by line
for raw_line in invoke_res.iter_lines():
    if raw_line:
        event = json.loads(raw_line.decode("utf-8"))
        print(event)

# 4. Close session
requests.post(f"{BASE_URL}/close", headers=HEADERS,
    json={"businessId": BUSINESS_ID, "clientKey": CLIENT_KEY, "sessionId": session_id})

NDJSON streaming

How to correctly parse the streaming response body.

Invoke (stream) reference

Full parameter docs including all input and response event types.