- Overview
- Reference Guide
- Setup & Architecture
- Release Notes
- Workflow
- API Reference
- Integration Guide
- Discovery Agent Setup Guide
Reports
The Reports endpoints generate certificate, risk, key strength, algorithm, self-signed, and wildcard reports, and manage the risk rules used to score certificates.
For the corresponding user interface, refer to the Reports section.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /reports | Get the certificate report for a CA. |
| POST | /reports | Start a CSV export of the certificate report. |
| GET | /reports/audit_report | Certificate audit report (deprecated). |
| POST | /reports/audit_trail | Start a CSV export of a CA's audit trail. |
| GET | /reports/certificate_issue_count | Certificate issue count. |
| GET | /reports/certificate_issue_report | Certificate issue report (CSV text, paged). |
| GET | /reports/certificate_issue_report_xlsx | Download the certificate issue report (CSV). |
| GET | /reports/certificate_report | Certificate report by status. |
| GET | /reports/compliance_policies | Compliance policies behind each risk parameter. |
| GET | /reports/config_keylength | Get key-length risk thresholds. |
| POST | /reports/config_keylength | Update key-length risk thresholds. |
| GET | /reports/config_risk | Get the risk report column configuration. |
| POST | /reports/config_risk | Set the visible risk report columns. |
| GET | /reports/count_by_template | Certificate count by template report. |
| GET | /reports/download | Download a finished report export. |
| GET | /reports/expired_last_7_days | Certificates that expired in the last 7 days. |
| GET | /reports/key_algorithms_report | Key strength report (CSV text). |
| GET | /reports/key_length | Key length report. |
| GET | /reports/key_strength_analytics | Key strength analytics. |
| GET | /reports/properties | Get report display columns. |
| POST | /reports/properties | Set report display columns. |
| GET | /reports/risk_profile_count | Risk profile count. |
| GET | /reports/risk_profile_report | Risk profile report (paged). |
| GET | /reports/risk_report_xlsx | Download the risk report as an Excel workbook. |
| GET | /reports/self_signed_report | Self-signed third-party certificate report. |
| GET | /reports/signing_algorithm_report | Signing algorithm report. |
| GET | /reports/status | Check the progress of a report export. |
| GET | /reports/wildcard_report | Wildcard certificate report. |
GET /reports
The certificate report for one CA, in one of two shapes. When BOTH count and page are supplied the answer is a JSON page of rows plus the exact total and the CA's column list (application/json). With either missing, the WHOLE report is returned as CSV text (a title line, a blank line, the header row, then one row per certificate; it is served with a text/html Content-Type) and search, filter and filterOperator are ignored. To export a filtered report use POST /reports. Rows are always ordered by Serial Number, and sortBy / sortOrder are refused with a 400 when paginating. Only columns configured for the CA (GET /reports/properties) can be filtered or searched.
Note: Call this endpoint without a trailing slash (/reports). The Swagger API lists it as /reports/.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | Yes | CertSecure name of the Certificate Authority to report on. This is the Name returned by GET /ca, not the CA's subject DN. The match is case-insensitive. A name that is not a registered CA is refused with a 400. |
type |
Query | string | No | Which certificates to report on, by status. Case-insensitive; defaults to active when omitted. expiring means active certificates whose expiry falls inside the from..to day window, so it needs both of those. |
from |
Query | integer | No | Start of the expiry window for type=expiring, as a number of days from now (0 is now). Must be 0 or more and less than to. Required with type=expiring; for every other type it is ignored, but if sent it must still be an integer. |
to |
Query | integer | No | End of the expiry window for type=expiring, as a number of days from now. Must be 0 or more and greater than from. Required with type=expiring; for every other type it is ignored, but if sent it must still be an integer. |
count |
Query | integer | No | Rows per page. Pagination only happens when count and page are BOTH sent; both must then be positive integers (otherwise a 400), and count is silently capped at 500. The capped value is echoed back in the response. |
page |
Query | integer | No | One-based page number. Pagination only happens when count and page are BOTH sent; both must then be positive integers (otherwise a 400). |
tags |
Query | string | No | Comma-separated list of certificate tags. Only certificates carrying at least one of the listed tags are reported. Blank entries are ignored. |
template |
Query | string | No | Only report certificates issued from this certificate template. Exact match against the certificate's Certificate Template value. |
filter |
Query | array of string | No | Column filter, written <column>:<operator>:<value> (split on the first two colons, so the value may itself contain colons). Repeat the parameter to add several filters. column must be one of the CA's configured report columns (the headers of the JSON page), otherwise the request is refused. Text operators, all case-insensitive: startsWith, contains, notContains, endsWith, equals, notEquals. Date operators: dateIs, dateIsNot, dateBefore, dateAfter, whose value must be YYYY-MM-DD. Only applied to the paginated JSON page (when count and page are both sent); ignored when the whole report is returned as CSV. |
filterOperator |
Query | array of string | No | How several filters on the SAME column combine, written <column>:and or <column>:or. Repeat for several columns. column must be one of the CA's configured report columns, otherwise the request is refused (400). A column that is not named combines with and. Filters on different columns are always ANDed. Only applied to the paginated JSON page (when count and page are both sent); ignored when the whole report is returned as CSV. |
search |
Query | string | No | Case-insensitive "contains" search across all of the CA's configured report columns. Must be at least 3 characters once trimmed (shorter is refused with a 400); a blank value means no search. Only applied to the paginated JSON page (when count and page are both sent); ignored when the whole report is returned as CSV. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports?ca=<ca>" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | The report. A JSON page when count and page were both sent; otherwise the complete report as CSV text. |
| 400 | The request was refused. The body is {"Error": "<reason>"}. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | An unexpected server-side failure while building the report; the body carries the exception text. |
Example Response
{
"data": [
{
"Common Name": "www.example.com",
"Serial Number": "4A1B2C3D4E5F",
"Certificate Expiration Date": "2026-12-31T23:59:00"
}
],
"total": 1,
"page": 1,
"count": 25,
"headers": [
"Common Name",
"Serial Number",
"Certificate Expiration Date"
],
"searched_columns": []
}
POST /reports
Starts a background job that builds the certificate report for one CA as a CSV file and answers 202 with its job_id immediately. Poll GET /reports/status until the job is complete, then fetch the file from GET /reports/download. The export honours the same type, from, to, tags, template, search, filter and filterOperator parameters as the paginated GET /reports page, so it contains exactly the rows that page would show; sortBy / sortOrder are refused. All inputs travel in the query string; the request has no body. Asking again with the same parameters while an identical job is still running returns that job's id instead of starting another, and at most 5 jobs may run at once. The job can only be read back by the user who started it, or a global Admin.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | Yes | CertSecure name of the Certificate Authority to report on. This is the Name returned by GET /ca, not the CA's subject DN. The match is case-insensitive. A name that is not a registered CA is refused with a 400. |
type |
Query | string | No | Which certificates to report on, by status. Case-insensitive; defaults to active when omitted. expiring means active certificates whose expiry falls inside the from..to day window, so it needs both of those. |
from |
Query | integer | No | Start of the expiry window for type=expiring, as a number of days from now (0 is now). Must be 0 or more and less than to. Required with type=expiring; for every other type it is ignored, but if sent it must still be an integer. |
to |
Query | integer | No | End of the expiry window for type=expiring, as a number of days from now. Must be 0 or more and greater than from. Required with type=expiring; for every other type it is ignored, but if sent it must still be an integer. |
tags |
Query | string | No | Comma-separated list of certificate tags. Only certificates carrying at least one of the listed tags are reported. Blank entries are ignored. |
template |
Query | string | No | Only report certificates issued from this certificate template. Exact match against the certificate's Certificate Template value. |
filter |
Query | array of string | No | Column filter, written <column>:<operator>:<value> (split on the first two colons, so the value may itself contain colons). Repeat the parameter to add several filters. column must be one of the CA's configured report columns (the headers of the JSON page), otherwise the request is refused. Text operators, all case-insensitive: startsWith, contains, notContains, endsWith, equals, notEquals. Date operators: dateIs, dateIsNot, dateBefore, dateAfter, whose value must be YYYY-MM-DD. Applied to the exported rows, so the CSV contains what the matching page would show. |
filterOperator |
Query | array of string | No | How several filters on the SAME column combine, written <column>:and or <column>:or. Repeat for several columns. A column that is not named combines with and. Filters on different columns are always ANDed. Applied to the exported rows, so the CSV contains what the matching page would show. |
search |
Query | string | No | Case-insensitive "contains" search across all of the CA's configured report columns. Must be at least 3 characters once trimmed (shorter is refused with a 400); a blank value means no search. Applied to the exported rows, so the CSV contains what the matching page would show. |
Example Request
curl -X POST "https://<certsecure-backend-url>/reports?ca=<ca>" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 202 | The export job was accepted (or an identical job is already running) and its id returned. |
| 400 | The request was refused. The body is {"Error": "<reason>"} ({"error": ...} for a bad from/to). |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 429 | Too many export jobs are already running (the limit is 5 at once). Try again shortly. |
GET /reports/audit_report
Deprecated. Use GET /enrollment/audit_trail?ca= to view a CA's audit trail and POST /reports/audit_trail to download it as CSV; this route will be removed in a later release. Every active, expired and revoked certificate of one CA as CSV text, ordered by status (a title line, a blank line, the header row, then one row per certificate). Columns are the CA's configured report columns plus status. E-mail addresses in values are replaced by [email protected]. It is served with a text/html Content-Type.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | Yes | CertSecure name of the Certificate Authority to report on. This is the Name returned by GET /ca, not the CA's subject DN. The match is case-insensitive. A name that is not a registered CA is refused with a 400. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/audit_report?ca=<ca>" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | CSV text, one row per certificate. |
| 400 | The ca parameter is missing, empty or does not name a registered Certificate Authority, or the CA has no report columns configured. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
POST /reports/audit_trail
Starts a background job that writes every audit-trail record of one CA (the data GET /enrollment/audit_trail?ca= shows) to a CSV file and answers 202 with its job_id immediately. Poll GET /reports/status until the job is complete, then fetch the file from GET /reports/download. The CSV has one row per certificate with the columns Serial Number, Common Name, Enrollment ID, Owner, Requesters, Approvers, Deniers, Revoker, Created (UTC) and Updated (UTC); list columns are joined with ; . Names and e-mail addresses are NOT redacted, so the caller needs Manage Certification Authorities. Asking again for the same CA while your job is still running returns that job's id, and at most 5 report jobs may run at once. The job can only be read back by the user who started it, or a global Admin. All inputs travel in the query string; the request has no body.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | Yes | CertSecure name of the Certificate Authority whose audit trail to export. This is the Name returned by GET /ca. A name that is not a registered CA is refused with a 400. |
Example Request
curl -X POST "https://<certsecure-backend-url>/reports/audit_trail?ca=<ca>" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 202 | The export job was accepted (or your identical job is already running) and its id returned. |
| 400 | ca is missing, empty or not a registered Certificate Authority. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 403 | The caller lacks Manage Certification Authorities. |
| 429 | Too many export jobs are already running (the limit is 5 at once). Try again shortly. |
GET /reports/certificate_issue_count
Returns, for each certificate-quality issue category, how many active certificates are affected and how serious that is, read from the precomputed report cache (so it is not real time). Only categories whose column is enabled in the risk configuration (GET /reports/config_risk) are included. Estate-wide unless ca is given, in which case only that CA's certificates are assessed (empty for a CA with no active certificates). The body is an empty object {} when the cache has not been built yet or could not be read; this operation answers 200 in both cases.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | CertSecure name of the Certificate Authority to act against. This is the Name returned by GET /ca, not the CA's subject DN. Callers only ever see CAs their department is entitled to. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/certificate_issue_count" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | Issue categories keyed by name (empty object when nothing is cached). |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
Example Response
{
"Weak Key Length": {
"count": 3,
"level": "high",
"grade": "secure"
},
"Missing AIA": {
"count": 120,
"level": "mid",
"grade": "high"
},
"Certificate Duration": {
"count": 450,
"level": "high",
"grade": "severe"
}
}
GET /reports/certificate_issue_report
Returns one page of the active certificates as CSV text, restricted to the columns enabled by the risk configuration (GET /reports/config_risk; the default is Serial Number, Key Length, Signing Algorithm, SAN Attributes, Public Key Algorithm, AIA, CDP, KeyUsages, EnhancedKeyUsages, CertificatePolicies, Duration). The first line is the header row (UTF-8 with a byte-order mark). The body is CSV although the response is served as text/html. page and per_page must be integers (400 otherwise). A request that is well formed but cannot be matched - filter names a column that is not enabled (or is Serial Number), key_word is not an integer for a Key Length/Duration filter, sort names a column that is not enabled, or no certificate matches - is answered 200 with a header-only CSV, so such an answer means "nothing to show for this request", not a failure. An unexpected failure while building the report is a 500. page and per_page always apply (defaults 1 and 50, per_page clamped to 1-500) and a page past the last one falls back to page 1. filter and key_word only take effect together.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | CertSecure name of the Certificate Authority whose certificates to return: the Name returned by GET /ca. Optional - omit it, or send all, for every CA. |
filter |
Query | string | No | Name of an enabled risk column to filter on (any column except Serial Number), for example Duration. Only applied together with key_word; an unknown column yields a header-only CSV. |
key_word |
Query | string | No | Exact value the filtered column must equal. It must be an integer when filter is Key Length or Duration, otherwise a header-only CSV is returned. Only applied together with filter. |
order |
Query | string | No | Sort direction used together with sort. Only the exact value ascending sorts ascending; any other value, including asc, sorts descending. Default ascending. |
page |
Query | integer | No | One-based page number, default 1; values below 1 are treated as 1 and a page past the last one falls back to 1. A value that is not an integer is a 400. |
per_page |
Query | integer | No | Rows per page, default 50; clamped to the range 1-500. A value that is not an integer is a 400. |
sort |
Query | string | No | Name of an enabled risk column to order by, for example Duration. When omitted rows come back in storage order. A column that is not enabled yields a header-only CSV. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/certificate_issue_report" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | CSV text (served as text/html): a header row and one row per certificate of the requested page. A header-only body means nothing could be returned for this request. |
| 400 | page or per_page is not an integer. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | An unexpected failure while building the report. |
GET /reports/certificate_issue_report_xlsx
Despite the _xlsx in its path this returns CSV, not an Excel workbook: a streamed attachment named cert_report.csv holding every active certificate with the eleven risk-related columns (Serial Number, Key Length, Signing Algorithm, SAN Attributes, Public Key Algorithm, AIA, CDP, KeyUsages, EnhancedKeyUsages, CertificatePolicies, Duration), UTF-8 with a byte-order mark. It takes no parameters and is not limited by CA or by the risk configuration.
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/certificate_issue_report_xlsx" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | The CSV file, streamed as an attachment. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | The export could not be started. |
GET /reports/certificate_report
Certificates of one CA (or of every CA) in a given status, as CSV text (a title line, a blank line, the header row, then one row per certificate), served with a text/html Content-Type. The status is chosen by sending ONE of the presence flags active, pending, denied or revoked (any value, even an empty one, counts as present; if several are sent the first in that order wins). Sending none of them is a 400. days narrows a revoked report to certificates revoked in the last N days and is only valid together with revoked (with any other status it is a 400). With ca the columns are that CA's configured report columns; without it, all certificate fields.
Note: At least one status filter (active, pending, denied, or revoked) must be passed; otherwise the request returns 400 with the error "Status is required".
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | CertSecure name of the Certificate Authority to report on (the Name returned by GET /ca). Omit to cover every configured CA. A name that is not a registered CA is a 400. |
active |
Query | string | No | Presence flag: send it (any value) to report ACTIVE certificates. One of active, pending, denied, revoked is required. |
pending |
Query | string | No | Presence flag: send it (any value) to report PENDING certificates. Ignored if active is also sent. One of active, pending, denied, revoked is required. |
denied |
Query | string | No | Presence flag: send it (any value) to report DENIED certificates. Ignored if active or pending is also sent. One of active, pending, denied, revoked is required. |
revoked |
Query | string | No | Presence flag: send it (any value) to report REVOKED certificates. Ignored if any of active, pending, denied is also sent. One of active, pending, denied, revoked is required. |
days |
Query | integer | No | Only with revoked (and none of the other status flags): restrict the report to certificates revoked within this many days up to now. Must be an integer. With any other status, or a non-integer, the request is a 400. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/certificate_report" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | CSV text, one row per certificate. |
| 400 | None of active, pending, denied, revoked was sent, days was sent without revoked (or with another status flag winning), days is not an integer, or ca is not a registered CA. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | Any failure while building the report. |
GET /reports/compliance_policies
Returns the static reference table that explains why each risk parameter matters: for every parameter (key_length, signing_algorithm, public_key_algorithm, aia, cdp, key_usage, enhanced_key_usages, certificate_policies, san_attributes, duration) a display name, an importance level and the standards (NIST, CA/Browser Forum, PCI DSS, RFCs, ISO) that justify it. The content is built into the product and does not change per request.
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/compliance_policies" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | Reference table keyed by risk parameter. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | The table could not be returned. |
Example Response
{
"key_length": {
"display_name": "Key Length",
"level": "High",
"relevance": [
{
"detail": "Subscriber certificates must use RSA keys of at least 2048 bits or ECC keys of at least 256 bits.",
"source": "CA/Browser Forum Baseline Requirements",
"link": "https://cabforum.org/baseline-requirements/"
}
]
}
}
GET /reports/config_keylength
Returns the current minimum key sizes. Passing rsa and/or ecc here does not just read: it validates, saves and returns the updated pair, the same as POST.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
rsa |
Query | integer | No | New minimum key length in bits for RSA, DSA and DH keys: an integer from 1024 to 16384. Omit to leave unchanged. |
ecc |
Query | integer | No | New minimum key length in bits for elliptic-curve keys: an integer from 160 to 521. Omit to leave unchanged. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/config_keylength" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | The thresholds now in force. |
| 400 | The body is not a JSON object, or a supplied threshold is not an integer or is out of range. Nothing is saved. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | An unexpected server-side failure while reading or saving the thresholds; the body carries the exception text. |
Example Response
{
"rsa": 2048,
"ecc": 256
}
POST /reports/config_keylength
Saves new minimum key sizes from a JSON body (or the query string, which wins when both are present) and returns the full updated pair. Fields that are omitted keep their current value; with neither field the call only reads, like GET.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
rsa |
Query | integer | No | New minimum key length in bits for RSA, DSA and DH keys: an integer from 1024 to 16384. Omit to leave unchanged. |
ecc |
Query | integer | No | New minimum key length in bits for elliptic-curve keys: an integer from 160 to 521. Omit to leave unchanged. |
Request Body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
rsa |
integer | No | New minimum key length in bits for RSA, DSA and DH keys: an integer from 1024 to 16384. Omit to leave unchanged. Not used when rsa is also in the query string, but still checked: null, a boolean, a fraction or a value outside the range is a 400. |
ecc |
integer | No | New minimum key length in bits for elliptic-curve keys: an integer from 160 to 521. Omit to leave unchanged. Not used when ecc is also in the query string, but still checked: null, a boolean, a fraction or a value outside the range is a 400. |
Example Request
curl -X POST "https://<certsecure-backend-url>/reports/config_keylength" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"rsa":2048,"ecc":256}'
Responses
| Status Code | Description |
|---|---|
| 200 | The thresholds now in force. |
| 400 | The body is not a JSON object, or a supplied threshold is not an integer or is out of range. Nothing is saved. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | An unexpected server-side failure while reading or saving the thresholds; the body carries the exception text. |
Example Response
{
"rsa": 2048,
"ecc": 256
}
GET /reports/config_risk
The risk configuration decides which columns the risk reports (/reports/risk_profile_report, /reports/certificate_issue_report, /reports/certificate_issue_count) show. GET returns the stored configuration, creating the default one if none exists. POST replaces the list of visible columns. The body must be a JSON object (Content-Type: application/json), and vector a non-empty array of the known column names; anything else is answered 400 and nothing is stored.
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/config_risk" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | The stored risk configuration. If it cannot be read the default configuration is returned, still with 200. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
Example Response
{
"Name": "Risk Config",
"vector": [
"Serial Number",
"Key Length",
"Signing Algorithm",
"SAN Attributes",
"Public Key Algorithm",
"AIA",
"CDP",
"KeyUsages",
"EnhancedKeyUsages",
"CertificatePolicies",
"Duration"
],
"visible vector": [
"Serial Number",
"Key Length",
"Signing Algorithm",
"SAN Attributes",
"Public Key Algorithm",
"AIA",
"CDP",
"KeyUsages",
"EnhancedKeyUsages",
"CertificatePolicies",
"Duration"
]
}
POST /reports/config_risk
The risk configuration decides which columns the risk reports (/reports/risk_profile_report, /reports/certificate_issue_report, /reports/certificate_issue_count) show. GET returns the stored configuration, creating the default one if none exists. POST replaces the list of visible columns. The body must be a JSON object (Content-Type: application/json), and vector a non-empty array of the known column names; anything else is answered 400 and nothing is stored.
Request Body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
vector |
array of string | Yes | The columns to show in the risk reports, stored as the new visible vector. Each entry must be one of Serial Number, Key Length, Signing Algorithm, SAN Attributes, Public Key Algorithm, AIA, CDP, KeyUsages, EnhancedKeyUsages, CertificatePolicies and Duration (400 otherwise). Must not be empty. |
Example Request
curl -X POST "https://<certsecure-backend-url>/reports/config_risk" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"vector":["Key Length","Signing Algorithm","SAN Attributes","Public Key Algorithm"]}'
Responses
| Status Code | Description |
|---|---|
| 200 | Successful response. |
| 400 | The body is not a JSON object, vector is missing, null or empty, is not an array of strings, or names a column that does not exist. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | The update failed unexpectedly; the cause is in the server log. |
Example Response
{
"Message": "Risk parameters updated successfully."
}
GET /reports/count_by_template
Number of certificates per certificate template for one CA, as CSV text (a title line, a blank line, a Template,Count header row and one row per template). It is served with a text/html Content-Type. The counts are the ones precomputed during the periodic inventory refresh.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | Yes | CertSecure name of the Certificate Authority to report on. This is the Name returned by GET /ca, not the CA's subject DN. The match is case-insensitive. A name that is not a registered CA is refused with a 400. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/count_by_template?ca=<ca>" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | CSV text, one row per template. |
| 400 | The ca parameter is missing, empty or does not name a registered Certificate Authority. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | The CA has no precomputed template counts yet, or another unexpected server-side failure; the body carries the exception text. |
GET /reports/download
Streams the CSV file produced by a POST /reports job as an attachment. The job must be complete (see GET /reports/status); otherwise 409. The file name is in the Content-Disposition header. A job that is unknown, or that belongs to another user, is reported as 404; a global Admin can download any job. Files are kept for 24 hours.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
jobId |
Query | string | Yes | Identifier of the export job: the job_id returned by POST /reports. A job that does not exist, or that another user started, gives a 404. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/download?jobId=<jobId>" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | The CSV file, as an attachment. |
| 400 | jobId is missing or empty. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 404 | No such job (or it belongs to another user), or the report file has already been removed. |
| 409 | The job has not finished successfully yet; status and progress say where it is. |
GET /reports/expired_last_7_days
Certificates whose status is expired and whose expiry date falls in the last 7 days, as CSV text (the header row, then one row per certificate; no title line), served with a text/html Content-Type. With ca the columns are that CA's configured report columns; without it, all certificate fields across every CA. When nothing matches (including for an unknown CA) the body is empty.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | CertSecure name of the Certificate Authority to report on (the Name returned by GET /ca). Omit to cover every CA. The name is matched exactly and is not validated: a name that matches no CA gives an empty report, not an error. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/expired_last_7_days" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | CSV text, one row per certificate; empty when none expired in the window. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | An unexpected server-side failure; message carries the exception text. |
GET /reports/key_algorithms_report
Returns the active certificates whose key is classified weak and/or strong as plain CSV text, under a title line (Key Strength Data for <CA> or Global Key Strength Data) and a blank line. Classification uses the RSA/ECC thresholds of the key-length configuration. At least one of weak and strong must be present (any value, including an empty one, counts as present); the operation answers 400 when both are absent. The *content* of a present parameter selects the output: a non-empty value includes that group, an empty value includes nothing, so use a non-empty value such as true. When both groups are requested the weak rows are written first and each group repeats its own header row. With ca the columns are Public Key Algorithm, Key Length and that CA's configured report properties; without it, every CA is covered and the columns are whatever the certificate documents carry. The body is CSV even though the response is served as text/html.
Note: Pass weak or strong to select the key type; otherwise the request returns 400 with the error "Type of key required".
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | CertSecure name of the Certificate Authority to report on: the Name returned by GET /ca, not the CA's subject DN. Optional - omit it to cover every CA. The literal all is NOT special here: a name that does not exist makes the handler fail with 500. |
strong |
Query | string | No | Include the certificates classified as strong. Any non-empty value switches the group on. At least one of strong and weak must be supplied. |
weak |
Query | string | No | Include the certificates classified as weak. Any non-empty value switches the group on. At least one of strong and weak must be supplied. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/key_algorithms_report" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | CSV text (served as text/html): a title line, a blank line, then one header row and one row per matching certificate for each requested group. |
| 400 | Neither weak nor strong was supplied. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | The report could not be produced, for example because ca names a CA that does not exist. |
GET /reports/key_length
Count of certificates per public-key algorithm and key length for one CA, as CSV text (a title line, a blank line, an Algorithm,Key Length,Count header row and one row per algorithm and length). It is served with a text/html Content-Type. The counts are the ones precomputed during the periodic inventory refresh.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | Yes | CertSecure name of the Certificate Authority to report on. This is the Name returned by GET /ca, not the CA's subject DN. The match is case-insensitive. A name that is not a registered CA is refused with a 400. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/key_length?ca=<ca>" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | CSV text, one row per algorithm and key length. |
| 400 | The ca parameter is missing, empty or does not name a registered Certificate Authority. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | The CA has no precomputed key-length data yet, or another unexpected server-side failure; the body carries the exception text. |
GET /reports/key_strength_analytics
How many certificates have strong versus weak keys, using the thresholds from GET /reports/config_keylength. Post-quantum algorithms always count as strong. Covers the listed CAs, or every configured CA when ca is omitted. When none of the CAs has precomputed key-length data the answer is zero for both counts (and no references) rather than an error.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | Comma-separated CertSecure names of the CAs to include (the Name values returned by GET /ca). Omit or leave empty to include every configured CA. Names that match no CA contribute nothing. A value with no usable name, such as a lone comma, fails with a 500. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/key_strength_analytics" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | Certificate counts by key strength. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | The ca value contains no usable CA name, or another unexpected server-side failure; the body carries the exception text. |
Example Response
{
"strong": 46,
"weak": 3,
"references": {
"classical": {
"nist_sp_800_131A": "https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf",
"keylength_com": "https://www.keylength.com/en/4/"
},
"post_quantum": {
"fips_203_ml_kem": "https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf",
"fips_204_ml_dsa": "https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf",
"fips_205_slh_dsa": "https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.205.pdf"
}
}
}
GET /reports/properties
Returns the columns the CA's reports currently show and the full list that can be chosen from.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | Yes | CertSecure name of the Certificate Authority to report on. This is the Name returned by GET /ca, not the CA's subject DN. The match is case-insensitive. A name that is not a registered CA is refused with a 400. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/properties?ca=<ca>" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | GET: the shown and available columns. |
| 400 | The ca parameter is missing, empty or does not name a registered Certificate Authority, or the CA has no inventory data yet (its first inventory refresh has not run). |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
Example Response
{
"Active": [
"Common Name",
"Serial Number",
"Certificate Expiration Date"
],
"Available": [
"Common Name",
"Serial Number",
"Certificate Effective Date",
"Certificate Expiration Date",
"Certificate Template"
]
}
POST /reports/properties
Replaces the set of columns shown in the CA's reports with the ones listed in properties. Every name must be one of the CA's Available columns; Serial Number is added if missing and a name given more than once is kept once. An empty properties value leaves only Serial Number.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | Yes | CertSecure name of the Certificate Authority to report on. This is the Name returned by GET /ca, not the CA's subject DN. The match is case-insensitive. A name that is not a registered CA is refused with a 400. |
properties |
Query | string | Yes | Comma-separated names of the columns to show, each one of the CA's Available columns from GET /reports/properties (a name is matched exactly, after trimming spaces). Blank entries are ignored. The parameter must be present, but may be empty. |
Example Request
curl -X POST "https://<certsecure-backend-url>/reports/properties?ca=<ca>&properties=<properties>" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | The columns were replaced. |
| 400 | The ca parameter is missing or not a registered CA, the CA has no inventory data yet, properties was not sent, or it names a column that is not available. Always a JSON {"Error": ...}; nothing is changed. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | The columns could not be saved. |
Example Response
{
"Success": "Properties has been updated"
}
GET /reports/risk_profile_count
Returns the number of active certificates at each risk level, read from the precomputed report cache (refreshed by the background job, so it is not real time). The estate-wide totals are returned unless ca is given, in which case only that CA's certificates are counted (every count is zero for a CA with no active certificates). If the cache has not been built yet the operation answers 202 with an empty object; if the cache cannot be read it answers 200 with every count at zero.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | CertSecure name of the Certificate Authority to act against. This is the Name returned by GET /ca, not the CA's subject DN. Callers only ever see CAs their department is entitled to. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/risk_profile_count" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | Certificates per risk level. |
| 202 | The risk profile has not been computed yet; the body is an empty object. Retry later. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
Example Response
{
"Secure": 12,
"Low Risk": 30,
"High Risk": 403079,
"Severe Risk": 1
}
GET /reports/risk_profile_report
Returns one page of the per-certificate risk evaluation (the cached RiskReport), worst certificates first by default, together with the column headers the caller should display. Pagination always applies: page defaults to 1 and per_page to 50 and is clamped to 1-500; a page beyond the last one falls back to page 1. Unlike the certificate report, pagination does not depend on any other parameter. This operation never answers with an error status of its own: any internal failure (including a non-numeric page/per_page, or a sort the database cannot order by, such as an empty one) is answered with 200 and an empty object {}, so a client must treat a body without data as "no result". filter and key_word only take effect together, and filter must name one of risk, key_length, signing_algorithm, san_attributes, aia, cdp, key_usages, enhanced_key_usages, certificate_policies or duration; any other field is silently ignored. The match is an exact comparison with key_word. Only risk holds a plain level string (Secure, Low Risk, High Risk, Severe Risk); the other fields are stored as {status, description} objects, so a plain string never matches them.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | CertSecure name of the Certificate Authority whose certificates to return: the Name returned by GET /ca. Optional - omit it, or send all, for every CA. |
filter |
Query | string | No | Name of the stored field to filter on (see the operation description for the accepted names). Only applied together with key_word; an unrecognised name is ignored, not rejected. |
key_word |
Query | string | No | Exact value the field named by filter must equal, for example High Risk when filter=risk. Surrounding whitespace is trimmed. Only applied together with filter. |
order |
Query | string | No | Sort direction, case-insensitive. descending or desc sorts descending; any other value, or none, sorts ascending (default ascending). |
page |
Query | integer | No | One-based page number, default 1; values below 1 are treated as 1 and a page past the last one falls back to 1. A non-numeric value makes the operation answer 200 with an empty object. |
per_page |
Query | integer | No | Rows per page, default 50; values are clamped to the range 1-500. A non-numeric value makes the operation answer 200 with an empty object. |
sort |
Query | string | No | Name of the stored field to order by (lower-cased before use), default risk_weight, which is worst-risk-first for descending order. Rows with equal values are ordered by risk_weight. An empty value makes the operation answer 200 with an empty object. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/risk_profile_report" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | One page of risk-evaluated certificates, or an empty object {} when the request could not be served. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
Example Response
{
"headers": {
"serial_number": "Serial Number",
"risk": "Risk Level",
"key_length": "Key Length",
"signing_algorithm": "Signing Algorithm",
"duration": "Duration Risk"
},
"data": [
{
"serial_number": "4A1B2C3D4E5F",
"risk": "High Risk",
"key_length": {
"status": "Low Risk",
"description": "RSA 2048-bit meets current minimum but approaches 2030 sunset."
},
"signing_algorithm": {
"status": "Secure",
"description": "SHA-256/384/512 meets current standards."
},
"duration": {
"status": "High Risk",
"description": "Validity 399-1825 days exceeds CAB Forum limits for TLS certs."
}
}
],
"total": 1,
"page": 1,
"per_page": 25,
"max_pages": 1
}
GET /reports/risk_report_xlsx
Streams the per-certificate risk evaluation as an .xlsx workbook (sheet Certs, one row per certificate, risk cells colour-coded), served as an attachment named cert_report.xlsx. All rows are included - there is no paging. Optionally limited to one CA.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | CertSecure name of the Certificate Authority to export: the Name returned by GET /ca. Optional - omit it, or send all, to export every CA. A name with no certificates yields a workbook with only the header row. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/risk_report_xlsx" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | The Excel workbook, as an attachment. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | The workbook could not be produced. |
GET /reports/self_signed_report
Self-signed certificates (subject equals issuer) among the third-party CA certificates recorded in the enrollment database, as CSV text (a title line, a blank line, the header row, then one row per certificate), ordered by CA and served with a text/html Content-Type. The optional status parameter narrows it to active (active) or not-active (other) certificates. When none is found only the title line and a blank line are returned.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
status |
Query | string | No | Optional. active reports only active certificates; other reports every certificate that is not active. Omit it for all of them. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/self_signed_report" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | CSV text, one row per self-signed certificate. |
| 400 | status was given and is neither active nor other. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | Any failure while building the report. |
GET /reports/signing_algorithm_report
Certificates of one CA (or of every CA) with their signing algorithm, as CSV text (a title line, a blank line, the header row, then one row per certificate), served with a text/html Content-Type. With ca the columns are that CA's configured report columns plus Signing Algorithm; without it, all certificate fields. algorithm narrows the list to certificates signed with exactly that algorithm. When nothing matches the answer is a 404.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | CertSecure name of the Certificate Authority to report on (the Name returned by GET /ca). Omit to cover every configured CA. The name is not validated: one that is not a registered CA makes the request fail with a 500. |
algorithm |
Query | string | No | Only certificates whose Signing Algorithm value is exactly this string (case-sensitive), for example sha256WithRSAEncryption. Omit or leave empty for all algorithms. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/signing_algorithm_report" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | CSV text, one row per matching certificate. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 404 | No certificate matches the filters. |
| 500 | Any failure while building the report, including a ca that is not a registered CA. |
GET /reports/status
Progress of a CSV export started with POST /reports. Poll until status is complete (then fetch GET /reports/download) or error (message says why). status moves pending, in_progress, then complete or error. A job that is unknown, or that belongs to another user, is reported as 404 so that job ids cannot be probed; a global Admin can read any job.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
jobId |
Query | string | Yes | Identifier of the export job: the job_id returned by POST /reports. A job that does not exist, or that another user started, gives a 404. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/status?jobId=<jobId>" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | The current state of the job. |
| 400 | jobId is missing or empty. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 404 | No such job, or the job belongs to another user. |
Example Response
{
"job_id": "3f2b8c1e-7a4d-4e59-9b1a-2c6d8e0f1a7b",
"ca": "Issuing CA 1",
"type": "active",
"status": "error",
"progress": "Report generation failed",
"progress_percent": 0,
"message": "An internal error occurred while generating the report. Please contact your administrator.",
"created_at": "2026-10-12 09:15:02",
"completed_at": null
}
GET /reports/wildcard_report
Certificates whose Common Name contains *, as CSV text (a title line, a blank line, the header row, then one row per certificate), served with a text/html Content-Type. Active certificates are always included; revoked and expired ones are added by the flags below. With ca the columns are that CA's configured report columns; without it the report spans every CA and has only the Common Name column. When no certificate matches, only the title line and a blank line are returned.
Request Parameters
| Name | Located In | Type | Required | Description |
|---|---|---|---|---|
ca |
Query | string | No | CertSecure name of the Certificate Authority to report on (the Name returned by GET /ca). Omit to cover every configured CA. The name is not validated: one that is not a registered CA makes the request fail with a 500. |
template |
Query | string | No | Only certificates issued from this certificate template. Exact match against the certificate's Certificate Template value. Omit for all templates. |
revoked |
Query | string | No | Presence flag: any non-empty value (even false) also includes revoked certificates; omit it or send an empty value to leave them out. Same as Revoked. |
Revoked |
Query | string | No | Presence flag: any non-empty value (even false) also includes revoked certificates. Same as revoked. |
expired |
Query | string | No | Presence flag: any non-empty value (even false) also includes expired certificates; omit it or send an empty value to leave them out. Same as Expired. |
Expired |
Query | string | No | Presence flag: any non-empty value (even false) also includes expired certificates. Same as expired. |
Example Request
curl -X GET "https://<certsecure-backend-url>/reports/wildcard_report" \
-H "Authorization: Bearer <token>"
Responses
| Status Code | Description |
|---|---|
| 200 | CSV text, one row per wildcard certificate. |
| 401 | Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists. |
| 500 | Any failure while building the report, including a ca that is not a registered CA. |