# API ## Overview The Report URI REST API gives you programmatic read access to your account data. You can query reports, retrieve Watch product findings, access CSP policies, and pull account configuration — all from your own tooling or scripts. An [OpenAPI 3.1 specification](https://api.report-uri.com/openapi.yaml) is available for use with compatible tooling. ## Getting Your API Key Visit [API](https://report-uri.com/api/getKey/) in your account to generate an API key. The full key is only shown once — at the moment it is created or rotated. Store it securely; if you lose it you will need to rotate it to get a new one. Personal account keys are prefixed `ruri_d_`. Team account keys are prefixed `ruri_t_`. The prefix indicates which account the key is scoped to — a team key returns data for the whole team. ## Authentication All requests must include your API key as a Bearer token in the `Authorization` header. Authorization: Bearer ruri_d_YOUR_KEY_HERE Requests without a valid key return `401 Unauthorized`. { "error": "Unauthorized" } ## Base URL https://api.report-uri.com/v1/ ## Rate Limiting The API allows **120 requests per 60-second window** per API key. Exceeding this returns `429 Too Many Requests`. { "error": "Too many requests" } ## HTTP Methods All endpoints are read-only. Only `GET` requests are accepted. Any other method returns `405 Method Not Allowed`. ## Response Format All responses are JSON. Successful responses return `200 OK` with a JSON object. Error responses return an appropriate status code and a JSON object with an `error` key. | Status | Meaning | |--------|---------| | `200` | Success | | `400` | Invalid request or query parameters | | `401` | Missing or invalid API key | | `403` | Insufficient permissions (e.g. plan restriction) | | `404` | Endpoint or resource not found | | `405` | Method not allowed | | `429` | Rate limit exceeded | | `500` | Internal server error | --- ## Endpoints ### GET /v1/me Returns basic information about the authenticated account. **Request** curl https://api.report-uri.com/v1/me \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response (personal account)** ```json { "type": "personal", "email": "you@example.com" } ``` **Response (team account)** ```json { "type": "team", "teamId": "abc123", "teamName": "Acme Security" } ``` ### GET /v1/setup Returns your account's configured report URIs, Reporting API header value, NEL header value, and email addresses for DMARC and TLS-RPT reporting. **Request** curl https://api.report-uri.com/v1/setup \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "reportUri": { "enforce": "https://abc123.report-uri.com/r/d/csp/enforce", "reportOnly": "https://abc123.report-uri.com/r/d/csp/reportOnly", "wizard": "https://abc123.report-uri.com/r/d/csp/wizard" }, "reportingApi": { "group": "default", "max_age": 31536000, "endpoints": [ { "url": "https://abc123.report-uri.com/a/d/g" } ], "include_subdomains": true }, "nel": { "report_to": "default", "max_age": 31536000, "include_subdomains": true }, "dmarc": "abc123@dmarc.report-uri.com", "tlsRpt": "abc123@tls-rpt.report-uri.com" } ``` ### GET /v1/quota Returns your current monthly quota usage. **Request** curl https://api.report-uri.com/v1/quota \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "used": 142857, "limit": 1000000 } ``` ### GET /v1/plan Returns your current plan details including quota, data retention, and feature entitlements. **Request** curl https://api.report-uri.com/v1/plan \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "plan": "ultimate2025", "name": "Ultimate", "status": "active", "reportQuota": 2000000, "collectHosts": 5, "dataRetentionDays": 90, "features": { "support": true, "teams": true, "blockedWatch": ["scriptWatch", "dataWatch", "frameWatch", "policyWatch"], "webhooks": true, "clientReputationFilter": true, "threatIntelligence": true, "integrityFeatures": ["cspIntegrity", "integrityPolicy"], "pciDss": false, "wildcardDomains": false } } ``` The `status` field is one of `active`, `canceled`, `past_due`, or `inactive`. The `blockedWatch` and `integrityFeatures` fields list the specific products enabled on the plan, or an empty array if the feature is not included. ### GET /v1/team Returns details about your team including members, roles, quota, and 2FA configuration. Only available when authenticated with a team key. **Request** curl https://api.report-uri.com/v1/team \ -H "Authorization: Bearer ruri_t_YOUR_KEY_HERE" **Response** ```json { "teamName": "Acme Security", "quotaLimit": 10000000, "require2fa": true, "members": [ { "email": "alice@example.com", "role": "owner" }, { "email": "bob@example.com", "role": "member" } ] } ``` --- ## Reports ### GET /v1/reports/{type} Returns individual report records for a given report type and time period. Results are scoped to the authenticated account and subject to your plan's retention limit. **Path parameter** | Parameter | Description | |-----------|-------------| | `type` | Report type — see [Report Types](#get-v1report-types) for valid values | **Required query parameters** | Parameter | Description | |-----------|-------------| | `unit` | Time unit: `hours`, `days`, or `months` | | `date` | Date for the period, formatted as `2026-03-23T14` (hours), `2026-03-23` (days), or `2026-03` (months) | **Optional filter parameters** | Parameter | Applies to | |-----------|------------| | `action` | CSP — `enforced` or `reportOnly` | | `hostnames` | Page hostname filter (comma-separated, wildcards supported) | | `paths` | Page path filter | | `effectiveDirective` | CSP directive | | `blockedHostnames` | Blocked resource hostname | | `blockedPaths` | Blocked resource path | | `subresourceHostnames` | CSP Integrity subresource hostname | | `subresourcePaths` | CSP Integrity subresource path | | `subresourceHashes` | CSP Integrity subresource hash | | `browser` | Browser name | | `platform` | OS/platform name | | `nelType` | NEL error type (only applies to `nel` reports) | | `phase` | NEL phase | | `disposition` | Permissions Policy disposition | | `organisation` | AS organisation name | | `id` | Specific report ID | | `certType` | Certificate Transparency cert type | | `issuer` | Certificate issuer | | `sha256Spki` | Certificate SHA-256 SPKI hash | | `policyId` | CSP policy ID | | `message` | Deprecation or Intervention message | | `policy` | Policy Watch policy text | | `property` | Permissions Policy property | | `destination` | Integrity Policy destination | | `ioc` | `true` to filter to threat intelligence matches only. Requires the Threat Intelligence plan | | `generatedDomain` | `true` to filter to algorithmically generated domains (CSP reports only). Requires the Threat Intelligence plan | | `newlyRegisteredDomain` | `true` to filter to newly registered domains. Requires the Threat Intelligence plan | | `domainReputationScore` | Maximum domain reputation score (integer). Requires the Threat Intelligence plan | | `anyThreatIntel` | `true` to filter to reports matching any threat-intelligence signal. Overrides the individual threat-intel filters above. Requires the Threat Intelligence plan | **Request** curl "https://api.report-uri.com/v1/reports/csp?unit=days&date=2026-03-23&action=enforced" \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "reports": [ { "action": "Enforced", "date": "2026-03-23T14:32:01+00:00", "uri": "https://example.com/checkout", "directive": "script-src", "blockedUri": "https://cdn.evil.com/track.js", "raw": "{\"csp-report\":{\"document-uri\":\"https://example.com/checkout\",\"blocked-uri\":\"https://cdn.evil.com/track.js\",\"effective-directive\":\"script-src\",\"original-policy\":\"script-src cdn.evil.com; ...\"}}", "count": 14, "browser": "Chrome", "platform": "Windows", "generatedDomain": 0, "indicatorOfCompromise": 1, "recentlyRegisteredDomain": 0, "lowReputationDomain": 0, "policyIocHosts": ["cdn.evil.com"], "policyConcernHosts": [] } ], "truncated": false } ``` The `truncated` field is `true` when the result set has been capped. Narrow your time period or apply filters to retrieve a complete result. The threat intelligence fields (`generatedDomain`, `indicatorOfCompromise`, `recentlyRegisteredDomain`, `lowReputationDomain`, `policyIocHosts`, `policyConcernHosts`) are present for all accounts but are meaningful only on plans that include the Threat Intelligence feature — on other plans the integer fields will be `0` and the host-list fields will be empty arrays. `indicatorOfCompromise` and `generatedDomain` reflect the blocked resource; `policyIocHosts` and `policyConcernHosts` reflect the hosts in the report's `original-policy` that are flagged — these are list-valued fields (arrays of hostname strings) and can be non-empty even when no violation has been blocked, because the policy allowlist may permit a flagged host that the browser never had reason to block. --- ## Graphs & Analytics ### GET /v1/graphs/{type}/{unit}/{amount} Returns report counts broken down by period for charting and trend analysis. Periods greater than one week require a paid plan. **Path parameters** | Parameter | Description | |-----------|-------------| | `type` | Report type — see [Report Types](#get-v1report-types) | | `unit` | `weeks` or `months` | | `amount` | For weeks: `1`, `2`, `3`, or `4`. For months: `3`, `6`, or `12` | **Request** curl https://api.report-uri.com/v1/graphs/csp/weeks/2 \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response (non-CSP type)** ```json { "type": "nel", "unit": "weeks", "amount": 2, "periods": [ { "date": "2026-03-09", "total": 4821 }, { "date": "2026-03-10", "total": 5103 }, { "date": "2026-03-11", "total": 3298 } ] } ``` **Response (CSP — includes per-directive breakdown)** ```json { "type": "csp", "unit": "weeks", "amount": 1, "periods": [ { "date": "2026-03-23", "total": 9142, "directives": { "script-src": 6201, "style-src": 1488, "img-src": 903, "connect-src": 550, "unknown": 0 } } ] } ``` ### GET /v1/last-seven-days Returns daily report totals for the last seven days, broken down by report type. **Request** curl https://api.report-uri.com/v1/last-seven-days \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "days": [ { "date": "2026-03-17", "csp": 8201, "nel": 412, "dmarc": 0 }, { "date": "2026-03-18", "csp": 7953, "nel": 388, "dmarc": 3 } ] } ``` ### GET /v1/breakdown Returns the current month's report count broken down by type. **Request** curl https://api.report-uri.com/v1/breakdown \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "breakdown": { "csp": 241892, "nel": 18443, "dmarc": 72, "certificate_transparency": 0 } } ``` ### GET /v1/usage-metrics Returns report counts broken down by type and action (accepted, filtered, sampled, rejected). **Request** curl https://api.report-uri.com/v1/usage-metrics \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "metrics": [ { "type": "csp", "accepted": 241892, "filtered": 18320, "sampled": 0, "rejected": 441 }, { "type": "nel", "accepted": 18443, "filtered": 902, "sampled": 0, "rejected": 12 } ] } ``` --- ## Policies ### GET /v1/policies/csp Returns all saved CSP policies for the account. **Request** curl https://api.report-uri.com/v1/policies/csp \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "policies": [ { "id": "policy-abc123", "name": "Main site", "policy": "default-src 'none'; script-src 'self'; style-src 'self'" } ] } ``` ### GET /v1/policies/csp/{id} Returns a single saved CSP policy by ID. **Path parameter** | Parameter | Description | |-----------|-------------| | `id` | Policy ID from `/v1/policies/csp` | **Request** curl https://api.report-uri.com/v1/policies/csp/policy-abc123 \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "id": "policy-abc123", "name": "Main site", "policy": "default-src 'none'; script-src 'self'; style-src 'self'" } ``` ### GET /v1/wizard/csp Returns the current state of the CSP Wizard for the account. **Request** curl https://api.report-uri.com/v1/wizard/csp \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "active": true, "policy": "default-src 'none'; script-src 'self' 'nonce-abc123'" } ``` --- ## Watch Products ### GET /v1/watches/script ### GET /v1/watches/data ### GET /v1/watches/frame ### GET /v1/watches/policy Returns the list of domains enrolled in the respective Watch product, along with their alert configuration. **Request** curl https://api.report-uri.com/v1/watches/script \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "watches": [ { "site": "example.com", "emailAlertsEnabled": true, "webhookEnabled": false, "webhookTarget": null, "alertThreshold": 3 } ] } ``` ### GET /v1/watches/script/{domain} ### GET /v1/watches/data/{domain} ### GET /v1/watches/frame/{domain} Returns blocked resource findings for the given domain, sorted by most recently seen. Returns `404` if the domain is not enrolled in the Watch product. **Path parameter** | Parameter | Description | |-----------|-------------| | `domain` | Domain enrolled in the Watch product | **Request** curl https://api.report-uri.com/v1/watches/script/example.com \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "findings": [ { "uri": "https://cdn.evil.com/tracker.js", "count": 142, "firstSeen": "2026-03-01T09:14:22+00:00", "lastSeen": "2026-03-23T14:55:01+00:00", "source": "csp" } ] } ``` The `source` field indicates how the item was detected: `csp`, `csp_integrity`, or `integrity_policy`. ### GET /v1/watches/policy/{domain} Returns observed CSP policies for the given domain. Returns `404` if the domain is not enrolled in Policy Watch. **Request** curl https://api.report-uri.com/v1/watches/policy/example.com \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "findings": [ { "policy": "default-src 'none'; script-src 'self'", "enforced": true, "count": 8821, "firstSeen": "2026-01-15T10:00:00+00:00", "lastSeen": "2026-03-23T14:00:00+00:00" } ] } ``` --- ## Other Endpoints ### GET /v1/filters Returns your current filter configuration including global filters, advanced filters, Certificate Transparency filters, and sampling rates. **Request** curl https://api.report-uri.com/v1/filters \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" ### GET /v1/report-types Returns all valid report type identifiers and their display labels. **Request** curl https://api.report-uri.com/v1/report-types \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "types": [ { "type": "csp", "label": "CSP" }, { "type": "nel", "label": "NEL" }, { "type": "dmarc", "label": "DMARC" }, { "type": "certificate_transparency", "label": "Certificate Transparency" } ] } ``` ### GET /v1/audit-log Returns a log of account activity including API key creation, rotation, deletion, and other account events. **Request** curl https://api.report-uri.com/v1/audit-log \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "events": [ { "date": "2026-03-20T11:42:00+00:00", "event": "api_key_created", "actor": "you@example.com" } ] } ``` ### GET /v1/certificate-transparency/cert/{sha256} Returns the raw PEM-encoded certificate for a given SHA-256 hash observed in your Certificate Transparency reports. **Path parameter** | Parameter | Description | |-----------|-------------| | `sha256` | SHA-256 hash of the certificate | **Request** curl https://api.report-uri.com/v1/certificate-transparency/cert/abc123def456 \ -H "Authorization: Bearer ruri_d_YOUR_KEY_HERE" **Response** ```json { "pem": "-----BEGIN CERTIFICATE-----\nMIIE....\n-----END CERTIFICATE-----\n" } ```