> ## Documentation Index
> Fetch the complete documentation index at: https://docs.connectly.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Invoke Sofia AI

> Call the Sofia AI sales assistant with a customer message and receive a streaming AI-generated response 🦾

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.

<Note>
  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`.
</Note>

## Endpoint

```json theme={null}
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).

```text theme={null}
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:

<Steps>
  <Step title="Init">
    Call [POST /agent\_graph/init](/ai/agent-graph/init-session) with your `businessId` and `clientKey` to receive a `sessionId`.
  </Step>

  <Step title="Invoke">
    Call this endpoint with the `sessionId` and your `inputEvents` to send a customer message and receive the agent's reply.
  </Step>

  <Step title="Close">
    Call [POST /agent\_graph/close](/ai/agent-graph/close-session) with the `sessionId` when the conversation ends.
  </Step>
</Steps>

***

## Request body

<ParamField body="businessId" type="string" required>
  The `business_id` provided by Connectly for your Sofia AI integration.
</ParamField>

<ParamField body="clientKey" type="string" required>
  A unique identifier for the customer. Use a stable ID from your system so you can correlate sessions with users.
</ParamField>

<ParamField body="sessionId" type="string" required>
  The session ID returned by the [init endpoint](/ai/agent-graph/init-session).
</ParamField>

<ParamField body="agentId" type="string">
  Your `agent_descriptor_id` — provided by Connectly during onboarding. Identifies the Sofia agent configuration to use.
</ParamField>

<ParamField body="inputEvents" type="array" required>
  The events to send to the agent. For a standard text interaction, include a single `messageEvent` with the customer's text.

  <Expandable title="messageEvent (text)">
    ```json theme={null}
    {
      "messageEvent": {
        "role": "USER",
        "content": {
          "textContent": {
            "text": "I'm looking for a running shoe under $100"
          }
        }
      }
    }
    ```
  </Expandable>

  For the full list of supported event types — button responses, list replies, form submissions, store events — see [Invoke (stream)](/ai/agent-graph/invoke-stream).
</ParamField>

***

## Response

The response is an NDJSON stream — one JSON object per line, each representing one agent response event.

<Warning>
  Do not call `response.json()` on the raw response — it will throw a parse error. Parse each line individually. See [NDJSON streaming](/ai/ndjson-streaming) for a complete guide.
</Warning>

***

## Full example (Python)

```python theme={null}
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})
```

***

## Related

<CardGroup cols={2}>
  <Card title="NDJSON streaming" icon="code" href="/ai/ndjson-streaming">
    How to correctly parse the streaming response body.
  </Card>

  <Card title="Invoke (stream) reference" icon="book" href="/ai/agent-graph/invoke-stream">
    Full parameter docs including all input and response event types.
  </Card>
</CardGroup>
