Skip to contentSkip to navigationSkip to topbar
Page tools
Useful for sharing or LLM
Accelerate development with AI

On this page
Looking for more inspiration?Visit the

Query syntax


This document explains how to construct queries for Conversation Insights, including syntax for filtering, grouping, ordering, and pagination.


Query structure

query-structure page anchor

A query request contains the following properties:

1
{
2
"domain": "Conversations",
3
"properties": {
4
"timezone": "UTC"
5
},
6
"query": {
7
"measures": [...],
8
"dimensions": [...],
9
"filters": [...],
10
"orderBy": [...]
11
}
12
}
PropertyRequiredDescription
domainNoSet to Conversations.
propertiesNoOptional configuration. Supports timezone, any valid IANA timezone identifier (for example, America/Los_Angeles). Defaults to UTC.
queryYesThe query payload containing measures, dimensions, and filters.

Measures are aggregated values. Specify at least one measure or dimension in your query.

Example: Query total conversation countLink to code sample: Example: Query total conversation count
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 createQueryResults() {
14
const query = await client.insights.v3.query.create({
15
domain: "Conversations",
16
query: {
17
measures: ["Conversation.Count"],
18
filters: [
19
{
20
expressions: [
21
{
22
op: "GT",
23
field: "Conversation.CreatedDate",
24
values: ["2026-04-02"],
25
},
26
],
27
},
28
],
29
},
30
});
31
32
console.log(query.domain);
33
}
34
35
createQueryResults();

See Data model for available measures.


Dimensions group your results by categories. When you include dimensions, the API returns one row per unique combination of dimension values.

Example: Query conversation count by statusLink to code sample: Example: Query conversation count by status
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 createQueryResults() {
14
const query = await client.insights.v3.query.create({
15
domain: "Conversations",
16
query: {
17
measures: ["Conversation.Count"],
18
dimensions: ["Conversation.ConversationStatus"],
19
filters: [
20
{
21
expressions: [
22
{
23
op: "GT",
24
field: "Conversation.CreatedDate",
25
values: ["2026-04-02"],
26
},
27
],
28
},
29
],
30
},
31
});
32
33
console.log(query.domain);
34
}
35
36
createQueryResults();
1
{
2
"items": [
3
{ "Conversation.ConversationStatus": "ACTIVE", "Conversation.Count": "15" }
4
]
5
}

Use filters to narrow your query results. Filters use a nested structure with logical operators (AND, OR) and field expressions.

Example: Query conversation count with multiple filtersLink to code sample: Example: Query conversation count with multiple filters
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 createQueryResults() {
14
const query = await client.insights.v3.query.create({
15
domain: "Conversations",
16
query: {
17
measures: ["Conversation.Count"],
18
filters: [
19
{
20
op: "AND",
21
expressions: [
22
{
23
op: "GT",
24
field: "Conversation.CreatedDate",
25
values: ["2026-04-02"],
26
},
27
{
28
op: "EQ",
29
field: "Conversation.ConversationStatus",
30
values: ["ACTIVE"],
31
},
32
],
33
},
34
],
35
},
36
});
37
38
console.log(query.domain);
39
}
40
41
createQueryResults();

Filter structure

filter-structure page anchor

The op property specifies the operator to use. Logical operators (AND, OR) combine multiple expressions at the filter level. Field operators (EQ, NE, GT, LT, IN) compare field values within expressions.

The following logical operators are available:

OperatorDescription
ANDAll expressions must match.
ORAt least one expression must match.

The following field operators are available:

OperatorDescriptionExample
EQEquals{ "op": "EQ", "field": "Conversation.ConversationStatus", "values": ["ACTIVE"] }
NENot equals{ "op": "NE", "field": "Conversation.ConversationStatus", "values": ["CLOSED"] }
GTGreater than{ "op": "GT", "field": "Conversation.CreatedDate", "values": ["2025-01-01"] }
LTLess than{ "op": "LT", "field": "Conversation.CreatedDate", "values": ["2025-02-01"] }
INValue is in list{ "op": "IN", "field": "Conversation.ConversationStatus", "values": ["ACTIVE"] }

Combine multiple conditions with logical operators:

