# How the Reporting API works (/en/docs/web-security/reporting-api/concepts/how-the-reporting-api-works)



The Reporting API separates the thing that produces a report (a policy like [CSP](/en/docs/web-security/policies/content-security-policy) or [COOP](/en/docs/web-security/policies/cross-origin-opener-policy)) from the thing that delivers it (the browser's report queue). A policy flags
an event, the browser collects it, batches it with others, and sends it to your
endpoint later, independent of the page. That decoupling is why a report can still
arrive after the page has navigated away or crashed.

## How the Reporting API delivers reports [#how-the-reporting-api-delivers-reports]

The producers are the policies and platform features: Content Security Policy,
Cross-Origin-Opener-Policy (COOP), Cross-Origin-Embedder-Policy (COEP),
Permissions-Policy, Document-Policy, Integrity-Policy, Network Error Logging, and
the implicit features that emit deprecation, intervention, and crash reports. Each
of these decides when something is worth reporting.

The Reporting API is the shared machinery underneath them. It defines no policy
behavior of its own; it only structures each report into a common envelope, queues
it, and delivers it. That is the key idea: the same transport carries a CSP
violation, a network error, and a deprecation warning, so you configure delivery
once and every producer uses it.

## Declaring where reports go [#declaring-where-reports-go]

You declare endpoints with one response header, `Reporting-Endpoints`, mapping a
name to an HTTPS URL. A policy then references that name to route its reports.

```http
Reporting-Endpoints: default="https://<Endpoint-ID>.report.centralcsp.com"
```

CSP names an endpoint with its `report-to` directive; COOP and COEP use a
`report-to=` parameter; Integrity-Policy uses `endpoints=()`; and the implicit
report types go to [the default reporting endpoint](/en/docs/web-security/reporting-api/concepts/default-endpoint). The full syntax, and the older
`Report-To` header that NEL still needs, are in the
[Headers](/en/docs/web-security/reporting-api/headers) section.

## Queueing, batching, and delivery [#queueing-batching-and-delivery]

When a report is generated, the browser does not send it on its own. It adds the
report to a queue, groups queued reports by endpoint and then by origin, and
delivers each group as a single HTTP `POST` with
`Content-Type: application/reports+json`. One delivery can therefore carry several
reports of different types.

```mermaid
sequenceDiagram
  participant Policy as "Policy (CSP, COOP, NEL)"
  participant Browser as "Browser queue"
  participant Endpoint as "Your endpoint"
  Policy->>Browser: event occurs, report generated
  Note over Browser: queued and batched<br/>out of band, can be delayed
  Browser->>Endpoint: POST batch as application/reports+json
  Note over Browser,Endpoint: best-effort, no guaranteed retry
```

Timing is up to the browser, not the spec. Chromium batches and can delay delivery
by up to about a minute to save battery and bandwidth on mobile, so a report you
trigger now may not arrive for a little while. That is normal; design your endpoint
to accept reports whenever they show up rather than expecting them in real time.

## Best-effort, not guaranteed [#best-effort-not-guaranteed]

<Callout type="info">
  The spec is explicit that delivery is best-effort. Reporting is not a reliable communications channel, and there is no defined retry mechanism, so do not build logic that depends on every report arriving.
</Callout>

Delivery can also stop. The browser tracks failures per endpoint, and an endpoint
that repeatedly fails, or that responds with HTTP `410 Gone`, is dropped and stops
receiving reports. So an endpoint that returns errors does not just lose the current
batch; it can be removed entirely. Return a `2xx` status from your receiver, and use
`410` deliberately if you ever want the browser to stop sending.

## See also [#see-also]

* [The report delivery format](/en/docs/web-security/reporting-api/concepts/report-delivery-format)
* [Report-To vs Reporting-Endpoints](/en/docs/web-security/reporting-api/concepts/report-to-vs-reporting-endpoints)
* [Headers](/en/docs/web-security/reporting-api/headers)
* Collect and aggregate every report type with [CentralCSP reporting](/en/docs/platform/monitoring).

## Sources [#sources]

* [W3C, Reporting API](https://www.w3.org/TR/reporting-1/)
* [MDN, Reporting API](https://developer.mozilla.org/en-US/docs/Web/API/Reporting_API)
* [Chrome, the Reporting API](https://developer.chrome.com/docs/capabilities/web-apis/reporting-api)
