GraphQL for Dummies: A Cheatsheet for Beginners
Facebook started developing GraphQL in 2012 as an internal solution to problems with REST — mainly over-fetching and under-fetching data. It was open-sourced in 2015, and is now used by companies like GitHub, Shopify, and also in Webex Contact Center.
GraphQL is a flexible way to get exactly the data you need from an API. Unlike REST, which gives you fixed results from multiple endpoints, GraphQL uses a single endpoint with customizable queries.
Note: For an introduction to GraphQL, refer to the GraphQL - 101.
Webex Contact Center supports GraphQL via the Search API. You can use it to:
- Pull tasks, agents, and queue data
- Filter by channel, wrap-up codes, and status
- Run aggregations like count, average, min, max
- Include custom fields like Reportable Global Variables
No more stitching together 5 REST calls. One query gets the job done.
We'll show how to:
- Build basic queries
- Use filters and group them
- Add aggregations
- Work with custom global variables
Let's start with how GraphQL compares to REST.
REST vs GraphQL
REST APIs give you fixed data from multiple endpoints. GraphQL gives you custom data from a single endpoint.
| Feature | REST | GraphQL |
|---|---|---|
| Endpoints | Multiple | Single |
| Data Shape | Fixed | Custom |
| Over-fetching | Common | Avoided |
| Under-fetching | Requires extra calls | Single query solves it |
| Caching | Easy (via URL) | Needs special tools |
// REST: 4 requests
await fetch('/api/users/123')
await fetch('/api/users/123/posts')
await fetch('/api/users/123/followers')
await fetch('/api/users/123/likes')
# GraphQL: 1 request
query {
user(id: 123) {
name
posts { title }
followers { count }
likes { total }
}
}
One request. One endpoint. Only the data you need.
The 3 Core Concepts of GraphQL
All GraphQL work comes down to three building blocks: schemas, queries, and mutations.
1. Schema (The Menu)
This defines what’s available. Think of it like a restaurant menu — it tells you what you can ask for.
type User {
id: ID!
name: String!
posts: [Post!]!
}
2. Query (Getting Stuff)
Use a query to fetch only what you need. Perfect
for dashboards or analytics panels.
query {
user(id: 123) {
name
posts {
title
}
}
}
3. Mutation (Changing Stuff)
Use a mutation to create or update data — like
submitting a form or changing queue config.
mutation {
createPost(title: "Hello") {
id
}
}
That’s it — if you get these three, you’re already halfway through mastering GraphQL.
Filtering with GraphQL
Filters help you narrow down the data — just like a
WHERE clause in SQL. Webex Contact Center lets
you filter by channelType,
terminationType, queueName, and even
custom global variables.
Simple Filter
Get only telephony tasks:
filter: {
channelType: { equals: telephony }
}
Compound Filter
Now let's say we want to get all telephony tasks that terminated
normally:
filter: {
and: [
{ channelType: { equals: telephony } },
{ terminationType: { equals: normal } }
]
}
Negation
Get all tasks except ones that ended normally:
filter: {
terminationType: { notequals: normal }
}
Group + Negate
Exclude email tasks that are inactive:
filter: {
not: {
and: [
{ channelType: { equals: email } },
{ isActive: { equals: false } }
]
}
}
You can combine filters and groupings to answer almost any reporting question — abandon rates, missed calls, callback durations, and more.
Aggregations with GraphQL
Aggregations summarize your data — like COUNT,
AVG, and MAX in SQL. In Webex Contact
Center, you can aggregate by any numeric field or ID.
Count of All Tasks
Let’s start with something simple:
aggregations: [
{ field: "id", type: count, name: "All Tasks" }
]
Filter Inside Aggregation
Count only telephony tasks:
aggregations: [
{
field: "id",
type: count,
name: "Telephony Calls",
filter: {
channelType: { equals: telephony }
}
}
]
Average Queue Time
Get the average time tasks spent in queue:
aggregations: [
{
field: "queueDuration",
type: average,
name: "Avg Queue Time"
}
]
Multiple Aggregations
Combine multiple aggregations for a more complete picture:
aggregations: [
{ field: "queueDuration", type: average, name: "Avg Queue" },
{ field: "queueDuration", type: max, name: "Max Queue" },
{ field: "connectedDuration", type: average, name: "Avg Talk Time" }
]
Breakdown by Group
Split counts by queue name and termination type:
tasks {
queueName
terminationType
aggregation {
name
value
}
}
Aggregations make it easy to answer big questions with small queries. You’ll use them a lot when building reports.
Using Global Variables in Queries
Webex Contact Center lets you pass data into the flow using Global Variables — and these become searchable in the GraphQL Search API.
Global Variable Types
-
stringGlobalVariables→ String (e.g. SegmentName) -
integerGlobalVariables→ Integer (e.g. Survey Score) doubleGlobalVariables→ DecimallongGlobalVariables→ DateTimebooleanGlobalVariables→ True/False flags
Returning a Global Variable
stringGlobalVariables(name:"SegmentName") {
name
value
}
Using an Alias
Clean up field names using aliases:
segment: stringGlobalVariables(name:"SegmentName") {
value
}
Filtering with Global Variables
Show only tasks where segment = "HighValue":
filter: {
stringGlobalVariables: {
name: { equals: "SegmentName" },
value: { equals: "HighValue" }
}
}
Aggregating with Global Variables
Count all calls where CampaignName = Promo2024:
aggregations: [
{
field: "id",
name: "Promo2024 Count",
type: count,
filter: {
stringGlobalVariables: {
name: { equals: "CampaignName" },
value: { equals: "Promo2024" }
}
}
}
]
You can use multiple global variables in a single query — just repeat the field type. These are incredibly useful for segmenting and tracking flows in custom dashboards.
Real Questions You Can Answer with GraphQL
Before we look at the examples: If you're familiar with GraphQL, you might expect to write queries like this:
task( from: "2024-06-01T00:00:00Z" to: "2024-06-08T00:00:00Z" ... )
That structure will fail in Webex Contact Center. The Search API is a REST-style GraphQL interface and expects:
-
The query must be wrapped in a
query { ... }block - Timestamps must be provided as epoch milliseconds (not ISO strings)
-
The full query must be embedded in a POST body under the
"query"field
Here’s the correct structure for the query body:
query {
task(
from: 1746038400000
to: 1746794400000
...
) {
tasks {
...
}
}
}
Now that you know how to build queries, here are some examples you can actually use in Webex Contact Center.
How many telephony calls did we receive in the past 7 days?
query {
task(
from: 1746038400000
to: 1746794400000
timeComparator: createdTime
filter: {
channelType: { equals: telephony }
}
aggregations: [
{ field: "id", type: count, name: "Telephony Calls" }
]
) {
tasks {
aggregation {
name
value
}
}
}
}
What’s the average and max queue time for abandoned calls?
query {
task(
from: 1746038400000
to: 1746794400000
timeComparator: createdTime
filter: {
terminationType: { equals: "abandoned" }
}
aggregations: [
{ field: "queueDuration", type: average, name: "Avg Queue Time" },
{ field: "queueDuration", type: max, name: "Max Queue Time" }
]
) {
tasks {
aggregation {
name
value
}
}
}
}
Tip: Even thoughterminationTypefeels like an enum with fixed values (e.g.,abandoned,normal), the Webex Contact Center Search API treats it as a string. Always wrap these values in double quotes — for example,terminationType: { equals: "abandoned" }.
Filter by Global Variable (e.g. Campaign)
query {
task(
from: 1746038400000
to: 1746756000000
timeComparator: createdTime
filter: {
stringGlobalVariables: {
name: { equals: "CampaignName" }
value: { equals: "Promo2024" }
}
}
) {
tasks {
id
channelType
stringGlobalVariables(name: "CampaignName") {
name
value
}
}
}
}
Show count of callbacks vs normal calls
query {
task(
from: 1744137600000 # Apr 9, 2025 00:00:00 GMT
to: 1749444000000 # Jun 9, 2025 10:00:00 GMT
timeComparator: createdTime
aggregations: [
{
field: "id"
name: "Callback Count"
type: count
filter: { isCallback: { equals: true } }
},
{
field: "id"
name: "Normal Call Count"
type: count
filter: { isCallback: { equals: false } }
}
]
) {
tasks {
aggregation {
name
value
}
}
}
}
From custom segments to agent behaviors, the GraphQL Search API gives you deep visibility into your contact center — no ETL or third-party dashboards required.
References
- Webex Contact Center: GraphQL Workbench
- Webex Contact Center: Getting Started with Search API
- Webex Contact Center API Docs (GitHub Pages)
- GraphQL Sample: Basic Reporting Queries
- GraphQL Sample: PowerBI Integration
- GraphQL.org: Learn GraphQL
- GraphQL Specification – GitHub
Tip: If you're just getting started, bookmark a few of your own working queries inside Altair or Postman. They’re faster than any documentation.
Thanks for reading. If your contact center runs on Webex, don’t sleep on GraphQL — it’s one of the fastest ways to get high-value insights with minimal backend overhead.