1
{
2
"filters": [
3
{
4
"op": "AND",
5
"expressions": [
6
{ "op": "EQ", "field": "Conversation.ConversationStatus", "values": ["ACTIVE"] },
7
{ "op": "GT", "field": "Conversation.CreatedDate", "values": ["2025-01-01"] }
8
]
9
}
10
]
11
}

Group results by time periods using time dimensions. Time dimensions use specific dimension names with granularity suffixes.

(information)

Info

All requests must include a greater than (GT) filter on the time dimension.

Example: Query conversation count grouped by dayLink to code sample: Example: Query conversation count grouped by day
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 createQueryResults() {
14
const query = await client.insights.v3.query.create({
15
domain: "Conversations",
16
query: {
17
measures: ["Conversation.Count"],
18
dimensions: ["Conversation.CreatedDate.day"],
19
filters: [
20
{
21
expressions: [
22
{
23
op: "GT",
24
field: "Conversation.CreatedDate",
25
values: ["2026-04-02"],
26
},
27
],
28
},
29
],
30
},
31
});
32
33
console.log(query.domain);
34
}
35
36
createQueryResults();

Use the following dimension names for different time groupings:

GranularityDimension nameDescription
hourConversation.CreatedDate.hourGroup by hour.
dayConversation.CreatedDate.dayGroup by day.
weekConversation.CreatedDate.weekGroup by week.
monthConversation.CreatedDate.monthGroup by month.

Use the properties.timezone field to control how time-based dimensions and groupings are evaluated. If not specified, the API defaults to UTC.

The timezone field accepts any valid Internet Assigned Numbers Authority (IANA) timezone identifier (for example, UTC, America/Los_Angeles, Europe/Berlin).

Example: Query conversation count grouped by day in a specific timezoneLink to code sample: Example: Query conversation count grouped by day in a specific timezone
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 createQueryResults() {
14
const query = await client.insights.v3.query.create({
15
domain: "Conversations",
16
query: {
17
measures: ["Conversation.Count"],
18
dimensions: ["Conversation.CreatedDate.day"],
19
filters: [
20
{
21
expressions: [
22
{
23
op: "GT",
24
field: "Conversation.CreatedDate",
25
values: ["2026-04-02"],
26
},
27
],
28
},
29
],
30
},
31
});
32
33
console.log(query.domain);
34
}
35
36
createQueryResults();

Sort results by a field in ascending or descending order:

Example: Query conversation count by status, ordered by count descendingLink to code sample: Example: Query conversation count by status, ordered by count descending
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 createQueryResults() {
14
const query = await client.insights.v3.query.create({
15
domain: "Conversations",
16
query: {
17
measures: ["Conversation.Count"],
18
dimensions: ["Conversation.ConversationStatus"],
19
filters: [
20
{
21
expressions: [
22
{
23
op: "GT",
24
field: "Conversation.CreatedDate",
25
values: ["2026-04-02"],
26
},
27
],
28
},
29
],
30
orderBy: [
31
{
32
field: "Conversation.Count",
33
direction: "DESC",
34
},
35
],
36
},
37
});
38
39
console.log(query.domain);
40
}
41
42
createQueryResults();

The orderBy property accepts the following fields:

PropertyDescription
fieldThe measure or dimension to sort by.
directionSort direction: ASC (ascending) or DESC (descending).

Use the pageSize and pageToken query parameters to paginate through results.

To set the page size, add the pageSize query parameter to your POST request. The default is 50 and the maximum is 1000.

1
curl -X POST "https://insights.twilio.com/v3/InsightsDomains/Conversations/Query?pageSize=20" \
2
-u $TWILIO_API_KEY:$TWILIO_API_SECRET \
3
-H "Content-Type: application/json" \
4
-d '{
5
"domain": "Conversations",
6
"query": {
7
"measures": ["Conversation.Count"],
8
"dimensions": ["Conversation.ConversationId"],
9
"filters": [
10
{
11
"expressions": [
12
{
13
"op": "GT",
14
"field": "Conversation.CreatedDate",
15
"values": ["2026-04-02"]
16
}
17
]
18
}
19
]
20
}
21
}'

The response includes a nextToken in the meta object. To fetch the next page, make a GET request with the pageToken query parameter:

