Skip to content

Reports API

Weekly Certificate and Secret Expiry Reports — Settings, Trigger, and Preview

Document Version: 1.0.61
Last Updated: 2026-11-09


Overview

The Reports API manages the weekly expiry report. Each organization has its own e-mail recipients and receives only its own organization's report: the certificates and secrets of its projects that expire within the next 60 days. The report also goes to the organization's report-enabled notification channels (Slack, Teams, webhook, Jira). Certificates without a project belong to no organization and appear in no organization's weekly report; assign them to a project to have them reported.

Method Endpoint Description Permission
GET /api/v1/organizations/{id}/reports/settings Get the organization's recipients report:read in the organization
PUT /api/v1/organizations/{id}/reports/settings Replace the organization's recipients report:write in the organization
POST /api/v1/organizations/{id}/reports/trigger Send the organization's report now report:write in the organization
GET /api/v1/organizations/{id}/reports/preview Preview the organization's report report:read in the organization
GET /api/v1/reports/settings Get the instance-level recipients left from before (they receive nothing) global report:read
PUT /api/v1/reports/settings Change or clear the instance-level recipients global report:write
POST /api/v1/reports/trigger Send every organization its own report now global report:write
GET /api/v1/reports/preview Preview the items of all organizations and projects visible to the caller report:read

"In the organization" means an organization role in that organization or a global role; a project role is not enough.


Get Organization Report Settings

Returns the organization's weekly-report recipients.

GET /api/v1/organizations/{id}/reports/settings HTTP/1.1
Authorization: Bearer <token>

Response 200 OK

{
  "recipients": [
    "security@example.com",
    "ops-team@example.com"
  ]
}

Response Fields

Field Type Description
recipients array of strings Email addresses that receive this organization's weekly report

Update Organization Report Settings

Replaces the organization's full recipient list. Send an empty array to stop e-mail delivery. The change is audited as REPORT_RECIPIENTS_UPDATED (the number of recipients, not the addresses).

PUT /api/v1/organizations/{id}/reports/settings HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json

{
  "recipients": [
    "security@example.com",
    "ops-team@example.com",
    "ciso@example.com"
  ]
}

Request Fields

Field Type Required Description
recipients array of strings ✅ List of email addresses to receive the report (max 10). Each address must be a valid email format. Send [] to disable email delivery.

Response 200 OK

{
  "message": "Settings updated"
}

Scheduling

Every Monday at 07:00 (Europe/Prague) each organization's report is sent to its recipients and report-enabled channels. This endpoint only manages recipients.


Trigger Organization Report

Sends the organization's report now to its recipients and report-enabled channels, with the same content as the scheduled delivery.

POST /api/v1/organizations/{id}/reports/trigger HTTP/1.1
Authorization: Bearer <token>

No request body is required.

Response 200 OK

{
  "message": "Report triggered successfully"
}

Delivery Behavior

Without recipients and report-enabled channels nothing is sent and the request still returns 200 OK. If a recipient or channel cannot be reached, the others still get the report and the request returns 500 with the failed deliveries in details.


Instance-Level Recipients

Before per-organization recipients there was one recipient list for the whole instance. On upgrade, an instance with a single organization moved that list to its organization. With several organizations the list is kept as instance-level recipients that receive no report, so that no organization's report reaches another organization's people. A global admin sees them with GET /api/v1/reports/settings, adds them to the right organizations, and then clears them with PUT /api/v1/reports/settings and {"recipients": []}. The System Outputs → Weekly Expiry Report tab shows them to a global admin with a Clear button.

POST /api/v1/reports/trigger (global role) sends every organization its own report, like the Monday run.


Preview Report

Returns the organization's report content without sending anything: what its recipients would get next. GET /api/v1/reports/preview returns the same shape for all organizations and projects visible to the caller.

GET /api/v1/organizations/{id}/reports/preview HTTP/1.1
Authorization: Bearer <token>

Response 200 OK

{
  "generated_at": "2026-04-26T10:00:00Z",
  "total_certificates": 3,
  "total_secrets": 1,
  "expiring_certificates": [
    {
      "common_name": "api.example.com",
      "expires_at": "2026-05-10T00:00:00Z",
      "days_remaining": 14,
      "issuer": "MazeVault Internal CA",
      "serial_number": "0a:1b:2c:3d:4e:5f",
      "auto_renew": true,
      "project_name": "Backend Services",
      "environment": "production"
    },
    {
      "common_name": "internal.corp.example.com",
      "expires_at": "2026-05-20T00:00:00Z",
      "days_remaining": 24,
      "issuer": "MazeVault Internal CA",
      "serial_number": "ff:ee:dd:cc:bb:aa",
      "auto_renew": false,
      "project_name": "Internal Tools",
      "environment": "staging"
    }
  ],
  "expiring_secrets": [
    {
      "name": "stripe-api-key",
      "expires_at": "2026-05-05T00:00:00Z",
      "days_remaining": 9,
      "type": "api_key",
      "project_name": "Payment Service",
      "environment": "production"
    }
  ]
}

Response Fields

Field Type Description
generated_at string (ISO 8601) Timestamp when this preview was generated
total_certificates integer Number of expiring certificates included in the report
total_secrets integer Number of expiring secrets included in the report
expiring_certificates array List of certificates expiring within the lookahead window
expiring_secrets array List of secrets expiring within the lookahead window

expiring_certificates Object

Field Type Description
common_name string Certificate Common Name (CN)
expires_at string (ISO 8601) Certificate expiry timestamp
days_remaining integer Days until expiry at the time the preview was generated
issuer string Issuing CA name
serial_number string Certificate serial number
auto_renew boolean Whether automatic renewal is configured for this certificate
project_name string Name of the project that owns the certificate
environment string Environment scope of the certificate

expiring_secrets Object

Field Type Description
name string Secret key name
expires_at string (ISO 8601) Secret expiry timestamp
days_remaining integer Days until expiry at the time the preview was generated
type string Secret type (e.g., api_key, password, certificate)
project_name string Name of the project that owns the secret
environment string Environment scope of the secret

Error Responses

HTTP Status Meaning
400 Bad Request Invalid request body — e.g., invalid email address format or more than 10 recipients
401 Unauthorized Missing or invalid bearer token
403 Forbidden The caller has no report:read/report:write organization or global role in the organization (a project role is not enough), or no global role for /api/v1/reports/settings and /trigger
404 Not Found The organization does not exist