---
name: azion-query-the-top-urls-bots-reach-with-graphql
description: >-
  Read the URLs bot traffic reached most, with one query against the botManagerBreakdownMetrics dataset in the GraphiQL Playground.
---

# Query the top URLs bots reach with GraphQL

You read the URLs bot traffic reached most from the `botManagerBreakdownMetrics` dataset, in the GraphiQL Playground or from any GraphQL client that sends your credentials.

`botManagerBreakdownMetrics` aggregates the requests [Bot Manager](/en/documentation/platform/firewall/#bot-manager) classified as bots and as bad bots, grouped by the URLs and the IP addresses that traffic reached. The dataset is retained for 60 days, so a time range that begins earlier than that returns no rows.

The second Bot Manager dataset, `botManagerMetrics`, carries the classification counts instead: the action, the category, and the verdict of each request. It is retained for 2 years. For more information, refer to [Query Bot Manager data with GraphQL](/en/documentation/guides/platform/observability/query-bot-manager-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.

---

## Query the URLs bots reached most

The query filters the dataset by a time range, sums `botRequests` per URL, and returns the five URLs with the highest total. 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, inside the last 60 days:

   ```graphql
   query {
     botManagerBreakdownMetrics (
       filter: {
         tsRange: {
           begin: "2024-10-01T00:00:00"
           end: "2024-10-03T00:00:00"
         }
       }
       aggregate: {
         sum: botRequests
       }
       groupBy: [requestUrl]
       orderBy: [sum_DESC]
       limit: 5
     ) {
       requestUrl
       sum
     }
   }
   ```

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

   The response carries one object per URL, with the summed requests in `sum`:

   ```json
   {
     "data": {
       "botManagerBreakdownMetrics": [
         {
           "requestUrl": "example-host1.com/api/v1/resource",
           "sum": 333543
         },
         {
           "requestUrl": "example-host2.net/api/v2/data",
           "sum": 107281
         },
         {
           "requestUrl": "example-host3.org/api/v3/info",
           "sum": 103363
         },
         {
           "requestUrl": "example-host4.io/api/v4/details",
           "sum": 89668
         },
         {
           "requestUrl": "example-host5.co/api/v5/summary",
           "sum": 64060
         }
       ]
     }
   }
   ```

You now have the URLs bot traffic reached most in the period, ordered by the number of requests classified as bots.

---

## 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`    |
| `aggregate` | With `sum: botRequests`, the total requests classified as bots in the range, after the filters apply |
| `groupBy`   | The fields the results are grouped by. `[requestUrl]` groups them by URL                             |
| `orderBy`   | The order of the results. `[sum_DESC]` returns them descending, `[sum_ASC]` ascending                |
| `limit`     | The maximum number of results. This query returns `5`; raise it to read further down the ranking     |

## Response fields

| Field        | What it carries                                                                   |
| ------------ | --------------------------------------------------------------------------------- |
| `requestUrl` | The URL the requests were made to. For example: `example-host5.co/api/v5/summary` |
| `sum`        | The requests classified as bots that reached the URL. For example: `333543`       |

---

## Change the grouping or the sum

The query above pairs one field of the dataset with one of its sums. The dataset carries four fields: `host`, `remoteAddr`, `requestUrl`, and `ts`. It carries three sums: `badBotRequests`, `botRequests`, and `uniqRequestUrl`. Two changes cover most other readings of the same period:

- Set `groupBy` to `[host]` or to `[remoteAddr]` to total the requests per host or per source IP address instead of per URL.
- Set `aggregate` to `sum: badBotRequests` to count only the requests classified as bad bots, which are a subset of the requests `botRequests` counts.

For the description of every field, refer to [botManagerBreakdownMetrics](/en/documentation/devtools/graphql/gql-real-time-metrics-fields/#botmanagerbreakdownmetrics).

---

## Next steps

- [Query Bot Manager data with GraphQL](/en/documentation/guides/platform/observability/query-bot-manager-data-with-graphql.md): The classification counts of the second dataset, retained for 2 years.
- [Real-Time Metrics GraphQL API Fields](/en/documentation/devtools/graphql/gql-real-time-metrics-fields.md#botmanagerbreakdownmetrics): Every field and every sum 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.
- [Real-Time Metrics](/en/documentation/platform/real-time-metrics/secure-dashboards.md#bot-manager): The same breakdown data as charts, read from Azion Console instead of a query.
