CentralCSP
Reporting APIConcepts

The report delivery format

The application/reports+json envelope the browser POSTs, and how it differs from the legacy application/csp-report format.

Last update:

When the browser delivers reports, it sends an HTTP POST with Content-Type: application/reports+json and a JSON array of report objects. Every report shares the same outer envelope; only the body changes per type. This page is the reference for that envelope, and for the older single-object format that report-uri still uses.

The request

Reports arrive as a POST whose body is a JSON array, not a single object, even when there is only one report. A single delivery can batch several reports together, and they do not have to be the same type: a CSP violation and a deprecation can share one POST if they are queued for the same endpoint. Your receiver should iterate the array and branch on each entry's type.

The envelope fields

Every entry in the array has the same five top-level fields. Only body differs from one report type to the next.

FieldMeaning
typeThe report category, for example csp-violation, deprecation, network-error.
urlThe document the report came from, stripped of credentials and fragment.
user_agentThe User-Agent string of the page that generated the report.
ageMilliseconds between when the report was generated and when it was sent, so you can correct for the batching delay and clock skew.
bodyThe type-specific payload (the fields documented on each report page).
[
  {
    "type": "csp-violation",
    "age": 53,
    "url": "https://api-next.centralcsp.com/",
    "user_agent": "Mozilla/5.0 ...",
    "body": {
      "documentURL": "https://api-next.centralcsp.com/",
      "blockedURL": "https://evil.example/script.js",
      "effectiveDirective": "script-src-elem",
      "disposition": "enforce",
      "statusCode": 200
    }
  }
]

Modern format vs the legacy csp-report format

The Reporting API uses camelCase body fields (documentURL, blockedURL); the legacy report-uri format uses a single object wrapped in csp-report with kebab-case fields (document-uri, blocked-uri) and Content-Type: application/csp-report. An endpoint that accepts both must branch on the Content-Type.

The legacy format predates the Reporting API and is specific to CSP. It is a single object, not an array, it has no envelope (no type, age, or user_agent), and its field names are kebab-case:

{
  "csp-report": {
    "document-uri": "https://api-next.centralcsp.com/",
    "blocked-uri": "https://evil.example/script.js",
    "effective-directive": "script-src-elem",
    "original-policy": "default-src 'self'; report-uri /csp-reports",
    "disposition": "enforce",
    "status-code": 200
  }
}

So a receiver that supports both reads the Content-Type: application/reports+json means the modern array, application/csp-report means the legacy object. The csp-violation report page documents both shapes field by field.

See also

Sources

On this page