# Conversation Intelligence quickstart

In this quickstart, you'll build an end-to-end implementation that analyzes voice conversations in real-time and delivers insights to your application. You'll use [Twilio Agent Connect (TAC)](/docs/conversations/agent-connect), a Python SDK that wires Twilio's Conversation Memory, Conversation Orchestrator, and Conversation Intelligence primitives into your AI application.

By the end of this quickstart:

* You'll call a Twilio phone number and talk to an AI-powered customer (GPT-4o)
* A browser dashboard will show real-time script adherence checkpoints as you follow an example support script
* A summary will appear automatically when the call ends

> \[!NOTE]
>
> Conversation Intelligence supports multiple channels, including Voice, SMS, RCS, and WhatsApp. This quickstart focuses on Voice to demonstrate the core concepts.

## How the quickstart application works

The following diagram illustrates the architecture of the quickstart application and how Conversation Intelligence works with TAC:

```text
Phone call (PSTN)
  └── Twilio routes to /tac/twiml (Conversation Relay)

FastAPI Server (server.py)
  ├── /tac/*             → TAC VoiceChannel (Conversation Relay WebSocket)
  ├── /webhook/cintel    → receives Script Adherence + Summary results
  └── /api/events        → SSE stream to browser dashboard

TAC VoiceChannel
  └── Conversation Relay ↔ WebSocket ↔ TAC ↔ handle_message_ready()
                                             └── OpenAI GPT-4o (AI customer)

Twilio Conversation Intelligence
  ├── Script Adherence operator  → fires per utterance → /webhook/cintel → SSE checkpoint-update
  └── Summary operator           → fires on call end   → /webhook/cintel → SSE summary-update
```

## How Conversation Relay works with Conversations

When a call arrives, Twilio sends an HTTP request to the voice webhook on your TAC server. TAC responds with TwiML that includes a `<ConversationRelay>` verb with your Conversation Configuration ID:

```xml
<Response>
  <Connect>
    <ConversationRelay
      url="wss://your-domain.ngrok.io/ws"
      conversationConfiguration="conv_configuration_xxx" />
  </Connect>
</Response>
```

Twilio reads the `conversationConfiguration` attribute and automatically creates a Conversation in the Conversation Orchestrator, adds the caller as a participant, and opens a WebSocket connection to your server for the audio stream. From that point, Twilio handles transcription and streams each utterance to TAC over the WebSocket. TAC invokes your `handle_message_ready` callback with the transcribed text, and your response is sent back through the same WebSocket as synthesized speech. This means you never call the Conversations API directly. Passing the ID in TwiML is sufficient for Twilio to manage the entire conversation lifecycle.

## Billing

This quickstart uses the following billable products in addition to Conversation Intelligence operator charges:

* Conversation Relay
* Inbound voice minutes
* Phone numbers

> \[!NOTE]
>
> All upgraded Twilio accounts receive \[Post-upgrade free units (PUFU)] that apply automatically before any charges.

