# API access to traffic data

The page below describes how to retrieve traffic data via the API. It contains these main sections:

* [Introduction](#introduction)
* [The filters parameter](#the-filters-parameter) (which specifies the traffic data that will be retrieved)
* [The four API routes that retrieve traffic data](#api-access-to-traffic-data), and how to use them

## Introduction

The [**Data queries** API namespace](/reference-information/api/namespace-reference/data-queries.md) provides access to traffic data, via these four routes:

* *GET /api/v4.0/data/topx*
* *GET /api/v4.0/data/stats*
* *GET /api/v4.0/data/timeline*
* *GET /api/v4.0/data/logs*

Each includes an input parameter named `filters`. **This parameter specifies the traffic data that will be retrieved.**&#x20;

Below, we begin by discussing this parameter's usage, syntax, and construction. Then we discuss the four API routes that require it, and the different types of data they return.

## The filters parameter

`filters` is a string that specifies one or more conditions. A database query is constructed from those conditions, and the results are returned to the user.

Usage of the `filters` parameter depends on the context:

* When using Swagger UI, this value is supplied directly in the `filters` input field.&#x20;
* When using curl to call the Link11 WAAP API, this value is encoded into the destination URL, preceded by "filters=". See [this explanation](/using-the-product/the-link11-waap-api/using-curl.md#manually-constructing-the-curl-command-string) for more information.&#x20;

### A short example

Here is an example of a `filters` specification in JSON format:

```bash
{
  "AND": [
    {
      "field": "timestamp",
      "op": "between",
      "value": [
        "2024-06-06 09:31:00",
        "2024-06-06 09:36:00"
      ]
    },
    {
      "field": "tags",
      "op": "regex",
      "value": "unrecognized"
    }
  ]
}
```

This will return requests which:

* were received in a five-minute time period (from 2024-06-06 09:31:00 to 2024-06-06 09:36:00), and...
* have a [Tag](/how-link11-waap-works/tagging.md) containing the string `unrecognized` . (In this example, the admin wanted to retrieve requests tagged with `unrecognized-host-header`.)

## Format

The `filters` parameter can be supplied as a query string, or as JSON.

### Query string format

This format is used in the first [Query Specification](/console-walkthrough/analytics/dashboard.md#query-specification) input field in the UI's [Dashboard](/console-walkthrough/analytics/dashboard.md) and [Events Log](/console-walkthrough/analytics/events-log.md). For example, this query string will display all requests with a 301 response code within a certain time period:

`status=301, timestamp between 2024-06-06 09:31:00 and 2024-06-06 09:36:00`

For more information on this format, see [Query filter syntax and best practices](/reference-information/query-filter-syntax-and-best-practices.md).

### JSON format

The JSON equivalent of the query string above is:

<pre class="language-bash"><code class="lang-bash"><strong>{
</strong>  "AND": [
    {
      "field": "timestamp",
      "op": "between",
      "value": [
        "2024-06-06 09:31:00",
        "2024-06-06 09:36:00"
      ]
    },
    {
      "field": "status",
      "op": "eq",
      "value": 301
    }
  ]
}
</code></pre>

(This is provided as an example only. A full discussion of JSON syntax is below.)

### Converting from query string to JSON

The POST */api/v4.0/data/timeline/parse* API route accepts query strings and returns the same query in JSON format.

## JSON structure

{% hint style="info" %}
The discussion below will focus on building the `filters` parameter in JSON format, for two reasons. First, text query strings are discussed elsewhere (in the links given above). Second, for complex queries, JSON is more powerful.&#x20;
{% endhint %}

A JSON filters parameter is structured as follows:

```bash
{
  "AND": [
    $CONDITION1,
    $CONDITION2,
    ...
    $CONDITIONn
  ]
}
```

### The first condition: a range of dates/times

The first condition must be included, and must be a range of dates/times. It is structured as follows:

```bash
{
  "field": "timestamp",
  "op": "between",
  "value": [
    "$TIMESTAMP1",
    "$TIMESTAMP2"
  ]
}
```

where $TIMESTAMP1 and $TIMESTAMP2 are timestamps: specifications of date and time.

For timestamps, any ISO format is supported. Nevertheless, both timestamps must include year, month, and day.&#x20;

If hours, minutes, or seconds are not included in a timestamp, the time will be rendered as the beginning of the day/hour/minute, respectively. Examples: `"2022-07-14"` -> `"2022-07-14 00:00:00"`, `"2022-07-14 06:52"` -> `"2022-07-14 06:52:00"`, etc.

### Subsequent conditions

After the first condition, additional conditions can be specified if desired. They are structured as follows:

```bash
{
  "field": "$FIELD_NAME",
  "op": "$OPERATOR",
  "key": "$KEY",
  "value": $VALUE
}
```

They must meet these requirements:

* Multiple conditions are combined with a logical AND. (A logical OR is not supported, as this could potentially retrieve unexpectedly large amounts of data.)
* When multiple conditions are provided, all are followed by commas, except for the final one.
* The "key" line is optional; see discussion [below](#key).

{% hint style="info" %}
Here in the documentation, spaces and carriage returns are included in JSON filter examples for clarity. In usage, they are optional.&#x20;

Also, the order of a condition's components (its `field`/`op`/`key`/`value`) does not matter.
{% endhint %}

### Field names

Available fields include those inherent to HTTP requests, along with additional data added by L11WAAP during processing.

* Some of the added information consists of internal IDs for the security settings that are relevant to the request.&#x20;
* Some requests will not contain all possible information. When L11WAAP blocks a request, processing usually stops immediately, and later stages in the [traffic filtering process](/how-link11-waap-works/traffic-filtering-process.md) do not occur. &#x20;

<table><thead><tr><th width="202">Field name</th><th>Comments</th><th data-hidden>Description</th></tr></thead><tbody><tr><td>acl_triggers</td><td><p>Populated during evaluation of the active ACL Profile. Contains keys:<br>   acl_action</p><p>   action (the type of Action that was triggered)</p><p>   extra (currently unused)</p><p>   tags</p><p>   trigger_id</p><p>   trigger_name <br>All are strings, except for tags, which is an array of strings. </p></td><td></td></tr><tr><td>arguments</td><td><p>Arguments of the request, if any. Query string and JSON examples for <em>mysite.com/page?foo=1</em> :</p><p>     arguments["foo"]="1" </p><p>     {"field": "arguments", "key": "^foo$", "op": "eq", "value": "1"}</p></td><td></td></tr><tr><td>asn</td><td>string</td><td></td></tr><tr><td>authority</td><td>string</td><td></td></tr><tr><td>biometric</td><td>array</td><td></td></tr><tr><td>blocked</td><td>boolean</td><td></td></tr><tr><td>bot</td><td>boolean</td><td></td></tr><tr><td>branch</td><td>string</td><td></td></tr><tr><td>bytes_sent</td><td>integer</td><td></td></tr><tr><td>challenge</td><td>boolean</td><td></td></tr><tr><td>challenge_type</td><td>string</td><td></td></tr><tr><td>cf_restrict_triggers</td><td>array</td><td></td></tr><tr><td>cf_triggers</td><td>Populated if the request triggered a Content Filter Rule. Contains keys: action, extra, name, risk_level, ruleid, section, trigger_id, trigger_name, value. All have string values, except for risk_level, which is an integer.</td><td></td></tr><tr><td>challenge</td><td>boolean</td><td></td></tr><tr><td>challenge_type</td><td>string</td><td></td></tr><tr><td>cookies</td><td>Can inspect specific cookies or all cookies. See <a href="#json-filter-examples">JSON filter examples</a>.</td><td></td></tr><tr><td>country</td><td>string</td><td></td></tr><tr><td>dr_triggers</td><td>array</td><td></td></tr><tr><td>geo_region</td><td>string</td><td></td></tr><tr><td>gf_triggers</td><td>An array of entries, one for each Global Filter that matched the request. Each entry contains these keys: action, extra, name, section, trigger_id, trigger_name, value</td><td></td></tr><tr><td>headers</td><td>Can inspect specific headers or all headers. See <a href="#json-filter-examples">JSON filter examples</a>.</td><td></td></tr><tr><td>host</td><td>string</td><td></td></tr><tr><td>hostname</td><td>string</td><td></td></tr><tr><td>human</td><td>boolean</td><td></td></tr><tr><td>ichallenge</td><td>boolean</td><td></td></tr><tr><td>ip</td><td>string</td><td></td></tr><tr><td>logs</td><td>array</td><td></td></tr><tr><td>messages</td><td>An array of strings, containing messages added to the event by the system. These can include <a href="/pages/9UkxgPs6j4Obbt0sGDrH#adding-custom-messages-to-log-events">messages injected into events by Edge Functions.</a></td><td></td></tr><tr><td>method</td><td>string</td><td></td></tr><tr><td>monitor</td><td>boolean: whether or not the request triggered a Monitor action.</td><td></td></tr><tr><td>monitor_reasons</td><td>array of strings; the various reasons (if any) that the request triggered Monitor actions.</td><td></td></tr><tr><td>organization</td><td>string</td><td></td></tr><tr><td>path</td><td>string. The path excluding the TLD and excluding arguments; the string begins with "/". </td><td></td></tr><tr><td>path_parts</td><td><p>string. Contents for <em>mysite.com/abc/123/home.html?foo=true</em>: <br>"path_parts": {</p><p>     "part1": "abc", </p><p>     "part2": "123", </p><p>     "part3": "home.html", </p><p>     "path": "/abc/123/home.html" </p><p>}<br>To match the second part of this example:<br>     path_parts["part2"]="123"<br>     {"field": "path_parts", "key": "^part2$", "op": "eq", "value": "123"}<br></p></td><td></td></tr><tr><td>port</td><td>string</td><td></td></tr><tr><td>processing_stage</td><td>integer: the furthest stage of <a href="/pages/Tai9ex56CGarkEL6QpbC">traffic filtering</a> that was reached.<br>     0: Initialization<br>     2: Global Filtering<br>     3. Flow Control<br>     4. Global Rate Limits<br>     5. Rate Limits<br>     6. ACL Profile<br>     7. Content Filtering</td><td></td></tr><tr><td>profiling</td><td>array of items containing the security settings relevant to this request. Each item contains:<br>     a name (secpol, mapping, flow, limit, acl, content_filter)<br>     and value (the internal ID of that setting). </td><td></td></tr><tr><td>protocol</td><td>string</td><td></td></tr><tr><td>proxy</td><td>array of items containing proxy-related data. Each item contains a name and value. The names are: additional_tags, bytes_sent, container, geo_as_domain, geo_as_name, geo_as_type, geo_company_country, geo_company_domain, geo_company_type, geo_lat, geo_long, geo_mobile_carrier, geo_mobile_country, geo_mobile_mcc, geo_mobile_mnc, realip, request_id, request_length, request_time, ssl_cipher, ssl_protocol, status.</td><td></td></tr><tr><td>query</td><td>string. Example: for <em>mysite.com/page?code=117</em>, this is <code>?code=117</code>.</td><td></td></tr><tr><td>rbz_latency</td><td>integer</td><td></td></tr><tr><td>rbzsessionid</td><td>Cookie set by L11WAAP. Example query string and JSON:<br>    cookies["rbzsessionid"]="57870178706cb50db6d41aab"<br>    {"field": "cookies", "key": "^rbzsessionid$", "op": "eq", "value": "578701713f70dcd8706cb50db6d41aab"}</td><td></td></tr><tr><td>reason</td><td>string. The reason, if any, the request was blocked.</td><td></td></tr><tr><td>referer</td><td>string</td><td></td></tr><tr><td>request_id</td><td>string</td><td></td></tr><tr><td>request_length</td><td>integer</td><td></td></tr><tr><td>request_time</td><td>float</td><td></td></tr><tr><td>result</td><td>string; the disposition of the request. A way to quickly see anomalies is to search for {"field": "result", "op": "not eq", "value": "Passed"}</td><td></td></tr><tr><td>rl_triggers</td><td>array; the reasons (if any) that rate limits were triggered.</td><td></td></tr><tr><td>security_config</td><td><p>The configuration of security settings when this request was processed. Keys and data types are:<br>     acl_active (boolean)</p><p>     cf_active (boolean)</p><p>     cf_rules (integer)</p><p>     gf_rules (integer)</p><p>     revision (string)</p><p>     rl_rules (integer)</p><p>     secpolentryid (string)</p><p>     secpolid (string)</p></td><td></td></tr><tr><td>session</td><td>string</td><td></td></tr><tr><td>session_ids</td><td>array</td><td></td></tr><tr><td>status</td><td>integer</td><td></td></tr><tr><td>tags</td><td>array of strings: all the tags attached to the request</td><td></td></tr><tr><td>time_period</td><td>integer; the Epoch Unix timestamp of the request</td><td></td></tr><tr><td>timestamp</td><td>string; date and time </td><td></td></tr><tr><td>trigger_counters</td><td>The number of times an Action was triggered, and the source of the triggers (ACL Profile, Content Filtering, Global Filters, or Rate Limits). This is a collection of keys (counters) and values (integers with the value of each counter). Counter names are strings: acl, cf, cf_restrict, dr, gf, rl. Sample filter condition: {"field": "trigger_counters", "key": "acl", "value": 0, "op": "gt"} </td><td></td></tr><tr><td>upstream_addr</td><td>array of strings</td><td></td></tr><tr><td>upstream_data</td><td>array of elements: {addr (string), response_time (float), status (integer)}</td><td></td></tr><tr><td>upstream_response_time</td><td>float or null</td><td></td></tr><tr><td>upstream_status</td><td>array of integers</td><td></td></tr><tr><td>url</td><td>string</td><td></td></tr><tr><td>user_agent</td><td>string</td><td></td></tr><tr><td>version</td><td>string</td><td></td></tr><tr><td>waap_id</td><td>Cookie set by L11WAAP. Example query string and JSON:<br>  cookies["waap_id"]="Jc491eLWqTBOfDnJwNk"<br>      {"field": "cookies", "key": "^waap_id$", "op": "eq", "value": "Jc491eLWqTBOfDnJwNk"}</td><td></td></tr></tbody></table>

### Key

For some types of data, it might not be enough to specify the *field*, because there could be multiple parameters in the request that match it. For example, a field name of "cookies" or "headers" does not tell the system **which** cookie or header to inspect.

The *key* field supplies this information; it is the name of the specific parameter to evaluate. If this parameter is not defined, the system will inspect all instances of the specified field (all cookies, all headers, etc.).

Some examples are in the [JSON filters examples](#json-filter-examples) below.

### Values&#x20;

Values should be specified in the appropriate data type: strings as quote-delimited strings, integers as numbers, etc. Arrays of values can be supplied.

### Operators

| Operator | Data Type                   | Description                                                                |
| -------- | --------------------------- | -------------------------------------------------------------------------- |
| is       | boolean                     | checks if value is True or False                                           |
| eq       | integer / float / string    | checks exact match for numeric/string value                                |
| gt/ lt   | integer / float             | checks if value is greater/less than                                       |
| gte/ lte | integer / float             | checks if value is greater/less than or equal                              |
| in       | integer / float / string    | checks if numeric/string value is in a list of values                      |
| regex    | string                      | checks if string has a match with a regex                                  |
| between  | integer / float / timestamp | checks if value between two numbers/ timestamps. Does not depend on order. |

### Negative operators

Operators can be inverted by adding `not`. For example, `not eq` means "does not equal".

### Inverting a condition

It's possible to invert an entire condition by adding NOT, like this:

<pre class="language-bash"><code class="lang-bash"><strong>{
</strong><strong>  "NOT": {
</strong>    "field": "$FIELD_NAME",
    "op": "$OPERATOR",
    "key": "$KEY",
    "value": $VALUE
  }
}
</code></pre>

## JSON filter examples

Retrieve PUT and POST requests:

```bash
{
    "AND": [
        {"field": "timestamp", "op": "between", "value": ["2022-07-14 06:52:37", "2022-07-12 06:52:37"]},
        {"field": "method", "value":"^P.*T$", "op":"regex"}
    ]
}
```

Retrieve requests containing a tag that matches "geo" or "location":

```bash
{
    "AND": [
        {"field": "timestamp", "value": ["2022-07-14 06:52:37", "2022-07-12 06:52:37"], "op": "between"},
        {"field": "tags", "value": ["geo", "location"], "op": "in"}
    ]
}
```

Retrieve requests where **certain** cookies' values match a regex:

```bash
{
    "AND": [
        {"field": "timestamp", "value": ["2022-07-14 06:52:37", "2022-07-12 06:52:37"], "op": "between"},
        {"field": "cookies", "key": "analytics_.*", "value": "gcp_.*", "op": "regex"}
    ]
}
```

Retrieve requests where **any** cookie's value matches a regex:

```bash
{
    "AND": [
        {"field": "timestamp", "value": ["2022-07-14 06:52:37", "2022-07-12 06:52:37"], "op": "between"},
        {"field": "cookies", "value": "gcp_.*", "op": "regex"}
    ]
}
```

Retrieve requests according to a subfield (the *acl\_active* subfield of *security\_config* must be greater than 11).&#x20;

```bash
{
    "AND": [
        {"field": "timestamp", "value": ["2022-07-14 06:52:37", "2022-07-12 06:52:37"], "op": "between"},
        {"field": "security_config", "key": "acl_active", "value": 11, "op": "gt"}
  ]
}
```

Retrieve requests according to an array of subfields:

```bash
{
    "AND": [
        {"field": "timestamp", "value": ["2022-07-14 06:52:37", "2022-07-12 06:52:37"], "op": "between"},
        {
            "field": "cf_triggers",
            "conditions": [
                {"field": "risk_level", "value": 2, "op": "gt"},
                {"field": "ruleid", "value": "100037", "op": "eq"}
            ]
        }
    ]
}
```

Retrieve requests according to a combination of conditions (there is no limit on the number of conditions):

```bash
{
    "AND": [
        {"field": "timestamp", "value": ["2022-08-08 01:15:25", "2022-08-08 01:52:28"], "op": "between"},
        {"field": "tags", "value":"geo-continent-name:north-america", "op": "eq"},
        {"field": "agent", "key": "ephemeral_id", "value": "029ab6f-6d15-4290-b44f-9133", "op": "regex"},
        {"field": "trigger_counters", "key": "acl","value": 2,"op": "not gt"},
        {"field": "headers", "key": "x-forwarded.*", "value": "3.65.14.177", "op": "regex"},
        {"field": "path_parts", "key": "^part3$", "value": "^-1&", "op": "regex"},
        {"field": "security_config", "key": "cf_active", "value": true, "op": "not eq"},
        {"field": "ip", "value": ["2.55.96.231", "23.65.14.177", "3.1.92.15", "8.206.254.196"], "op": "in"}
    ]
}
```

## API access to traffic data

As noted previously, there are four API routes that use the `filters` parameter to retrieve traffic data:

* *GET /api/v4.0/data/topx*
* *GET /api/v4.0/data/stats*
* *GET /api/v4.0/data/timeline*
* *GET /api/v4.0/data/logs*

Their typical uses are as follows.

**Quickly discover the most important factors** in the traffic stream (e.g., the countries sending the most blocked requests, the URLs receiving the most bot traffic, etc.): use the *topx* route.

**Get a summary of traffic statistics** (total requests, bandwidth, and latency): use the *stats* route.

**Get a summary of security metrics** (total requests, blocked requests, status codes returned, number of human clients, activity of the origin, etc.): use the *timeline* route.

**Get complete data** for all requests matching certain criteria (often used for drilling down into trends discovered from the other routes): use the *logs* route.

Below, we discuss each route in detail.

## GET /api/v4.0/data/topx

This route provides API access to the same [Top Metrics](/console-walkthrough/analytics/dashboard.md#top-metrics) available in the Dashboard. Here's an example of Top Countries in the Dashboard:

<figure><img src="/files/EFjmeF9qtj3ZBWquyDDZ" alt=""><figcaption></figcaption></figure>

Calling this route returns all metrics of data: all results for "top applications", all results for "top countries", all items for "top sources", and so on. They are combined into a single continuous list:

```bash
{
  "data": {
    "results": [
        $RESULT1,
        $RESULT2,
        $RESULT3,
        ...
        $RESULTn
    ],
    "statistics": {
      "bytes_billed": null,
      "bytes_processed": null,
      "elapsed_ms": 0
    }
  },
  "status": 200
}
```

...where the list of $RESULTs looks something like this (incomplete) example:

```bash
"results": [
  {
    "key": "China",
    "label": "country"
  },
  {
    "key": "United States",
    "label": "country"
  },
  {
    "key": "161.1.50.2",
    "label": "ip"
  },
  {
    "key": "101.6.123.53",
    "label": "ip"
  },
  {
    "key": "161.1.50.5",
    "label": "ip"
  },
  {
    "key": "mysite.com/login",
    "label": "url"
  }
]

```

We see that in the time period specified in the `filters` parameter, there were three IP addresses in two countries that sent requests to a single URL.&#x20;

Some points to note:

* The results are organized and grouped together in the list according to their *label*.
* Labels are ordered alphabetically.
* Labels can differ in their number of results.
* The route returns the "top" results for each label (for example, results with the "ip" label show the IPs that sent the most blocked requests). When there are only a few results for a given label, all are retrieved. When there are many, only the "top" results are retrieved.

#### Actual usage

The example above is oversimplified. In actual use, the *topx* route:

* Returns much more data per result, not just *key* and *label* (see the list of fields below)
* Returns more categories than just *country*, *ip*, and *url* (see the discussion of the *label* field below)

A detailed discussion of *topx* follows.

### Contents of each result

Each result contains the fields listed below.&#x20;

{% hint style="info" %}
The \_time fields are in seconds. These are floats, but can appear at various precisions: zero decimal places, several decimal places, or scientific notation (e.g., 1.6210818451802098e-9).
{% endhint %}

<table><thead><tr><th width="285">Result field name</th><th width="130">Type</th><th>Comments</th></tr></thead><tbody><tr><td>avg_origin_time</td><td>float</td><td>The average amount of processing time by the origin for these requests. If no requests reached the origin, this will be null. </td></tr><tr><td>avg_rbz_time </td><td>float</td><td>The average amount of processing time by L11WAAP for these requests.</td></tr><tr><td>avg_total_time</td><td>float</td><td>The average total amount of processing time for these requests.</td></tr><tr><td>first_asn</td><td>string</td><td>First entry in the list of ASNs</td></tr><tr><td>first_geo_country</td><td>string</td><td>First entry in the list of countries</td></tr><tr><td>first_organization</td><td>string</td><td>First entry in the list of organizations</td></tr><tr><td>key</td><td>string</td><td>Content varies; see discussion below.</td></tr><tr><td>label</td><td>string</td><td>Category of result. See discussion below.</td></tr><tr><td>max_origin_time</td><td>float</td><td>The longest amount of processing time by the origin among these requests. If no requests reached the origin, this will be null. </td></tr><tr><td>max_rbz_time</td><td>float</td><td>The longest amount of processing time by L11WAAP among these requests.</td></tr><tr><td>max_total_time</td><td>float</td><td>The longest amount of total processing time among these requests.</td></tr><tr><td>min_origin_time</td><td>float</td><td>The shortest amount of processing time by the origin among these requests. If no requests reached the origin, this will be null. </td></tr><tr><td>min_rbz_time</td><td>float</td><td>The shortest amount of processing time by L11WAAP among these requests.</td></tr><tr><td>min_total_time</td><td>float</td><td>The shortest amount of total processing time among these requests.</td></tr><tr><td>num_of_blocked_requests</td><td>integer</td><td></td></tr><tr><td>num_of_bot_requests</td><td>integer</td><td></td></tr><tr><td>num_of_challenges</td><td>integer</td><td></td></tr><tr><td>num_of_human_requests</td><td>integer</td><td></td></tr><tr><td>num_of_monitored_requests</td><td>integer</td><td>Includes all requests that triggered a "monitor" action, even if they were blocked as well.</td></tr><tr><td>num_of_requests</td><td>integer</td><td></td></tr><tr><td>sum_of_bytes_sent</td><td>integer</td><td></td></tr><tr><td>sum_of_request_length</td><td>integer</td><td></td></tr></tbody></table>

### Organization of results: the label and key fields

The *topx* route returns results in a specific order:

* Results are grouped together according to their *label* (i.e., their category).
* Labels are ordered alphabetically (see full list below)
* Within each label, results are ordered by **num\_of\_blocked\_requests**, in descending order.

{% hint style="info" %}
Notice that this is unlike the UI's Dashboard Top Metrics, where some types of results have other default orders.
{% endhint %}

The *topx* route returns twelve categories of results, each with its own label. The label determines the contents of the *key* field.

| Label        | 'Key' field contains                        |
| ------------ | ------------------------------------------- |
| country      | country name                                |
| host         | host name or IP                             |
| ip           | IP address                                  |
| organization | organization                                |
| origin\_time | target URL                                  |
| rbz\_time    | target URL                                  |
| reason       | reason the request was monitored or blocked |
| referer      | referer string                              |
| total\_time  | target URL                                  |
| url          | target URL                                  |
| user\_agent  | user agent string                           |
| waap\_id     | waap\_id cookie value                       |

## GET /api/v4.0/data/stats

This route returns traffic metrics for the requested time period, broken down into shorter segments of time.

### Data structures

The retrieved metrics are structured like this:

```bash
{
  "data": {
    "results": [
      $RESULTS-TIMESEGMENT-1,
      $RESULTS-TIMESEGMENT-2,
      ...
      $RESULTS-TIMESEGMENT-n
    ],
    "statistics": {
      "bytes_billed": null,
      "bytes_processed": null,
      "elapsed_ms": 0
    }
  },
  "status": 200
}
```

...where each $RESULTS-TIMESEGMENT-x has this structure:

```bash
{
   "avg_latency": float,
   "hostname": string,
   "num_of_requests": integer,
   "sum_of_bandwidth": integer,
   "time_period": integer,
   "timeperiod_string": string
}

```

### Contents of each result

| Field name         |                                                                        |
| ------------------ | ---------------------------------------------------------------------- |
| avg\_latency       | Average latency in seconds                                             |
| hostname           | Host                                                                   |
| num\_of\_requests  | Total requests received during the time period                         |
| sum\_of\_bandwidth | Total bytes sent and received                                          |
| time\_period       | Beginning of time segment, as an Epoch Unix integer (e.g., 1718186400) |
| timeperiod\_string | Beginning of time segment, as a string (e.g., "2024-06-12 10:00:00")   |

## GET /api/v4.0/data/timeline

This route returns security metrics for the requested time period, broken down into shorter segments of time.

### Data structures

The retrieved metrics are structured like this:

```bash
{
  "data": {
    "results": [
      $RESULTS-TIMESEGMENT-1,
      $RESULTS-TIMESEGMENT-2,
      ...
      $RESULTS-TIMESEGMENT-n
    ],
    "statistics": {
      "bytes_billed": null,
      "bytes_processed": null,
      "elapsed_ms": 0
    }
  },
  "status": 200
}
```

...where each $RESULTS-TIMESEGMENT-x has this structure:

```bash
{
  "array_origin_status_codes": [
    $STATUS-DATA-ORIGIN1,
    $STATUS-DATA-ORIGIN2,
    ...
    $STATUS-DATA-ORIGINn,    
  ],
  "array_status_codes": [
    $STATUS-DATA-L11WAAP1,
    $STATUS-DATA-L11WAAP2,
    ...
    $STATUS-DATA-L11WAAPn,    
  ],
  "num_of_blocked_requests": integer,
  "num_of_challenges": integer,
  "num_of_human_requests": integer,
  "num_of_ip": integer,
  "num_of_origin_blocked_requests": integer,
  "num_of_requests": integer,
  "num_of_sessions": integer,
  "sum_of_sent_bytes": integer,
  "time_period": integer,
  "timeperiod_string": string 
}
```

...and each $STATUS-DATA-x contains the number of responses with a specific status:

```bash
{
  "num_of_requests": integer,
  "status": integer [an HTTP status code]
}
```

### Contents of each result

| Field name                         |                                                                                                                                                                                                        |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| array\_origin\_status\_codes       | An array: each element contains a status code and the number of responses from the origin with that code. If no requests reached the origin during the specified time period, the array will be empty. |
| array\_status\_codes               | An array: each element contains a status code and the number of responses from L11WAAP with that code.                                                                                                 |
| num\_of\_blocked\_requests         | Requests that were blocked                                                                                                                                                                             |
| num\_of\_challenges                | Number of times L11WAAP issued a bot challenge                                                                                                                                                         |
| num\_of\_human\_requests           | Requests from human (i.e., non-bot) clients                                                                                                                                                            |
| num\_of\_ip                        | Number of IPs used by clients                                                                                                                                                                          |
| num\_of\_origin\_blocked\_requests | Number of requests rejected by the origin                                                                                                                                                              |
| num\_of\_requests                  | Total requests received during the time period                                                                                                                                                         |
| num\_of\_sessions                  | Number of unique sessions                                                                                                                                                                              |
| sum\_of\_sent\_bytes               | Total bytes sent                                                                                                                                                                                       |
| time\_period                       | Beginning of time segment, as an Epoch Unix integer (e.g., 1718186400)                                                                                                                                 |
| timeperiod\_string                 | Beginning of time segment, as a string (e.g., "2024-06-12 10:00:00")                                                                                                                                   |

## GET /api/v4.0/data/logs&#x20;

This route returns **all** requests that match the filter parameters, up to the number of requests specified. The results are returned like this:

```bash
{
  "data": {
    "results": [
      {
            $REQUEST1
      },
      {
            $REQUEST2
      }, 
      {
            $REQUEST3
      },           
      ...
      {
            $REQUESTn
      }
    ],
    "statistics": {
      "bytes_billed": null,
      "bytes_processed": null,
      "elapsed_ms": 0
    }
  },
  "status": 200
}
```

Each $REQUEST has this structure:

```
$FIELD1: $VALUE1,
$FIELD2: $VALUE2,
...
$FIELDn: $VALUEn
```

...where the $FIELDs are the **Field names** listed [above](#field-names) in the `filters` discussion, and the $VALUEs are their values, if any. So a request looks like this:

```bash
"acl_triggers": [],
"arguments": {},
"asn": "AS4837",
...
"user_agent": "curl/7.74.0",
"version": null
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://waap.docs.link11.com/reference-information/api/api-access-to-traffic-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
