Insights Videos Blog Learning
CHEATSHEET

GraphQL for Dummies: A Cheatsheet for Beginners

A simple and practical GraphQL cheatsheet explaining key concepts like queries, mutations, and schemas. Perfect for REST developers getting started with GraphQL.

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 → Decimal
  • longGlobalVariables → DateTime
  • booleanGlobalVariables → 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 though terminationType feels 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

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.