Using States and Timers in Conversations
With Twilio Conversations' states and timers features, you can manage, store, and archive your application's Conversations.
By using these features, your Conversations participants can focus on active (ongoing) Conversations. You can also close out old or inactive Conversations to make sure you're not exceeding the Participants-per-Conversation limit.
This guide provides an overview of states and timers, as well as how to configure them.
For the best end-user experience, we highly recommend that you read the complete Twilio Conversations documentation and tailor our general recommendations provided for your specific use case.
Info
Note: States and Timers for specific Conversations are only modifiable via the REST API. Global Timers can be configured for all Conversations created in your account through the Console under the Defaults tab.
Conversations States and Timers are default features that appear in a Conversation's Properties.
There are two configurable timers to automatically transition Conversations between active
to inactive
as well as from inactive
to closed
states.

Note: We recommend leaving the default Conversation state as active
unless you need to change it for your specific use case.
There are three ways to transition between Conversations states:
- Use a configured timer (see below). The state will change once the timer elapses.
- Manipulate state using a REST API call.
- The Conversation will automatically move from an
inactive
toactive
state when a new text or media message arrives.
A Conversation can have one of three states:
active
inactive
closed
A newly created Conversation has the active state by default. Active
and inactive
states are considered as "hot" storage and can be manipulated back and forth. The transition between these two states is instantaneous; there will be no delay.
Be aware that active
and inactive
conversations count towards the participant-per-conversation limit: 50 non-Chat (SMS, WhatsApp, etc) and up to 1000 native Chat participants.
1// Download the helper library from https://www.twilio.com/docs/node/install2const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";34// Find your Account SID and Auth Token at twilio.com/console5// and set the environment variables. See http://twil.io/secure6const accountSid = process.env.TWILIO_ACCOUNT_SID;7const authToken = process.env.TWILIO_AUTH_TOKEN;8const client = twilio(accountSid, authToken);910async function updateConversation() {11const conversation = await client.conversations.v112.conversations("CHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")13.update({ state: "inactive" });1415console.log(conversation.accountSid);16}1718updateConversation();
Response
Note: This shows the raw API response from Twilio. Responses from SDKs (Java, Python, etc.) may look a little different.1{2"sid": "CHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",3"account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",4"chat_service_sid": "ISaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",5"messaging_service_sid": "MGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab",6"friendly_name": "friendly_name",7"unique_name": "unique_name",8"attributes": "{ \"topic\": \"feedback\" }",9"date_created": "2015-12-16T22:18:37Z",10"date_updated": "2015-12-16T22:18:38Z",11"state": "inactive",12"timers": {13"date_inactive": "2015-12-16T22:19:38Z",14"date_closed": "2015-12-16T22:28:38Z"15},16"bindings": {},17"url": "https://conversations.twilio.com/v1/Conversations/CHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",18"links": {19"participants": "https://conversations.twilio.com/v1/Conversations/CHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Participants",20"messages": "https://conversations.twilio.com/v1/Conversations/CHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Messages",21"webhooks": "https://conversations.twilio.com/v1/Conversations/CHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Webhooks",22"export": "https://conversations.twilio.com/v1/Conversations/CHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Export"23}24}
The closed
state is a little bit more special: once a Conversation is closed
, it cannot be restarted. In other words, you cannot add new Participants to a Conversation in the closed
state.
If a new non-chat (e.g., SMS) message comes into closed
Conversation, a new Conversation will be auto-created with the Participant who initiated the Conversation. At this point, there is no automatic addition of other Participants, so you should add them to the newly created Conversation.
Be aware that closed
Conversations do not count towards the Conversations-per-Identity limit.
There are no default timers configured at the time of account creation. Instead, you choose whether or not to set timers for individual Conversations or a global default for all Conversations created in your account.
There are two configurable timers to transition between Conversation states:
timers.inactive
timers.closed
Timers are optional functionality, but we highly recommend enabling them to manage Conversations efficiently and avoid encountering the Conversations-per-Identity limit. Setting timers allows you to see the specific date and times when a Conversation transitions between activate
and inactive
as well as inactive
and closed
states.
All timer values are represented in ISO 8601 duration format.
In the following example, the Conversation has two timers set:
1"timers": {2"date_inactive": "2015-12-16T22:19:38Z",3"date_closed": "2015-12-16T22:28:38Z"4}
Note: If you wish to disable one or both timers, use PT0S
to set them to zero.
A few things to be aware of when configuring Conversations Timers:
- If both timers are set, they automatically support active-to-inactive and inactive-to-closed transitions
- Timers have precision of one second (1 second)
- The minimum time for the inactive timer is 60 seconds (one minute). For a closed timer, the minimum time is 600 seconds (ten minutes).
- When you manually change the state of a Conversation, for example by REST API call, the timer counter resets to zero.
1// Download the helper library from https://www.twilio.com/docs/node/install2const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";34// Find your Account SID and Auth Token at twilio.com/console5// and set the environment variables. See http://twil.io/secure6const accountSid = process.env.TWILIO_ACCOUNT_SID;7const authToken = process.env.TWILIO_AUTH_TOKEN;8const client = twilio(accountSid, authToken);910async function updateConversation() {11const conversation = await client.conversations.v112.conversations("CHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")13.update({14"timers.closed": "PT60000S",15"timers.inactive": "PT5M",16});1718console.log(conversation.accountSid);19}2021updateConversation();
Response
Note: This shows the raw API response from Twilio. Responses from SDKs (Java, Python, etc.) may look a little different.1{2"sid": "CHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",3"account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",4"chat_service_sid": "ISaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",5"messaging_service_sid": "MGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab",6"friendly_name": "friendly_name",7"unique_name": "unique_name",8"attributes": "{ \"topic\": \"feedback\" }",9"date_created": "2015-12-16T22:18:37Z",10"date_updated": "2015-12-16T22:18:38Z",11"state": "inactive",12"timers": {13"date_inactive": "2015-12-16T22:19:38Z",14"date_closed": "2015-12-16T22:28:38Z"15},16"bindings": {},17"url": "https://conversations.twilio.com/v1/Conversations/CHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",18"links": {19"participants": "https://conversations.twilio.com/v1/Conversations/CHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Participants",20"messages": "https://conversations.twilio.com/v1/Conversations/CHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Messages",21"webhooks": "https://conversations.twilio.com/v1/Conversations/CHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Webhooks",22"export": "https://conversations.twilio.com/v1/Conversations/CHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Export"23}24}
At their core, states and timers in Conversations provide basic functionality to handle customers' requests promptly and to better manage time for service providers, such as customer service agents, tutors, healthcare workers, and wealth advisors.
Examples of how to use states and timers include:
To handle inbound customer contacts, we recommend setting the inactive
timer to roughly the human attention span, or a few minutes. This way, the person fielding the inbound requests can stay focused and manage the incoming messages more efficiently. Once the inactive
timer has elapsed on a given Conversation, the new active
Conversation kicks in, waiting for a response.
To determine the timer for transitioning to the closed
state, determine the length of your average conversation; this is the best indicator of how long to wait before an inactive
Conversation should be archived and moved to closed
state.
Some use cases involve long-term relationships with your customers, such as those that a wealth manager or a personal shopper develops. In this case, you can use primarily inactive
timers. Ideally, Conversations go to the closed
state after years--rather than minutes--of inactivity so that customers are assured that their important conversations are handled with care.
Consider the following four scenarios for how to configure states and timers
With the following settings, the Conversation's state changes to inactive
if there has been no update for 300 seconds. At this point, the clock on timers.closed
starts to tick. If after 30,000 seconds, there is still no activity, the clock on timers.closed
elapses, and the Conversation state changes to closed
.
- set
timers.inactive
= 300 seconds - set
timers.closed
= 30,000 seconds
In this case, the Conversation's state never changes to inactive
because the timers.inactive
property has not been set. Likewise, the clock on timers.closed
never starts to increment because timers.closed
was also not configured. The Conversation's state is always active
.
- set
timers.inactive
= not configured - set
timers.closed
= not configured
With these settings, the Conversation never transitions to the closed
state because timers.closed
is not configured. The Conversation's state becomes inactive
if there has been no updating activity for 600 seconds; inactive
is the last possible state that the Conversation can have.
Note: Because this Conversation never achieves the closed
state, it will be always counted into Conversation-per-User limit.
- set
timers.inactive
= 600 seconds - set
timers.closed
= not configured
With these settings, the Conversation never becomes inactive
because timers.inactive
is not set. The Conversation's state remains active
for its entire duration. Finally, timers.closed
closes the Conversation after 30 days of inactivity.
- set
timers.inactive
= not configured - set
timers.closed
= 30 days
Info
Currently, you can only control the post-webhook onConversationStateUpdated
via the REST API.
With Conversations, there is no need to set any default state. All Conversations are in an active
state as soon as they are created.
We advise setting your timers and state transitions based on your unique use case, taking into account your end users' behavior and the number of Conversations you expect to create. Based on the analysis of Conversations data, we suggest the following "rule of thumb" as common values that will work for timers in many use cases:
- Transition to
inactive
after 30 days of inactivity inactive
state - Transition to
closed
after one (1) year in theinactive
state with no activity (new text or media messages)
Keep in mind that your use case may benefit from shorter timers, but the above suggestions are a good starting place.
Setting states and timers for your Conversations helps you seamlessly manage interactions with your end users based, clearing out inactivated Conversations and staying within the limits of Conversations-per-Participant.
Ready to build feature-rich Conversations? Check out the following resources: