PHPackages                             audunru/reporting-api - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. audunru/reporting-api

ActiveLibrary[API Development](/categories/api)

audunru/reporting-api
=====================

Receive and handle W3C Reporting API and CSP violation reports in Laravel

v2.1.0(2w ago)097MITPHPPHP ^8.3CI passing

Since May 1Pushed 1w agoCompare

[ Source](https://github.com/audunru/reporting-api)[ Packagist](https://packagist.org/packages/audunru/reporting-api)[ RSS](/packages/audunru-reporting-api/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (7)Dependencies (8)Versions (14)Used By (0)

Receive [W3C Reporting API](https://www.w3.org/TR/reporting/) and [CSP violation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) reports in Laravel
===========================================================================================================================================================

[](#receive-w3c-reporting-api-and-csp-violation-reports-in-laravel)

[![Build Status](https://github.com/audunru/reporting-api/actions/workflows/validate.yml/badge.svg)](https://github.com/audunru/reporting-api/actions/workflows/validate.yml)[![Coverage Status](https://camo.githubusercontent.com/ab13fd78acefea3b9ffcaf9455d24571eb99fa2bf32f6e2d7122cf0923329f83/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f617564756e72752f7265706f7274696e672d6170692f62616467652e7376673f6272616e63683d6d61696e)](https://coveralls.io/github/audunru/reporting-api?branch=main)

Browsers send batched reports — CSP violations, deprecations, network errors, crashes, and more — to a configured endpoint. This package registers that endpoint, decodes the payload, and dispatches Laravel events for each report type.

Requirements
------------

[](#requirements)

- PHP 8.3+
- Laravel 13+

Installation
------------

[](#installation)

```
composer require audunru/reporting-api
```

The service provider is auto-discovered. The package registers a `POST /reports` route automatically.

Sending reports from a browser
------------------------------

[](#sending-reports-from-a-browser)

### Legacy CSP reports (`application/csp-report`)

[](#legacy-csp-reports-applicationcsp-report)

Set the `report-uri` directive in your `Content-Security-Policy` header:

```
Content-Security-Policy: default-src 'self'; report-uri /reports

```

With [spatie/laravel-csp](https://github.com/spatie/laravel-csp):

```
// config/csp.php
'report_uri' => env('CSP_REPORT_URI', '/reports'),
```

### Modern Reporting API (`application/reports+json`)

[](#modern-reporting-api-applicationreportsjson)

Use `Reporting-Endpoints` and `report-to` to send batched reports in the modern format:

```
Reporting-Endpoints: default="/reports"
Content-Security-Policy: default-src 'self'; report-to default

```

The modern format supports additional report types beyond CSP violations (deprecations, network errors, crashes, etc.).

With [spatie/laravel-csp](https://github.com/spatie/laravel-csp), add `Directive::REPORT_TO` in your Policy class:

```
use Spatie\Csp\Directive;
use Spatie\Csp\Policies\Basic;

class MyPolicy extends Basic
{
    public function configure(): void
    {
        parent::configure();
        $this->add(Directive::REPORT_TO, 'default');
    }
}
```

Also apply the `reporting-endpoints` middleware (see [Middleware](#middleware)) so the `Reporting-Endpoints` header is sent to browsers alongside the CSP header.

For legacy browser fallback (Firefox and Safari do not support `report-to`), also set `report_uri` in `config/csp.php`. Modern browsers ignore `report-uri` when `report-to` is present, so each browser uses the right format automatically:

```
// config/csp.php
'report_uri' => env('CSP_REPORT_URI', '/reports'),
```

Getting started
---------------

[](#getting-started)

When a report arrives the package dispatches a Laravel event based on the report type. The package ships two ready-made listeners — `LogCspViolation` and `LogReport` — that you can register directly in `AppServiceProvider::boot()`:

```
use audunru\ReportingApi\Contracts\ReportEvent;
use audunru\ReportingApi\Events\CspViolationReceived;
use audunru\ReportingApi\Listeners\LogCspViolation;
use audunru\ReportingApi\Listeners\LogReport;
use Illuminate\Support\Facades\Event;

public function boot(): void
{
    Event::listen(CspViolationReceived::class, LogCspViolation::class);
    Event::listen(ReportEvent::class, LogReport::class);
}
```

`LogCspViolation` logs CSP violations as `warning`. `LogReport` logs every other report type as `info`, with the full raw report in the log context. Neither is registered automatically.

Both log to the `stack` channel by default. Override `protected string $channel` to redirect to a different channel:

```
class MyCspViolationListener extends LogCspViolation
{
    protected string $channel = 'security';
}
```

### Filtering noise with `shouldExclude()`

[](#filtering-noise-with-shouldexclude)

Browser extensions routinely trigger CSP reports. Override `shouldExclude()` in a subclass to filter them out:

```
// app/Listeners/MyCspViolationListener.php
namespace App\Listeners;

use audunru\ReportingApi\DTOs\CspViolationReport;
use audunru\ReportingApi\Listeners\LogCspViolation;

class MyCspViolationListener extends LogCspViolation
{
    private const EXTENSION_SCHEMES = [
        'chrome-extension://',
        'moz-extension://',
        'safari-extension://',
    ];

    protected function shouldExclude(CspViolationReport $report): bool
    {
        $blocked = $report->body->blockedURL ?? '';

        foreach (self::EXTENSION_SCHEMES as $scheme) {
            if (str_starts_with($blocked, $scheme)) {
                return true;
            }
        }

        return false;
    }
}
```

`LogReport` supports the same pattern via its `Report` base type:

```
// app/Listeners/MyReportListener.php
namespace App\Listeners;

use audunru\ReportingApi\DTOs\Report;
use audunru\ReportingApi\Listeners\LogReport;

class MyReportListener extends LogReport
{
    protected function shouldExclude(Report $report): bool
    {
        return $report->type === 'csp-violation'; // handled separately
    }
}
```

Register your subclasses the same way:

```
use audunru\ReportingApi\Contracts\ReportEvent;
use audunru\ReportingApi\Events\CspViolationReceived;
use App\Listeners\MyCspViolationListener;
use App\Listeners\MyReportListener;
use Illuminate\Support\Facades\Event;

public function boot(): void
{
    Event::listen(CspViolationReceived::class, MyCspViolationListener::class);
    Event::listen(ReportEvent::class, MyReportListener::class);
}
```

Middleware
----------

[](#middleware)

The package registers a `reporting-endpoints` middleware alias that adds the `Reporting-Endpoints` header to responses. Browsers use this header to discover where to POST their reports.

Apply it to specific routes or route groups:

```
Route::middleware('reporting-endpoints')->group(function () {
    Route::get('/', HomeController::class);
});
```

To add it globally to all web routes (Laravel 11+, `bootstrap/app.php`):

```
use audunru\ReportingApi\Http\Middleware\AddReportingEndpointsHeader;
use Illuminate\Foundation\Configuration\Middleware;

->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        AddReportingEndpointsHeader::class,
    ]);
})
```

The header value uses the `path` from your config:

```
Reporting-Endpoints: default="/reports"

```

Configuration
-------------

[](#configuration)

Publish the config file to customise the endpoint path and throttle limit:

```
php artisan vendor:publish --tag=reporting-api-config
```

KeyEnv varDefaultDescription`path``REPORTING_API_PATH``/reports`URL path of the report endpoint`throttle``REPORTING_API_THROTTLE``60,1`Throttle value — named limiter or `attempts,minutes`Reference
---------

[](#reference)

### Dispatched events

[](#dispatched-events)

Event classTrigger`CspViolationReceived``csp-violation` type (modern) or `application/csp-report` (legacy)`DeprecationReportReceived``deprecation` type`InterventionReportReceived``intervention` type`CrashReportReceived``crash` type`NetworkErrorReceived``network-error` type`CoepReportReceived``coep` type`CoopReportReceived``coop` type`DocumentPolicyViolationReceived``document-policy-violation` type`GenericReportReceived`Any unrecognized type### Event interface

[](#event-interface)

All event classes implement `audunru\ReportingApi\Contracts\ReportEvent` and expose:

MethodReturns`getReport()`Typed report DTO (e.g. `CspViolationReport`)`getRawReport()`Raw report array as received from the browser### Report DTOs

[](#report-dtos)

`getReport()` returns a typed DTO that extends `audunru\ReportingApi\DTOs\Report`, with properties common to all report types:

PropertyTypeDescription`type``string`W3C report type (e.g. `'csp-violation'`)`url``?string`URL of the page that generated the report`age``?int`Milliseconds between report generation and sending`userAgent``?string`Browser user agent stringEach specific report DTO also has a typed `body` property whose class matches the report type:

Event`getReport()` returns`body` type`CspViolationReceived``CspViolationReport``CspViolationReportBody``DeprecationReportReceived``DeprecationReport``DeprecationReportBody``InterventionReportReceived``InterventionReport``InterventionReportBody``CrashReportReceived``CrashReport``CrashReportBody``NetworkErrorReceived``NetworkErrorReport``NetworkErrorReportBody``CoepReportReceived``CoepViolationReport``CoepViolationReportBody``CoopReportReceived``CoopViolationReport``CoopViolationReportBody``DocumentPolicyViolationReceived``DocumentPolicyViolationReport``DocumentPolicyViolationReportBody``GenericReportReceived``GenericReport``?array`Body classes are plain PHP objects with nullable readonly properties matching the W3C specification for that report type. For example, `CspViolationReportBody` exposes `blockedURL`, `effectiveDirective`, `disposition`, `documentURL`, `originalPolicy`, and so on.

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance97

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 69.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

7

Last Release

15d ago

Major Versions

v1.2.2 → v2.0.02026-05-03

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5163790?v=4)[Audun Rundberg](/maintainers/audunru)[@audunru](https://github.com/audunru)

---

Top Contributors

[![audunru](https://avatars.githubusercontent.com/u/5163790?v=4)](https://github.com/audunru "audunru (18 commits)")[![semantic-release-bot](https://avatars.githubusercontent.com/u/32174276?v=4)](https://github.com/semantic-release-bot "semantic-release-bot (7 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

laravelreportingcspcontent-security-policyReporting API

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/audunru-reporting-api/health.svg)

```
[![Health](https://phpackages.com/badges/audunru-reporting-api/health.svg)](https://phpackages.com/packages/audunru-reporting-api)
```

###  Alternatives

[statamic/cms

The Statamic CMS Core Package

4.8k3.5M901](/packages/statamic-cms)[dedoc/scramble

Automatic generation of API documentation for Laravel applications.

2.1k9.9M87](/packages/dedoc-scramble)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

815320.5k3](/packages/defstudio-telegraph)[rupadana/filament-api-service

A simple api service for supporting filamentphp

208114.4k7](/packages/rupadana-filament-api-service)[simplestats-io/laravel-client

Analytics for Laravel. Track visitors, registrations, and payments. Discover which channels actually drive revenue, not just traffic. Server-side, GDPR compliant, ad-blocker proof.

5019.3k](/packages/simplestats-io-laravel-client)[lettermint/lettermint-laravel

Official Lettermint driver for Laravel

1152.3k1](/packages/lettermint-lettermint-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