1
curl -X GET "https://insights.twilio.com/v3/InsightsDomains/Conversations/Query?pageToken=NEXT_PAGE_TOKEN" \
2
-u $TWILIO_API_KEY:$TWILIO_API_SECRET \
3
-H "Content-Type: application/json"

To run Conversation Insights queries asynchronously, use the QueryJobs resource instead of waiting on an open connection for a response. Submit the same query payload used for the Query resource, then poll for completion and retrieve results once they're ready. This is useful when your queries are too large for a synchronous request to finish before timing out.

1
curl -X POST "https://insights.twilio.com/v3/InsightsDomains/Conversations/QueryJobs" \
2
-u $TWILIO_API_KEY:$TWILIO_API_SECRET \
3
-H "Content-Type: application/json" \
4
-d '{
5
"domain": "Conversations",
6
"query": {
7
"measures": ["Conversation.Count"],
8
"filters": [
9
{
10
"expressions": [
11
{
12
"op": "GT",
13
"field": "Conversation.CreatedDate",
14
"values": ["2026-04-02"]
15
}
16
]
17
}
18
]
19
}
20
}'

Twilio returns 202 Accepted with an operationId and a statusUrl to poll:

1
{
2
"operationId": "<OPERATION_ID>",
3
"status": "PENDING",
4
"statusUrl": "https://insights.twilio.com/v3/InsightsDomains/Conversations/QueryJobs/{operationId}",
5
"createdAt": "2026-05-25T14:30:00Z"
6
}
(information)

Info

Include an Idempotency-Key header (a client-generated UUIDv7) to safely retry a submission without creating a duplicate job. Twilio returns the original operation if the same key is submitted again within 24 hours.

Poll the statusUrl until the operation reaches a terminal state. Use the Retry-After response header to determine how long to wait between polls.

StatusDescription
PENDINGThe query is queued, not yet started.
RUNNINGThe query is executing.
COMPLETEDThe query completed. The result is ready.
FAILEDThe query failed. The response includes an error field.
CANCELLEDThe query was cancelled by a DELETE request before completion.
1
curl -X GET "https://insights.twilio.com/v3/InsightsDomains/Conversations/QueryJobs/{operationId}" \
2
-u $TWILIO_API_KEY:$TWILIO_API_SECRET \
3
-H "Content-Type: application/json"

When the query finishes, status changes to COMPLETED:

1
{
2
"operationId": "<OPERATION_ID>",
3
"status": "COMPLETED",
4
"createdAt": "2026-05-25T14:30:00Z",
5
"completedAt": "2026-05-25T14:32:17Z",
6
"statusUrl": "https://insights.twilio.com/v3/InsightsDomains/Conversations/QueryJobs/{operationId}",
7
"resultUrl": "https://insights.twilio.com/v3/InsightsDomains/Conversations/QueryJobs/{operationId}/Results",
8
"resultId": "<OPERATION_ID>",
9
"resultRetentionPeriod": "P7D"
10
}

Once status is COMPLETED, retrieve results from the Results resource. Results remain available for the resultRetentionPeriod shown above, and support the same pageSize and pageToken pagination as the synchronous Query resource.

1
curl -X GET "https://insights.twilio.com/v3/InsightsDomains/Conversations/QueryJobs/{operationId}/Results" \
2
-u $TWILIO_API_KEY:$TWILIO_API_SECRET \
3
-H "Content-Type: application/json"

The response has the same structure as the synchronous Query response:

1
{
2
"domain": "Conversations",
3
"items": [
4
{ "Conversation.Count": "48213" }
5
],
6
"meta": {
7
"key": "items",
8
"nextToken": null,
9
"pageSize": 50,
10
"previousToken": null
11
}
12
}

To stop a PENDING or RUNNING operation, make a DELETE request to the operation's URL. Poll the operation status to confirm it reaches the terminal CANCELLED state.

1
curl -X DELETE "https://insights.twilio.com/v3/InsightsDomains/Conversations/QueryJobs/{operationId}" \
2
-u $TWILIO_API_KEY:$TWILIO_API_SECRET \
3
-H "Content-Type: application/json"

Explore the following resources to learn more:

  • Aggregate conversation data
  • Data model: See all available measures and dimensions.