Learn more about [Conversation Intelligence billing](/docs/conversations/intelligence/understanding-billing) and [Twilio Voice pricing](https://www.twilio.com/en-us/voice/pricing).

## Prerequisites

Before you begin, complete the following prerequisites:

* [Sign up for Twilio](https://www.twilio.com/try-twilio) and buy a Twilio phone number with voice capabilities.
* [Get an OpenAI API key](https://platform.openai.com/signup) for the conversational AI agent.
* [Install Python 3.10+](https://www.python.org/downloads/).
* [Install uv](https://docs.astral.sh/uv/getting-started/installation/).
* [Install and set up ngrok](https://ngrok.com/).
* [Install Git](https://git-scm.com/downloads/).

## Clone the repository

In a terminal, clone the quickstart application repository and navigate to the project directory:

```bash
git clone --branch feature/cintel-quickstart https://github.com/twilio/twilio-agent-connect-python.git
cd twilio-agent-connect-python
```

## Start ngrok

To start ngrok and create a tunnel to your localhost, run:

```bash
ngrok http 3340
```

> \[!NOTE]
>
> To use your custom ngrok domain and avoid VPN blocking issues, run `ngrok http 3340 --domain=your-domain.ngrok.app`.

The ngrok console displays your forwarding URL (for example, `https://your-domain.ngrok.app` or `https://abc123.ngrok.app`).

## Run the setup wizard

The TAC setup wizard provisions all required Twilio resources and configures your phone number automatically.

1. From the repo root, run:

```bash
make setup
```

2. In a browser, open [http://localhost:8080](http://localhost:8080).
3. Under **Twilio Credentials**, enter your Twilio credentials (API key SID, API key secret, Account SID, Auth token) and your Twilio phone number in E.164 format.
4. Under **Memory Store**, select a memory store. If you want to create a new one, click **Create New** and enter a **Display name** and **Description** for the memory store, then click **Create**.
5. Under **Conversation Configuration**, enter a **Display name** and **Description**.
6. Enter your **ngrok domain** (without `https://`) and **OpenAI API key**.
7. Under **Profile Information**, enter **Email** and **Phone number**.
8. Click **Set Up Services**.

   The wizard creates:

   * **Memory store**: Stores customer memory and conversation history
   * **Conversation configuration**: Captures inbound voice calls to your number and links to the memory store and intelligence configuration
9. Click **Detect ngrok Tunnel**.
10. Click **Create Intelligence Configuration & Configure phone number**.

    The wizard creates an Intelligence Configuration with two operators:

    * **Script Adherence** (trigger: `on: COMMUNICATION`): Evaluates agent speech against a preset support script in real-time. Sends results to `https://<ngrok-domain>/webhook/cintel`.
    * **Summary** (trigger: `on: CONVERSATION_END`): Generates a post-call summary. Sends results to the same webhook.

    The wizard also configures your Twilio phone number's voice webhook to `https://<ngrok-domain>/tac/twiml` so incoming calls are handled by the demo server.

When the wizard completes, it displays all required environment variable values. Copy them.

## Configure the application

To configure the application, create a `.env` file in the `getting_started/examples/cintel` directory:

```bash
cd getting_started/examples/cintel
cp .env.example .env
```

Paste the setup wizard output into `.env`.

```text title=".env"
INTELLIGENCE_CONFIG_SID=intelligence_configuration_xxx
WEBHOOK_BASE_URL=https://abc123.ngrok-free.app

# From Step 1:
MEMORY_STORE_SID=mem_store_xxx

# From Step 2:
CONVERSATION_CONFIGURATION_ID=conv_configuration_xxx

# Twilio credentials
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_API_KEY=SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_API_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_PHONE_NUMBER=+1xxxxxxxxxx

# Voice
TWILIO_TAC_VOICE_PUBLIC_DOMAIN=abc123.ngrok-free.app

# OpenAI
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Server
PORT=3340
ENV=development
```

## Install dependencies and run the app

Install the demo application's Python dependencies, then start the local development server:

```bash
make install
make dev
```

Open [http://localhost:3340](http://localhost:3340). You'll see a dashboard with two panels:

* Live transcript
* Script checkpoints

## Test your application

Call the phone number shown in the dashboard banner. An AI customer (GPT-4o playing a frustrated internet subscriber) will answer. Follow the Owl Internet support script:

| Checkpoint             | What to say                                                                        |
| ---------------------- | ---------------------------------------------------------------------------------- |
| Greeting               | "Hi, this is \[your name] calling from Owl Internet"                               |
| Identity verification  | "Can I get your account number to pull up your information?"                       |
| Resolution steps       | "Let me trigger a remote modem reset for you"                                      |
| Brand-approved closing | "Thank you for choosing Owl Internet. Is there anything else I can help you with?" |

Watch the checkpoints turn green in real-time as you follow each step. After you hang up, the summary appears automatically in the right panel.

### View results in Twilio Console

You can also view the operator results in Twilio Console.

1. In [Twilio Console](https://1console.twilio.com), go to **Products & services** > **Conversation Intelligence** > **Intelligence configurations**.
2. Select your configuration, then open the **Conversations** tab.
3. Click a conversation to view its operator results.

### Example results

```text title="Example: checkpoint-update event"
"categories": [
  {
    "category_key": "greeting",
    "criteria": [
      {
        "criteria_key": "introduce_yourself",
        "criteria_met": "Failed"
      }
    ]
  },
  ...
]
```

```text title="Example: summary-update event"
{
  "summary_text": "Customer called about recurring internet disconnections. Agent followed the full support script and resolved the issue by triggering a remote modem reset.",
  "key_points": ["Internet disconnecting every few hours", "Remote modem reset resolved issue"]
}
```

## Troubleshooting

See the following common issues and resolutions.

### Checkpoints not updating

1. Verify ngrok is running and `TWILIO_TAC_VOICE_PUBLIC_DOMAIN` in `.env` matches the current domain.
2. In [Twilio Console](https://1console.twilio.com), go to **Develop** > **Troubleshoot** > **Debugger** to see failed webhook deliveries to `/webhook/cintel`.
3. Go to **Products & services** > **Conversation Intelligence**. Click your configuration, then click the **Conversations** tab to confirm operators ran.

### ngrok domain changed

1. In `.env`, update `TWILIO_TAC_VOICE_PUBLIC_DOMAIN`.
2. Re-run the setup wizard to update both the Intelligence Configuration webhook URL and the phone number voice webhook.
3. To restart the server, run `make dev`.

### AI customer not responding

1. In `.env`, verify `OPENAI_API_KEY` is valid (starts with `sk-`).
2. Check server logs for OpenAI errors.

## Next steps

* To build tailored analysis for your use case, [create custom language operators](/docs/conversations/intelligence/create-custom-language-operators).
* Learn how to [integrate results with your application](/docs/conversations/intelligence/integrate-results-with-application).
* Explore [language operator results](/docs/conversations/intelligence/explore-language-operator-results).
* Learn more about [TAC](/docs/conversations/agent-connect).
