---
name: azion-query-bot-manager-data-with-graphql
description: >-
  Read the classification counts Bot Manager produced, with one query against the botManagerMetrics dataset in the GraphiQL Playground.
---

# Query Bot Manager data with GraphQL

You read the classification counts of your bot traffic from the `botManagerMetrics` dataset, in the GraphiQL Playground or from any GraphQL client that sends your credentials.

`botManagerMetrics` aggregates the requests [Bot Manager](/en/documentation/platform/firewall/#bot-manager) analyzed, whether it identified them as bots or as legitimate traffic, and groups them by the action, the category, the mode, and the verdict of each one. The dataset is retained for 2 years, so a time range can reach that far back.

It carries counts, not requests. There is no score field on it, because a score belongs to a single request and is written on the report log line, which [Logs](/en/documentation/platform/firewall/bot-manager/logs/) documents. The second Bot Manager dataset, `botManagerBreakdownMetrics`, carries the URLs bot traffic reached and the addresses it came from, and it is retained for 60 days. For more information, refer to [Query the top URLs bots reach with GraphQL](/en/documentation/guides/platform/observability/query-bot-manager-breakdown-data-with-graphql/).

---

## Prerequisites

- A subscription to Bot Manager on your account. The dataset is not retrievable without one.
- A signed-in Azion session in the browser you open the Playground from. A request that carries no session returns an error message.
- Access to the [GraphiQL Playground](/en/documentation/devtools/graphql/graphql-playground/).
- A personal token, to send the query from a GraphQL client instead. The call then carries the `Authorization: Token [TOKEN VALUE]` header. For more information, refer to [Personal Tokens](/en/documentation/fundamentals/personal-tokens/).

---

## Query the classification counts

The query filters the dataset by a time range, sums `requests` per group, and returns one object per combination of the grouped fields. To run it:

1. **Open the Playground**

   Go to `https://api.azion.com/v4/metrics/graphql`.

2. **Enter the query**

   Set `begin` and `end` to the period you want to read:

   ```graphql
   query {
     botManagerMetrics(
       filter: {
         tsRange: {
           begin: "2024-09-23T15:00:00"
           end: "2024-09-23T17:00:00"
         }
       }
       aggregate: {
         sum: requests
       }
       orderBy: [ts_ASC]
       groupBy: [ts, action, botCategory, botMode, classified]
       limit: 10000
     ) {
       action
       botCategory
       botMode
       classified
       sum
     }
   }
   ```

3. **Run the query and read the response**

   The response carries one object per combination of the grouped fields, with the summed requests in `sum`:

   ```json
   {
     "data": {
       "botManagerMetrics": [
         {
           "action": "allow",
           "botCategory": "Enterprise Bot",
           "botMode": "web",
           "classified": "good bot",
           "sum": 6
         },
         {
           "action": "allow",
           "botCategory": "Brute Force",
           "botMode": "web",
           "classified": "bad bot",
           "sum": 325
         },
         {
           "action": "allow",
           "botCategory": "Bad Bot Signatures",
           "botMode": "web",
           "classified": "bad bot",
           "sum": 68
         },
         {
           "action": "allow",
           "botCategory": "Non-Bot Like",
           "botMode": "web",
           "classified": "legitimate",
           "sum": 34359
         },
         {
           "action": "redirect",
           "botCategory": "Bad Bot Signatures",
           "botMode": "web",
           "classified": "bad bot",
           "sum": 703
         },
         {
           "action": "allow",
           "botCategory": "Monitoring Bot",
           "botMode": "web",
           "classified": "good bot",
           "sum": 8
         },
         {
           "action": "allow",
           "botCategory": "Bad Bot Signatures",
           "botMode": "web",
           "classified": "under evaluation",
           "sum": 2902
         },
         {
           "action": "redirect",
           "botCategory": "Malicious Browser Behavior",
           "botMode": "web",
           "classified": "bad bot",
           "sum": 17
         },
         {
           "action": "allow",
           "botCategory": "Scripted Bots",
           "botMode": "web",
           "classified": "bad bot",
           "sum": 1
         }
       ]
     }
   }
   ```

You now have the requests Bot Manager analyzed in the period, counted by how it classified each one and by the action it applied.

---

## Query fields

| Field       | What it carries                                                                                                                       |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `filter`    | The criteria that narrow the returned data                                                                                            |
| `tsRange`   | A subfield of `filter`, with a `begin` and an `end` timestamp in the format `YYYY-MM-DDTHH:mm:ss`. For example: `2024-04-11T00:00:00` |
| `aggregate` | With `sum: requests`, the total requests evaluated in the range, after the filters apply                                              |
| `groupBy`   | The fields the results are grouped by. Every combination of their values becomes one object in the response                           |
| `orderBy`   | The order of the results. `[ts_ASC]` returns them ascending, `[ts_DESC]` descending                                                   |
| `limit`     | The maximum number of results the response carries                                                                                    |

## Response fields

| Field         | What it carries                                                                            |
| ------------- | ------------------------------------------------------------------------------------------ |
| `action`      | The action Bot Manager applied to the requests in the group. For example: `redirect`       |
| `botCategory` | The bot category identified in the request. For example: `Brute Force`                     |
| `botMode`     | The bot protection mode used in the request. For example: `web`                            |
| `classified`  | How the traffic was identified: `bad bot`, `good bot`, `legitimate`, or `under evaluation` |
| `sum`         | The requests behind that combination of grouped fields. For example: `34359`               |

`classified` and `botCategory` are independent of each other. One category, such as `Bad Bot Signatures`, can hold requests classified `under evaluation` alongside requests classified `bad bot`.

The query selects five fields, and the dataset carries more, including the host, the HTTP method, the geographic origin, and the result of a CAPTCHA challenge. For the description of every field, refer to [botManagerMetrics](/en/documentation/devtools/graphql/gql-real-time-metrics-fields/#botmanagermetrics).

---

## Rank the classifications by volume

Ordering by the aggregate instead of by the timestamp turns the same dataset into a ranking, so you read which combinations account for the most traffic. Two changes to the query above produce it:

- Set `orderBy` to `[sum_DESC]`, so the largest groups come first.
- Drop `ts` from `groupBy`, so each combination collapses into one object across the whole range.

The result groups the period by classification, category, and action:

```graphql
query {
  botManagerMetrics(
    filter: {
      tsRange: {
        begin: "2024-10-01T00:00:00"
        end: "2024-10-03T23:59:59"
      }
    }
    aggregate: {
      sum: requests
    }
    orderBy: [sum_DESC]
    groupBy: [classified, botCategory, action]
    limit: 10000
  ) {
    classified
    botCategory
    action
    sum
  }
}
```

The objects at the top of the response are the largest groups, which is where a change of threshold or of action moves the most traffic. For more information on reading these counts back into a configuration, refer to [Monitor and calibrate Bot Manager](/en/documentation/guides/application-security/bots-and-network/monitor-and-calibrate-bot-manager/).

---

## Next steps

- [Query the top URLs bots reach with GraphQL](/en/documentation/guides/platform/observability/query-bot-manager-breakdown-data-with-graphql.md): The URLs and the addresses of the second dataset, retained for 60 days.
- [Logs](/en/documentation/platform/firewall/bot-manager/logs.md): Every field of the report log line, including the score this dataset does not carry.
- [Real-Time Metrics GraphQL API Fields](/en/documentation/devtools/graphql/gql-real-time-metrics-fields.md#botmanagermetrics): Every field of this dataset, with an example value for each.
- [Monitor and calibrate Bot Manager](/en/documentation/guides/application-security/bots-and-network/monitor-and-calibrate-bot-manager.md): How to act on the traffic a query like this one surfaces.
