Skip to contentSkip to navigationSkip to topbar
Page toolsOn this page
Looking for more inspiration?Visit the

Conversation lifecycle


This page explains how conversations move through lifecycle states, how timeouts work, and when to close conversations.


Lifecycle states

lifecycle-states page anchor

The following table describes the three possible lifecycle states of a conversation.

StateDescription
ACTIVEAn active conversation that's receiving new communications. This is the default state when a conversation is created.
INACTIVETemporarily paused. The conversation reopens if new traffic arrives from a participant. This state is optional: you can turn it on in your conversation configuration.
CLOSEDFinalized and immutable. No new communications can be added. Any new matching traffic starts a new conversation.

State transitions

state-transitions page anchor

Conversations transition between states based on activity and configured timeouts:

Conversations move from ACTIVE to INACTIVE when the inactive timeout expires, and from INACTIVE to CLOSED when the closed timeout expires.

An INACTIVE conversation returns to ACTIVE when new traffic arrives from any participant—inbound or outbound. Traffic from a different customer starts a new conversation instead. Once CLOSED, a conversation can't be reopened: any matching traffic starts a new conversation.

You can also close conversations directly, bypassing the INACTIVE state.


Timeouts control when Conversation Orchestrator moves a conversation between states.

  • The inactive timeout is the duration from the last communication to the INACTIVE state.
  • The closed timeout is the duration from the last communication to the CLOSED state.

Both timers are measured from the last communication, not relative to entering the inactive state. Timeout values are in minutes. With {"inactive": 10, "closed": 30}, a conversation moves to inactive 10 minutes after the last communication and to closed at the 30 minute mark.

All conversations have a maximum lifespan of three years from creation, regardless of activity.

Voice timeouts behave differently

voice-timeouts-behave-differently page anchor

Voice conversations measure time from transcription events, not call events. Conversation Orchestrator doesn't receive call start or end events—it only receives transcribed utterances as communications. If a call has no speech, no communications are created, the timeout clock never starts, and the conversation stays active indefinitely.

This matters most for pre-created conversations (for example, a conversation created by Twilio Agent Connect or your own API call) where the customer never speaks. To avoid orphaned active conversations, use one of the following patterns:

  • Close immediately when the call ends (recommended): set "statusTimeouts": null on the voice channel. The conversation closes when the transcription stream ends.
  • Allow a callback window: set short timeouts, for example {"inactive": 5, "closed": 30}. A follow-up call within the window reopens the conversation and resets the timers.
(warning)

Silent calls cause stuck conversations

If a voice call produces zero transcription (silent call, immediate hangup, or transcription fails to start), the conversation remains ACTIVE indefinitely because no communication was recorded and the timeout clock never starts. Monitor for stuck conversations and close them with the API. See Close conversations with the API.

Multi-channel timeout behavior

multi-channel-timeout-behavior page anchor

When a conversation spans multiple channels (for example, voice and SMS with GROUP_BY_PROFILE):

  • Each channel's timeout applies independently to communications on that channel.
  • The conversation doesn't close until all active channels' timeouts have expired.
  • A new communication on any channel resets that channel's clock.

For example, a customer is on a voice call (statusTimeouts: null) and sends an SMS during the call (SMS statusTimeouts: {"inactive": 10, "closed": 60}). When the voice call ends, the voice channel's final transcription event closes out voice, but the SMS channel's timeout hasn't expired. The conversation remains ACTIVE until 10 minutes after the last SMS, then transitions to INACTIVE, then to CLOSED 60 minutes after the last SMS.

TTS fragmentation and voice communications

tts-fragmentation-and-voice-communications page anchor

When you use Conversation Relay, each TTS fragment is written as a separate communication, not one communication per complete agent response. A single agent utterance might produce three to five communications depending on how the TTS engine chunks the text.

This behavior has three effects:

  • Communication lists are longer than expected.
  • Intelligence operators with the COMMUNICATION trigger fire per-fragment (cost multiplier).
  • Webhook handlers (statusCallbacks) receive more events than anticipated.

This is expected behavior. If you need per-turn analysis rather than per-fragment, use the CONVERSATION_END trigger on intelligence operators instead of COMMUNICATION.

Configure timeouts when you create a conversation configuration or update them later for an existing configuration. You can set different timeout values for each channel (SMS, Voice).

ConsoleAPI

To configure timeouts using the Twilio Console, follow these steps:

  1. Sign in to the Twilio Console(link takes you to an external page).
  2. Go to Products & services > Conversation Orchestrator > Conversation Configurations.
  3. Click the name of the conversation configuration you want to update.
  4. In the Conversation lifecycle and timeouts section, click Edit.
  5. For each channel you want to configure, select a timeout option.
  6. Click Save.

Close conversations with the API

close-conversations-with-the-api page anchor

You can close conversations programmatically by sending a PUT request to the Conversations endpoint with "status": "CLOSED". See the Conversation Orchestrator API reference.

1
// Download the helper library from https://www.twilio.com/docs/node/install
2
const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";
3
4
// Find your Account SID at twilio.com/console
5
// Provision API Keys at twilio.com/console/runtime/api-keys
6
// and set the environment variables. See http://twil.io/secure
7
// For local testing, you can use your Account SID and Auth token
8
const accountSid = process.env.TWILIO_ACCOUNT_SID;
9
const apiKey = process.env.TWILIO_API_KEY;
10
const apiSecret = process.env.TWILIO_API_SECRET;
11
const client = twilio(apiKey, apiSecret, { accountSid: accountSid });
12
13
async function updateConversationById() {
14
const conversation = await client.conversations.v2
15
.conversations("CONVERSATION_ID")
16
.update({
17
status: "CLOSED",
18
});
19
20
console.log(conversation.id);
21
}
22
23
updateConversationById();

Replace CONVERSATION_ID with the conversation ID.


  • Core concepts: Learn about conversation configurations, conversations, communications, and participants.
  • Ingestion modes: Understand how messaging and voice traffic becomes part of a conversation.
  • Troubleshooting: Resolve conversations stuck in ACTIVE and other lifecycle issues.
  • Quickstart: Create your first conversation configuration.