> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://api.docs.modulards.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://api.docs.modulards.com/_mcp/server.

# Patch & Protect statistics

GET https://api.modulards.com/api/public/v1/patchstack-services/{site_preset_patchstack}/stats

The attacks Patch & Protect blocked on one website: how many per day, the addresses that insisted the most with their country, and the rules that fired, each with its own total.

`start_date` and `end_date` are whole days (`YYYY-MM-DD`), never in the future, and both optional: the default is the last seven whole days.

That default is the period kept ready. Modular DS stores one period per website and refreshes it every few hours, so a read of the default range is answered from what is stored and `cached_at` says when it was read. Asking for any other period reads it from the security provider, stores it in place of the previous one and answers it, which takes longer.

The figures need the add-on subscribed and the statistics permission; without them the call answers 404. Unlike the rest of this surface, the payload is not a JSON:API document: it is the statistics block on its own.

Reference: https://api.docs.modulards.com/modular-ds-public-api/patch-protect/statistics

## Authentication

- `Authorization` header (bearer token, required) — Personal access token created in the Modular DS dashboard; read-only tokens can only call GET endpoints.

## Request

### Path parameters

- `site_preset_patchstack` (string, required)

### Query parameters

- `start_date` (string, optional) — First whole day to count; defaults to seven days before end_date
- `end_date` (string, optional) — Last whole day to count; defaults to today and is never in the future

## Response

### 200

200 - Seven days of blocked attacks

- `attacks` (list of ApiPublicV1PatchstackServicesSitePresetPatchstackStatsGetResponsesContentApplicationJsonSchemaAttacksItems, optional)
- `cached_at` (string, optional)
- `end_date` (string, optional)
- `ips` (list of ApiPublicV1PatchstackServicesSitePresetPatchstackStatsGetResponsesContentApplicationJsonSchemaIpsItems, optional)
- `rules` (list of ApiPublicV1PatchstackServicesSitePresetPatchstackStatsGetResponsesContentApplicationJsonSchemaRulesItems, optional)
- `start_date` (string, optional)

## Types

### ApiPublicV1PatchstackServicesSitePresetPatchstackStatsGetResponsesContentApplicationJsonSchemaAttacksItems

- `date` (string, optional)
- `total` (double, optional)

### ApiPublicV1PatchstackServicesSitePresetPatchstackStatsGetResponsesContentApplicationJsonSchemaIpsItems

- `country` (ApiPublicV1PatchstackServicesSitePresetPatchstackStatsGetResponsesContentApplicationJsonSchemaIpsItemsCountry, optional)
- `ip` (string, optional)
- `total` (double, optional)

### ApiPublicV1PatchstackServicesSitePresetPatchstackStatsGetResponsesContentApplicationJsonSchemaRulesItems

- `description` (string, optional)
- `total` (double, optional)

### ApiPublicV1PatchstackServicesSitePresetPatchstackStatsGetResponsesContentApplicationJsonSchemaIpsItemsCountry

- `code` (string, optional)
- `name` (string, optional)

## Examples

**Response**

```json
{
  "attacks": [
    {
      "date": "2026-09-18",
      "total": 12
    },
    {
      "date": "2026-09-19",
      "total": 3
    }
  ],
  "cached_at": "2026-09-24T15:00:57.000000Z",
  "end_date": "2026-09-24",
  "ips": [
    {
      "country": {
        "code": "US",
        "name": "United States"
      },
      "ip": "203.0.113.42",
      "total": 9
    }
  ],
  "rules": [
    {
      "description": "SQL injection attempt",
      "total": 15
    }
  ],
  "start_date": "2026-09-18"
}
```

**SDK Code**

```python 200 - Seven days of blocked attacks
import requests

url = "https://api.modulards.com/api/public/v1/patchstack-services/site_preset_patchstack/stats"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript 200 - Seven days of blocked attacks
const url = 'https://api.modulards.com/api/public/v1/patchstack-services/site_preset_patchstack/stats';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go 200 - Seven days of blocked attacks
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.modulards.com/api/public/v1/patchstack-services/site_preset_patchstack/stats"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby 200 - Seven days of blocked attacks
require 'uri'
require 'net/http'

url = URI("https://api.modulards.com/api/public/v1/patchstack-services/site_preset_patchstack/stats")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java 200 - Seven days of blocked attacks
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.modulards.com/api/public/v1/patchstack-services/site_preset_patchstack/stats")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php 200 - Seven days of blocked attacks
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.modulards.com/api/public/v1/patchstack-services/site_preset_patchstack/stats', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp 200 - Seven days of blocked attacks
using RestSharp;

var client = new RestClient("https://api.modulards.com/api/public/v1/patchstack-services/site_preset_patchstack/stats");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift 200 - Seven days of blocked attacks
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.modulards.com/api/public/v1/patchstack-services/site_preset_patchstack/stats")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```