---
name: azion-read-the-score-of-a-blocked-request
description: >-
  Query Real-Time Events for the internal rules that matched a request and the score each threat family gave it.
---

# Read the score of a blocked request

You can read which internal rules matched a blocked request, and the score each threat family gave it, from the [Real-Time Events](/en/documentation/platform/real-time-events/) GraphQL API. A blocked response carries `400` and the **Bad Request** page, with no header naming WAF; its `x-azion-request-id` header finds the record.

---

## Prerequisites

- A rule applying a rule set in `blocking` on the firewall bound to your workload. To create it, refer to [Apply a rule set to every request](/en/documentation/guides/application-security/firewall-and-waf/apply-rule-set/).
- A personal token, for the GraphQL query.

---

## Read the request id

Send a request that WAF blocks, and read the `x-azion-request-id` header in the response:

```bash
curl -i "https://<your-workload-domain>/?q=1%27%20OR%20%271%27%3D%271"
```

```text
HTTP/2 400
content-type: text/html
x-azion-request-id: 0123456789abcdef0123456789abcdef
```

The response is `HTTP/2 400` with the `x-azion-request-id` header, and its value is the request id the query below filters on.

---

## Query the record of the request

Send a GraphQL query to `https://api.azion.com/v4/events/graphql`, over the `workloadEvents` dataset, with a personal token, filtered on the request id and a window around it:

```graphql
query {
  workloadEvents(
    limit: 1
    filter: { tsGte: "<start>", tsLt: "<end>", requestIdEq: "<request-id>" }
  ) {
    ts
    requestUri
    status
    upstreamStatus
    wafBlock
    wafMatch
    wafScore
    wafAttackFamily
    wafAttackAction
  }
}
```

```json
{
  "ts": "2026-01-01T12:00:00Z",
  "requestUri": "/?q=1%27%20OR%20%271%27%3D%271",
  "status": 400,
  "upstreamStatus": 0,
  "wafBlock": "1",
  "wafMatch": "0:1009:ARGS:q,1:1013:ARGS:q",
  "wafScore": "0:$SQL:18,1:$XSS:32",
  "wafAttackFamily": "$SQL,$XSS",
  "wafAttackAction": "$BLOCK"
}
```

The row returns `wafBlock` as `1`, one entry per internal rule that matched in `wafMatch`, and one score per threat family in `wafScore`.

A `wafMatch` entry is shaped `<index>:<ruleId>:<zone>:<varName>`, so `1:1013:ARGS:q` names rule `1013` on the `q` argument. A `wafScore` entry is shaped `<index>:$<family>:<score>`, so a request has several scores rather than one. `upstreamStatus` reads `0` because the request never reached an origin.

> **Note**
>
> A request the WAF did not act on carries `-` in every one of these fields, and a `400` with no such row is not a WAF block. Query the v4 path: the older `https://api.azion.com/events/graphql` answers `204` with an empty body. The fields are camelCase here, rather than the snake\_case spellings a [Data Stream](/en/documentation/platform/data-stream/) payload uses.

---

## Next steps

- [Exempt one query string parameter](/en/documentation/guides/application-security/firewall-and-waf/exempt-query-parameter.md): Turn a rule id read from wafMatch into the exception that clears it.
- [WAF Rule Sets](/en/documentation/platform/firewall/waf/rules-set.md): Look up what an internal rule id detects, for every id wafMatch can name.
