CertSecure Documentation
  • Overview
    • About CertSecure Manager
    • Documentation Guide
  • Reference Guide
    • Header Bar
      • CertSecure Documentation
      • Swagger API
      • Profile Section
      • Search
    • Dashboard
      • Key Performance Indicators
      • Expiring Certificates
      • CA metrics
      • Key Strength
      • Signing Algorithm
      • Certificate Risk Report Profile
      • PKI Posture Management
      • NDES Health Information
    • AI Assistant
      • Chat
      • Configuration
      • Usage Report
    • Inventory
      • Overview
        • Overall
        • CertSecure
      • Template Management
        • Switch Templates
        • Exclusion List
        • Alert Templates
        • Certificate Templates
      • Template Categories
    • Discovery
      • Inventory
      • Scan Config
      • Cloud Config
      • Vault Config
      • Discovery Analytics
      • Scan Details
      • Discovery Ingestion
    • Reports
    • Utilities
      • ACME
      • Tasks
      • Integrations
        • Renewal Manager
        • Load Balancers
        • Discovery Agents
        • CLI Tool
        • Key Management
        • SEIM Tools
        • DevOps Tools
        • Ansible Automation Platform
      • NDES
      • Azure Key Vault
      • API Tokens
    • Enrollment
      • Certificate Request
      • Generate CSR
      • Enroll CSR
      • Generate Certificate
      • Import Certificate
      • Bulk Certificate Generation
      • Manage Policies
      • Organization Details
    • Administration
      • Users
      • Roles and permission
      • Certificate Authorities
      • Departments
    • Miscellaneous
      • Logging
      • Service Setup
        • Zoom
        • Zendesk
      • Settings
        • Configure Realms
        • Schedule Alerts
        • Metrics
        • Web Branding
        • About License
  • Setup & Architecture
    • Identity and Access Control
    • Architecture
    • Installation
      • Pre-requisites
      • Windows
      • Linux
      • Docker
    • Upgrade
      • Windows
      • Docker
  • Release Notes
    • Releases for 2026
      • v3.4.0
      • v3.3.1
      • v3.3.0
    • Releases for 2025
      • v3.2.0
      • v3.1.0
    • Releases for 2024
      • v3.0.0
  • Workflow
    • Approval Workflow
  • API Reference
    • Getting Started
    • Authorizing Requests
    • Securing API Access
    • Request and Response Conventions
    • Endpoint Reference
      • Health
      • API Token Management
      • CA Management
      • Templates
      • Certificate Enrollment
      • Inventory
      • Certificate Discovery
      • Tasks
      • Watcher Groups
      • Alerts
      • Reports
      • Logs
      • Monitoring
      • Scheduling
      • SMTP
      • ACME
      • Azure Key Vault
      • Google Cloud (GCP)
      • HashiCorp Vault
      • EJBCA
      • ServiceNow
  • Integration Guide
    • Renewal Manager
      • Workflow
      • Setup
      • Troubleshooting
      • IIS
      • Apache
      • Tomcat
      • Nginx
      • MSSQL
      • MongoDB
      • Oracle
      • Cloudflare
      • AudioCodes
      • Cisco ISE
      • Palo Alto PAN-OS
      • Cisco ACI
    • Load Balancer
      • F5
        • Workflow
        • Setup
        • Onboarding
        • UI Guide
        • Troubleshooting
      • NetScaler
        • Workflow
        • Setup
        • UI Guide
        • Troubleshooting
    • Certificate Authorities
      • ACME CAs
      • AWS
      • DigiCert Connector
      • EJBCA
      • GlobalSign
      • GoDaddy
      • HashiCorp Vault PKI
      • Microsoft AD CS
      • Sectigo
      • Sectigo-PS
    • Ansible Automation Platform
    • Azure Key Vault
  • Discovery Agent Setup Guide

Certificate Enrollment

The Certificate Enrollment endpoints issue certificates from a CSR or from subject details, generate CSRs, renew and revoke certificates (individually or in bulk), download certificates and PFX files, import third-party certificates and trusted roots, and manage enrollment policies and ownership.

For the corresponding user interface, refer to the Enrollment section.

Endpoints

Method Endpoint Description
GET /enrollment List enrollment records.
GET /enrollment/alert_templates List the templates that raise expiry alerts per CA.
POST /enrollment/alert_templates Update the templates that raise expiry alerts of the named CAs.
PUT /enrollment/attach-cert Attach a certificate to a manually entered record.
GET /enrollment/audit_trail Get the audit trail of a certificate or of a whole CA.
POST /enrollment/bulk/generate Generate certificates in bulk from an uploaded CSV.
POST /enrollment/bulk/upload Upload the CSV for a bulk certificate generation.
POST /enrollment/bulk_ownership_transfer Transfer ownership of several certificates.
POST /enrollment/bulk_renewal Renew many certificates in bulk.
POST /enrollment/bulk_revoke Revoke several certificates in one request.
GET /enrollment/ca_cert_count Count active certificates by certificate authority.
GET /enrollment/cert_status Look up the revocation status of a certificate by serial number.
GET /enrollment/columns Get the enrollment table columns.
POST /enrollment/columns Set the enrollment table columns.
POST /enrollment/csr_details Decode a certificate signing request.
GET /enrollment/csr_generated_count Number of CSRs generated per four-week period.
DELETE /enrollment/delete-third-party-cert Delete a third-party certificate record.
POST /enrollment/delete-trusted-root Remove a certificate from the trust store.
GET /enrollment/download Download an issued certificate.
GET /enrollment/download_cert Download the certificate of an enrollment record as PEM text.
POST /enrollment/download_cert_enroll_pfx Download a certificate and its private key as a PFX (PKCS#12) file.
POST /enrollment/download_pfx Download a certificate and its private key as a password-protected PKCS#12 (PFX) file.
POST /enrollment/download_zip_key Download a certificate, its chain and its password-protected private key as a zip archive.
POST /enrollment/enroll-acme-ca-cert Register a certificate obtained over ACME from a public CA.
POST /enrollment/enroll_csr Request a certificate from a CSR.
POST /enrollment/enroll_on_behalf Request a certificate on behalf of a CMP client (no CSR).
GET /enrollment/enrolled_csr_details Get the details of an enrollment record.
GET /enrollment/enrollment_inventory_count Count enrollment records by status.
GET /enrollment/expiry_count Count certificates by expiry bucket.
POST /enrollment/generate_acme_cert Request a certificate from an ACME CA.
GET /enrollment/generate_aws_acm_cert List the options for an AWS ACM certificate request.
POST /enrollment/generate_aws_acm_cert Request a public certificate from AWS Certificate Manager.
POST /enrollment/generate_cert Request a certificate with a server-generated key.
POST /enrollment/generate_csr Generate a key pair and CSR.
GET /enrollment/generate_password Generate a password that satisfies the policy.
POST /enrollment/hold_cert Place one certificate on hold.
GET /enrollment/ignore_cert List ignored certificates.
POST /enrollment/ignore_cert Ignore a certificate.
GET /enrollment/ignore_templates List the ignored templates per CA.
POST /enrollment/ignore_templates Update the ignored templates of the named CAs.
POST /enrollment/import-third-party-cert Import a third-party certificate from PEM.
POST /enrollment/import-third-party-cert-manual Record a third-party certificate from typed-in details.
POST /enrollment/import-trusted-root Add a certificate to the trust store.
GET /enrollment/key_length_count Count active certificates by key length.
GET /enrollment/organization_details Get organization details.
POST /enrollment/organization_details Set organization details.
GET /enrollment/organization_info Organization information stored for a CA.
GET /enrollment/policy Get the enrollment policy.
POST /enrollment/policy Update the enrollment policy.
POST /enrollment/renew_aws_acm_cert Renew an AWS ACM certificate.
POST /enrollment/renew_cert Renew a certificate.
POST /enrollment/renew_csr Renew a certificate with your own CSR.
POST /enrollment/revoke_cert Revoke one certificate.
POST /enrollment/switch_ca Re-issue certificates from a different CA.
GET /enrollment/templates Templates the caller can enroll against, per CA.
POST /enrollment/transfer-third-party-cert Move a certificate record to another third-party container.
GET /enrollment/transfer_ownership Transfer ownership of a certificate.
POST /enrollment/trust-certificate-chain Trust the root of a certificate's chain.
GET /enrollment/trust-history This certificate's trust chain over time.
GET /enrollment/trusted-roots List trusted root certificates.
POST /enrollment/unhold_cert Remove the hold on one certificate.
GET /enrollment/unknown-certs List third-party certificates as CSV text.
POST /enrollment/update_email Replace the notification e-mail addresses of an enrollment record.
POST /enrollment/upload-chain Upload a certificate chain for a certificate.
GET /enrollment/user Get the status of the caller's user certificate.
POST /enrollment/user Request a user certificate for the caller.
POST /enrollment/user/download-cert Download the self-service user certificate.
GET /enrollment/user/manage Get the self-service enrollment configuration.
POST /enrollment/user/manage Set the self-service enrollment configuration.
GET /enrollment/view-trust-chain View the certificate chain of a certificate.
GET /enrollment

Certificate requests and their state, as distinct from the issued-certificate inventory under /inventory. type chooses the lifecycle state to list (default active); every other query parameter narrows the result. Most filters accept a comma-separated list and match any of the values. The caller only sees records they own or are named on (EmailID), unless view_all_user_certs=true is sent and they hold View all user certificates; for type=requested every record awaiting action is considered. Only CAs the caller's department may use are searched. type=expiring additionally needs day; type=keylength additionally needs a single integer keyLength. Both of those force Status to active. Besides the parameters listed, a cf_<custom field name> query parameter filters on that custom field (comma-separated values, case-insensitive substring match), and the custom fields defined in the product are added to every returned certificate.

Note: Call this endpoint without a trailing slash (/enrollment). The Swagger API lists it as /enrollment/.

Request Parameters

Name Located In Type Required Description
type Query string No Lifecycle state of the records to list. Case-insensitive, defaults to active when omitted. It is matched against the record Status, so any status used by enrollment records works, e.g. active, expired, revoked, pending, requested, approved, denied, failed. Two values change behaviour: expiring (needs day) and keylength (needs keyLength). The handler does not reject other values, it simply returns an empty list.
certCategory Query string No Which kind of certificate to list. A value containing thirdparty selects imported third-party certificates, one containing certsecure selects certificates issued through CertSecure; both may be given in one string. Anything else (or empty) selects both.
day Query string No Expiry window in days, matched exactly against the record's expiresIn value. Required (400 otherwise) when type=expiring; ignored otherwise.
expiration_date_from Query string No Only certificates expiring on or after this date, YYYY-MM-DD. Must not be later than expiration_date_to. Empty means no lower bound.
expiration_date_to Query string No Only certificates expiring on or before this date (inclusive of the whole day), YYYY-MM-DD. Empty means no upper bound.
keyLength Query string No Public key size in bits. Comma-separated list of integers (2048,4096) for filtering any listing; with type=keylength it is required and must be a single integer.
san Query string No Substring of the subject alternative names to match, case-insensitive.
status Query string No Accepted for compatibility but has no effect: the Status of the result is always taken from type. A value made up only of commas and spaces is rejected.
tags Query string No Only certificates carrying all of these tags. Comma-separated list (production,external); send the parameter once.
template Query string No Certificate template name. Comma-separated list; matches any of them as a case-insensitive substring.
view_all_user_certs Query boolean No Send true to list every user's records rather than only the caller's. Silently ignored (the list stays limited to the caller) unless the caller holds the View all user certificates permission. false (or leaving it out) keeps the list limited to the caller. The value must be true or false in any letter case; anything else (null, 0, yes, ...) is a 400. (Until 2026-10-26 any value other than an empty one, false included, listed everyone's records for a caller who holds the permission.)
watchers Query string No Only certificates whose watcher list (EmailID) contains all of these e-mail addresses. Comma-separated list; exact, case-insensitive match.
common_name Query string No Common name filter. Comma-separated list; case-insensitive substring match on any value.
organization Query string No Organization (O) filter. Comma-separated list; case-insensitive substring match.
organization_unit Query string No Organizational unit (OU) filter. Comma-separated list; case-insensitive substring match.
country Query string No Country code filter. Comma-separated list; case-insensitive substring match.
state Query string No State or province filter. Comma-separated list; case-insensitive substring match.
city Query string No City or locality filter. Comma-separated list; case-insensitive substring match.
owner Query string No Certificate owner e-mail filter. Comma-separated list; case-insensitive substring match.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 Matching enrollment records, with the CA names and template names that occur in them.
400 A filter failed validation.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the View Enrollment Database permission.

Example Response

{
  "CANames": [
    "Issuing CA 1"
  ],
  "TemplateNames": [
    "WebServer"
  ],
  "Certificates": [
    {
      "EnrollmentID": 1042,
      "SerialNumber": "4A1B2C3D4E5F",
      "CertificateAuthority": "Issuing CA 1",
      "Template": "WebServer",
      "Status": "active",
      "EmailID": [
        "[email protected]"
      ],
      "keyLength": 2048,
      "commonName": "www.example.com",
      "san": "www.example.com, example.com",
      "ExpiresOn": "12/31/2026 11:59 PM",
      "pfxExport": "False",
      "certAvailable": true,
      "owner": "[email protected]",
      "thirdPartyCert": false,
      "tags": [
        "production"
      ]
    }
  ]
}
GET /enrollment/alert_templates

Returns an object keyed by CA name whose values are the alerting template names. When nothing has ever been saved, every registered CA maps to an empty array. Open to any authenticated caller.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/alert_templates" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 Alerting template names per CA.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 Any unexpected failure while reading the setting.

Example Response

{
  "Issuing CA 1": [
    "WebServer"
  ],
  "Issuing CA 2": []
}
POST /enrollment/alert_templates

Restricted to global administrators and Department PKIAdmins. Responds with the lists of the CAs the request named, as stored, which can be shorter than the ones sent because unknown templates are dropped. A body that is missing, is not a JSON object, or whose alertTemplates is not an object of CA names to arrays of template names is a 400; an unexpected failure is a 500.

Request Body (application/json)

Field Type Required Description
alertTemplates object Yes Object keyed by CertSecure CA name; each value is the array of template names that should raise expiry alerts for that CA. Each CA named has its list replaced by the one sent, and a CA that is not named keeps its list: to stop alerting on every template of a CA, send an empty array for it. An empty object changes nothing. Template names are trimmed, and a name the CA does not publish is silently skipped. Every CA named must be registered (400 otherwise), and a Department PKIAdmin may only name CAs of their own department (403).

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/alert_templates" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"alertTemplates":{"Issuing CA 1":["WebServer"]}}'

Responses

Status Code Description
200 The alerting templates as stored.
400 The body is missing or is not a JSON object, it names no alertTemplates, alertTemplates is not an object of CA names to arrays of template names, or a CA is not registered.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller is neither a global administrator nor a Department PKIAdmin (plain-text body), or a Department PKIAdmin named a CA outside their department (JSON body).
500 Any unexpected failure while reading or saving the setting.

Example Response

{
  "Templates Configured for Alerts": {
    "Issuing CA 1": [
      "WebServer"
    ]
  }
}
PUT /enrollment/attach-cert

Completes a record created by POST /enrollment/import-third-party-cert-manual by attaching the real certificate PEM to it. Requires the Import Certificate permission and, in addition, being a global administrator, a Department PKIAdmin for the record's CA, or the record's owner. Only a record that has no certificate yet can be attached to (otherwise 409), and the PEM's serial number must match the serial number that was typed in (otherwise 409). Fields parsed from the certificate then replace the typed-in ones.

Request Body (application/json)

Field Type Required Description
cert_chain string No PEM-encoded issuing chain for the certificate, root last.
cert_data string Yes PEM-encoded certificate body.
eid integer or string Yes Enrollment ID of the manually entered record to attach the certificate to. Must be an integer; a numeric string is also accepted.
watchers array of string No Email addresses notified about this certificate's expiry and lifecycle events, in addition to the owner. When omitted or empty, the watchers already on the record are kept.

Example Request

curl -X PUT "https://<certsecure-backend-url>/enrollment/attach-cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"cert_chain":"-----BEGIN CERTIFICATE-----\nMIIDgzCCAmugAwIBAgIGShssPU5fMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYT\nAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGRGFsbGFzMRUwEwYDVQQKDAxF\neGFtcGxlIENvcnAxCzAJBgNVBAsMAklUMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5j\nb20wHhcNMjYwMTAxMDAwMDAwWhcNNDYwMTAxMDAwMDAwWjBsMQswCQYDVQQGEwJV\nUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkRhbGxhczEVMBMGA1UECgwMRXhh\nbXBsZSBDb3JwMQswCQYDVQQLDAJJVDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29t\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4KGdPq0SDQaATi+On/dF\nTH+mxg8a6grfrTpOk5FwE33zG+ow0s5ggulvCOuWSZ0mNhMlVPXIdcD09hO+kPXY\nNxh7TxQdJA5CQLS8Luo0NkdeA6VUPx0b1F5AA/ooaAPs7WXSiLrDCIrmrVg0uWJF\nUIH491cHZygNvIOLsbFo9VxKJZTql0YLlZZGV3JECZiPXyIqLvZFlCMdFzcLtoZA\nVpLJKOM7W31kum5uoZYwd+g7KFQ48vimcj+04mZhE4rhpx5iOUz6EMfad1Ttm8i2\ncpLVxBhLvUN+PO/RXAjmtS7KJ2Azv9FY0eRlahXWHj4X9Za1CUY3kvYA+4vz3JVO\ntwIDAQABoyswKTAnBgNVHREEIDAegg93d3cuZXhhbXBsZS5jb22CC2V4YW1wbGUu\nY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAs+vreNbnsbORRn4Xlqkx3YgFIVUr9ia+s\nE+KNkFtZ6VqwJ4zBCghYUXAcvGqb/0Ru1jr1hXFW1C4WgeXoGhWm+l6FEgLaHA0Z\nh9JcUZ+zkhLnzHtsz4EBnqmDQ93YjFbQMFkPFxrO98RZsbgcGovF4ohrxRypcYbS\nwcbPRP1NWcF8ljJlbLCTM4pEGz4wfaioZHRed5Po0EcOh5O0JLkqxrhlW6Y9enNE\n5NBywAIeg8Dh50rNtoo9LlvpPboNdr7+Kit+xmzTOoZK2Ky9SjuVm7vOIQ17/02y\n9pPQRD5Uz8jRif2CRgIrm9KuqGsR6C+LM6cvL3CKn4r/zJ9Dk2Uy\n-----END CERTIFICATE-----\n","cert_data":"-----BEGIN CERTIFICATE-----\nMIIDgzCCAmugAwIBAgIGShssPU5fMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYT\nAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGRGFsbGFzMRUwEwYDVQQKDAxF\neGFtcGxlIENvcnAxCzAJBgNVBAsMAklUMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5j\nb20wHhcNMjYwMTAxMDAwMDAwWhcNNDYwMTAxMDAwMDAwWjBsMQswCQYDVQQGEwJV\nUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkRhbGxhczEVMBMGA1UECgwMRXhh\nbXBsZSBDb3JwMQswCQYDVQQLDAJJVDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29t\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4KGdPq0SDQaATi+On/dF\nTH+mxg8a6grfrTpOk5FwE33zG+ow0s5ggulvCOuWSZ0mNhMlVPXIdcD09hO+kPXY\nNxh7TxQdJA5CQLS8Luo0NkdeA6VUPx0b1F5AA/ooaAPs7WXSiLrDCIrmrVg0uWJF\nUIH491cHZygNvIOLsbFo9VxKJZTql0YLlZZGV3JECZiPXyIqLvZFlCMdFzcLtoZA\nVpLJKOM7W31kum5uoZYwd+g7KFQ48vimcj+04mZhE4rhpx5iOUz6EMfad1Ttm8i2\ncpLVxBhLvUN+PO/RXAjmtS7KJ2Azv9FY0eRlahXWHj4X9Za1CUY3kvYA+4vz3JVO\ntwIDAQABoyswKTAnBgNVHREEIDAegg93d3cuZXhhbXBsZS5jb22CC2V4YW1wbGUu\nY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAs+vreNbnsbORRn4Xlqkx3YgFIVUr9ia+s\nE+KNkFtZ6VqwJ4zBCghYUXAcvGqb/0Ru1jr1hXFW1C4WgeXoGhWm+l6FEgLaHA0Z\nh9JcUZ+zkhLnzHtsz4EBnqmDQ93YjFbQMFkPFxrO98RZsbgcGovF4ohrxRypcYbS\nwcbPRP1NWcF8ljJlbLCTM4pEGz4wfaioZHRed5Po0EcOh5O0JLkqxrhlW6Y9enNE\n5NBywAIeg8Dh50rNtoo9LlvpPboNdr7+Kit+xmzTOoZK2Ky9SjuVm7vOIQ17/02y\n9pPQRD5Uz8jRif2CRgIrm9KuqGsR6C+LM6cvL3CKn4r/zJ9Dk2Uy\n-----END CERTIFICATE-----\n","eid":1042,"watchers":["[email protected]"]}'

Responses

Status Code Description
200 The certificate was attached.
400 A key is missing or blank, eid is not an integer, or cert_data could not be parsed as a PEM certificate.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller lacks the Import Certificate permission, or is not allowed to modify this record.
404 No enrollment record has this Enrollment ID.
409 The record already has a certificate attached, or the certificate's serial number differs from the one recorded.
500 The attach failed unexpectedly.

Example Response

{
  "Success": "Certificate attached",
  "eid": 1042
}
GET /enrollment/audit_trail

Who owns, requested, approved, denied and revoked certificates, in one of two modes. One certificate. Identify it by eid (enrollment ID) or by serialNum together with ca; eid wins when both are sent, and ca is then ignored. A certificate with no recorded events yet answers 200 with empty fields. A caller who is the owner or a listed watcher of the enrollment record may read it; anyone else needs View all user certificates. When no enrollment record is found for the identifier, that permission is required and the identifier must also exist in the audit trail (404 otherwise). A whole CA. Send ca alone. Answers every audit-trail record of that CA, ordered by serial number, as {data, total}; with both count and page it answers that page as {data, total, page, count}. Names and e-mail addresses are returned unredacted, so this mode needs Manage Certification Authorities. Only certificates something has been recorded for appear. To download the same data as CSV use POST /reports/audit_trail.

Request Parameters

Name Located In Type Required Description
eid Query integer No Enrollment ID of the certificate. Must be an integer (400 otherwise). Selects the one-certificate mode and takes precedence over serialNum and ca.
serialNum Query string No Certificate serial number, used when eid is absent; ca is then required.
ca Query string No CertSecure name of the Certificate Authority. With serialNum, the CA of that certificate (required, 400 otherwise). Alone, the CA whose whole audit trail to list; it must be a registered CA (400 otherwise). Ignored when eid is sent.
count Query integer No Whole-CA mode only: rows per page, at least 1 and capped at 500. Pagination applies only when page is sent too; sending one without the other, or a non-integer, is a 400.
page Query integer No Whole-CA mode only: 1-based page number. Pagination applies only when count is sent too.
search Query string No Whole-CA mode only: case-insensitive "contains" match on the serial number, common name, owner, requesters, approvers, deniers or revoker. At least 3 characters once trimmed (400 otherwise); blank means no search.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/audit_trail" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 One certificate: the audit trail, with every field present and empty when nothing was recorded. A whole CA: data holds one such record per certificate and total the number of matching records; page and count are echoed when paginating.
400 No identifier was sent, eid is not an integer, serialNum came without ca, ca is not a registered CA, or count/page/search are invalid.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 One certificate: the caller is not its owner or a watcher and lacks View all user certificates. A whole CA: the caller lacks Manage Certification Authorities.
404 One certificate: no audit trail exists for the identifier.
500 The lookup failed.

Example Response

{
  "enrollmentID": 1042,
  "serialNumber": "4A1B2C3D4E5F",
  "caName": "Issuing CA 1",
  "commonName": "www.example.com",
  "owner": "[email protected]",
  "requesters": [
    "[email protected]"
  ],
  "approvers": [
    "[email protected]"
  ],
  "deniers": [],
  "revoker": ""
}
POST /enrollment/bulk/generate

Second step of a bulk generation (the first is POST /enrollment/bulk/upload). The request does not carry certificate values: it names the previously uploaded file and maps each certificate field to the CSV column header that holds it. One certificate request, with a private key, is queued for every row. Every row must name the same CA, which is read from the column mapped by ca. order_validity and organization_id are only needed (and only checked) when that CA is a DigiCert one. A cell that is empty in a mandatory column is recorded as a failure for that row without stopping the others. The call answers 202 once every row has been processed, whether or not each one succeeded: the parent task taskID carries the totals and the per-row outcome (its status reads Completed, or Failed for N). The uploaded file is consumed when generation starts; a validation refusal (a 400) leaves it in place so the mapping can be corrected and sent again. The caller needs the Generate Certificate with Private Key permission, and file_name must be a file that same user uploaded within the last hour (otherwise 404).

Request Body (application/json)

Field Type Required Description
file_name string Yes Name the CSV was uploaded under with POST /enrollment/bulk/upload. Only the caller's own uploads are visible, so another user's file, an expired one and one that never existed all answer 404.
ca string Yes Header of the CSV column holding the CertSecure CA name for each row (the Name returned by GET /ca). Every row must hold the same CA.
template string Yes Header of the CSV column holding the certificate template for each row.
key_length string Yes Header of the CSV column holding the public key size in bits (for example 2048).
common_name string Yes Header of the CSV column holding the subject common name (CN).
organization string Yes Header of the CSV column holding the subject organisation (O).
country_code string Yes Header of the CSV column holding the subject country (C), a two-letter ISO 3166-1 code.
order_validity string No Header of the CSV column holding the requested validity, such as 1 year. Mandatory only when the CA is a DigiCert one.
organization_id string No Header of the CSV column holding the numeric DigiCert organisation id. Mandatory only when the CA is a DigiCert one.
organization_unit string No Header of the CSV column holding the subject organisational unit (OU). Optional.
city string No Header of the CSV column holding the subject locality (L). Optional.
state string No Header of the CSV column holding the subject state or province (ST). Optional.
dns_names string No Header of the CSV column holding comma-separated DNS subject alternative names. Optional.
ip_addresses string No Header of the CSV column holding comma-separated IP-address subject alternative names. Optional.
san_emails string No Header of the CSV column holding comma-separated email subject alternative names. Optional.
email string No Header of the CSV column holding the comma-separated email addresses of the CertSecure users to notify about the certificate (its watchers). Optional.
group_email string No Header of the CSV column holding a distribution-list address to put in the subject. Optional; when absent the requesting user's address is used.
owner string No Header of the CSV column holding the certificate owner's email address. Optional.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/bulk/generate" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"file_name":"certificates.csv","ca":"ca","template":"template","key_length":"key_length","common_name":"common_name","organization":"organization","country_code":"country_code"}'

Responses

Status Code Description
202 Every row was processed. This does not mean every row succeeded: see the parent task for the outcome.
400 The mapping or the uploaded file failed validation; nothing was queued.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Generate Certificate with Private Key permission.
404 No upload by that name belongs to the caller, or it has expired (uploads last one hour).
500 The stored CSV could not be parsed, or the run failed unexpectedly.
POST /enrollment/bulk/upload

First step of a bulk generation. Uploads a CSV file in which each row describes one certificate, and answers with the file's columns sorted by data type so the caller can map them onto certificate fields. The second step is POST /enrollment/bulk/generate, which names this file again by file_name. The file is held on the server for one hour, per user and per file name; uploading the same name again replaces the earlier upload. It is never written to disk and nobody else can read it. The size limit is 5 MB. The caller needs the Generate Certificate with Private Key permission. The body is multipart/form-data with a single part called file. The file name must survive sanitising (path separators and similar are stripped) with something left over.

Request Body (multipart/form-data)

Field Type Required Description
file string Yes The CSV file: a header row followed by one row per certificate. At most 5 MB. The name it is uploaded under is the file_name to give to POST /enrollment/bulk/generate.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/bulk/upload" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"file":"ca,template,key_length,common_name,organization,country_code\nIssuing CA 1,WebServer,2048,www.example.com,Example Corp,US\n"}'

Responses

Status Code Description
200 The CSV was stored. Its columns, grouped by the type pandas inferred.
400 The upload was refused.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Generate Certificate with Private Key permission.
413 The file is larger than 5 MB.
500 The file could not be parsed as CSV, or could not be stored.

Example Response

{
  "date_cols": [
    "requested_on"
  ],
  "numeric_cols": [
    "key_length"
  ],
  "alphanumeric_cols": [
    "ca",
    "template",
    "common_name",
    "organization",
    "country_code"
  ]
}
POST /enrollment/bulk_ownership_transfer

Makes the registered CertSecure user email the owner of each enrollment record in eids. The new owner is checked once up front (400 if not registered); after that each Enrollment ID is processed independently and the answer is 200 even when some of them fail: read successful, failed (with a reason per ID) and already_owned for the outcome. As for the single transfer, only a global administrator or the record's current owner may move a record, so for any other caller every ID lands in failed with reason User Unauthorized. A certificate that has not been issued yet (awaiting approval or the CA, denied or failed) is not transferred either: it lands in failed with reason Ownership can only be transferred after the certificate is issued. Each transfer is recorded in that certificate's audit trail.

Request Body (application/json)

Field Type Required Description
eids array of integer Yes Enrollment IDs of the certificates to transfer. Must be a non-empty array; each element is an integer (a string of digits is also accepted). An element that is neither, for example an object, null, a boolean, a fractional number or a non-numeric string, is not looked up: it is reported in failed and the request still answers 200.
email string Yes Email address of the registered CertSecure user who becomes the new owner. Must be a string with an @ between two non-empty parts (400 otherwise), and a registered user (400).

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/bulk_ownership_transfer" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"eids":[1042,1043],"email":"[email protected]"}'

Responses

Status Code Description
200 Per-record outcome. Present even when some or all records failed.
400 The body is missing or is not a JSON object, a key is missing, eids is not a non-empty array, email is not a plausible email address, or the new owner is not a registered user.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The transfer failed unexpectedly.

Example Response

{
  "Response": "Bulk transfer of ownership complete",
  "successful": [
    1042
  ],
  "failed": [
    {
      "eid": 1043,
      "reason": "Enrollment ID not found"
    }
  ],
  "already_owned": []
}
POST /enrollment/bulk_renewal

Starts a background job that renews each listed inventory certificate and answers 202 with the id of a parent task you can follow. The job works through the serial numbers in batches of 10, 30 seconds apart. Serial numbers that another renewal job is already processing are skipped. Template maps the current template name of each certificate to the template to renew it with. Requires the Renew Inventory Certificates permission. The body is validated before anything is started (400 for a missing field, a wrong type, or a CertificateAuthority that is not registered), but the 202 only means the job was queued: a certificate that cannot be renewed, for example one whose current template is not a key of Template, fails inside the job.

Request Body (application/json)

Field Type Required Description
SerialNumber array of string Yes Serial numbers of the inventory certificates to renew: a non-empty array of non-empty strings. total_certificates in the response is its length.
Template object Yes Object mapping a certificate's current template name to the template to renew it with. A certificate whose current template is not a key fails to renew inside the job.
CertificateAuthority string Yes CertSecure name of the CA to renew against. Must be a registered CA (400 otherwise).
additional_notes string No Free-text note stored with each renewal request.
additional_info object No Object of extra order data merged into every renewal request (the job adds the computed order_validity). Free-form; not interpreted here. Anything but an object is a 400.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/bulk_renewal" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"SerialNumber":["4A1B2C3D4E5F","4A1B2C3D4E60"],"CertificateAuthority":"Issuing CA 1","Template":{"WebServer":"WebServer"}}'

Responses

Status Code Description
202 The job was accepted. taskID identifies the parent task that tracks the whole batch.
400 The body is missing or is not a JSON object; SerialNumber, CertificateAuthority or Template is missing or has the wrong type (SerialNumber an empty array or not an array of strings, Template not an object of strings); additional_notes is not a string; additional_info is not an object; or the CA is not registered.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Renew Inventory Certificates permission.
500 The parent task or the worker thread could not be started, or another unexpected failure.
POST /enrollment/bulk_revoke

Starts a background job that revokes every listed certificate and answers 202 with the id of the parent task. The shape of the body and of every entry is validated before the answer (400 for an entry that is not an object, has no CertificateAuthority string, or has an eid or serialNum of the wrong type); the individual revocations are processed afterwards, one per entry, and their outcomes (queued, skipped because the record is not active, failed, including a certificate that does not exist) are recorded in the parent task and the audit log, not in this response. Each entry is processed like POST /enrollment/revoke_cert: identify the certificate by eid, or by serialNum, and always name its CA in CertificateAuthority. The caller needs the View Enrollment Database permission and, per certificate, the same rights as for a single revocation. The body is read as JSON regardless of the Content-Type header.

Request Body (application/json)

Field Type Required Description
certificates array of object Yes The certificates to revoke, one object per certificate. Must be a non-empty array of objects.
revocation_reason string No Free-text reason, recorded in the job's task and audit entry. The key may be left out, but when it is sent it must be a string: null, a number, an array or an object is a 400. Its content is not validated and it is not sent to the CA.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/bulk_revoke" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"certificates":[{"CertificateAuthority":"Issuing CA 1","eid":1042},{"CertificateAuthority":"Issuing CA 1","serialNum":"4A1B2C3D4E5F"}],"revocation_reason":"cessationOfOperation"}'

Responses

Status Code Description
202 The job was accepted. taskID identifies the parent task to poll.
400 The body is empty, is not valid JSON or is not a JSON object; certificates is missing, empty, or not an array; revocation_reason is present and not a string (null included); or an entry is not an object, has no CertificateAuthority string, or has an eid that is neither an integer nor a string of digits, or a serialNum that is neither a string nor null.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the View Enrollment Database permission.
500 The job could not be started, or the request failed unexpectedly.
GET /enrollment/ca_cert_count

Returns, for every certificate authority (or third-party container) that has active enrollment records, the number of active records filed under it. The keys of the returned object are the CertSecure CA names. An estate with no active certificates answers an empty object. Takes no input.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/ca_cert_count" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 Map of CA name to the number of active certificates it issued.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.

Example Response

{
  "Issuing CA 1": 12,
  "Third Party Container": 3
}
GET /enrollment/cert_status

Read-only status lookup used by the Proton Gateway's OCSP responder. It answers revoked when the matching enrollment record has status revoked; revoked with revocation_reason certificateHold while it is on hold (good again once released); good for any other status (expiry is not a revocation state); and unknown when no record matches. There is no per-user ownership check: the lookup is a machine query made under an API token and revocation status is not user-private. The serial number is matched in the spellings it may be stored in (as given, with :, - and spaces removed, upper and lower case, with and without a leading zero, and the decimal form of a hex value). ca narrows the search to one CA when it names a registered CA; an unknown CA name is ignored rather than rejected. revocation_time is when the revocation or hold was recorded; it is null for a certificate revoked or held before CertSecure recorded those times. revocation_reason is null for a revocation CertSecure performed: the CA revokes those as "unspecified", which an OCSP response expresses by omitting the reason.

Request Parameters

Name Located In Type Required Description
serialNum Query string Yes Certificate serial number, usually hex; : and spaces are ignored. Must contain at least one non-blank character.
ca Query string No CertSecure name of the Certificate Authority to restrict the lookup to. Optional; a name that is not a registered CA is ignored.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/cert_status?serialNum=<serialNum>" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The disposition of the certificate. revocation_time and revocation_reason accompany revoked and may be null when the record does not hold them.
400 serialNum is missing, empty or blank.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.

Example Response

{
  "status": "good"
}
GET /enrollment/columns

Active is the caller's saved choice (the default set until one has been saved) and Available the default set plus the names of every defined custom field.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/columns" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 Columns in use and columns that can be chosen.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.

Example Response

{
  "Active": [
    "EnrollmentID",
    "commonName",
    "CertificateAuthority",
    "Template",
    "ExpiresOn",
    "SerialNumber",
    "owner",
    "san",
    "EmailID"
  ],
  "Available": [
    "EnrollmentID",
    "commonName",
    "CertificateAuthority",
    "Template",
    "ExpiresOn",
    "SerialNumber",
    "owner",
    "san",
    "EmailID",
    "Cost Center"
  ]
}
POST /enrollment/columns

Replaces the caller's saved column choice. No permission is needed beyond being signed in.

Request Body (application/json)

Field Type Required Description
columns array of string Yes Names of the columns to show, in display order. Every item must be a non-empty string (400 otherwise). The names are stored as sent, without checking them against the available columns (Available in the GET response). EnrollmentID is appended when it is missing. An empty array is accepted and stores just EnrollmentID.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/columns" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"columns":["EnrollmentID","commonName","CertificateAuthority","Template","ExpiresOn","SerialNumber","owner","san","EmailID"]}'

Responses

Status Code Description
200 The choice was saved.
400 columns is missing or is not an array (a request body that is not a JSON object counts as missing), or an item is not a non-empty string.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.

Example Response

{
  "Message": "Success"
}
POST /enrollment/csr_details

Parses a PEM-encoded PKCS#10 CSR and returns its public-key type and size, the subject attributes, and the subject alternative names. Nothing is stored; the request is only logged. A value that cannot be parsed as a CSR is answered with 400 Invalid CSR.

Request Body (application/json)

Field Type Required Description
csr string Yes PEM-encoded PKCS#10 certificate signing request, including the -----BEGIN CERTIFICATE REQUEST----- armour.
ca string No Optional. Together with template, selects Sectigo PS key-policy checks: when both name a Sectigo PS CA and one of its templates, the CSR is also checked against the key policy of that template. Ignored for every other CA.
template string No Optional. Used with ca for the Sectigo PS key-policy check described there; ignored otherwise.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/csr_details" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"csr":"-----BEGIN CERTIFICATE REQUEST-----\nMIIC6zCCAdMCAQAwbDELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYD\nVQQHDAZEYWxsYXMxFTATBgNVBAoMDEV4YW1wbGUgQ29ycDELMAkGA1UECwwCSVQx\nGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\nADCCAQoCggEBAOChnT6tEg0GgE4vjp/3RUx/psYPGuoK3606TpORcBN98xvqMNLO\nYILpbwjrlkmdJjYTJVT1yHXA9PYTvpD12DcYe08UHSQOQkC0vC7qNDZHXgOlVD8d\nG9ReQAP6KGgD7O1l0oi6wwiK5q1YNLliRVCB+PdXB2coDbyDi7GxaPVcSiWU6pdG\nC5WWRldyRAmYj18iKi72RZQjHRc3C7aGQFaSySjjO1t9ZLpubqGWMHfoOyhUOPL4\npnI/tOJmYROK4aceYjlM+hDH2ndU7ZvItnKS1cQYS71Dfjzv0VwI5rUuyidgM7/R\nWNHkZWoV1h4+F/WWtQlGN5L2APuL89yVTrcCAwEAAaA6MDgGCSqGSIb3DQEJDjEr\nMCkwJwYDVR0RBCAwHoIPd3d3LmV4YW1wbGUuY29tggtleGFtcGxlLmNvbTANBgkq\nhkiG9w0BAQsFAAOCAQEAEApMFMCPeZet/95ukhjHBgbpQDVjhxiRyg7hxcuRmBcJ\nNIHqjVW9F3ryFD+fHXrTMZJGkgaKgw1OZXlsz1j7GvwIKnaDqO2Yix/wQr07btDD\n5RMysRzOnWkcHsinDBY6VWYgMliTkA5VKTkQ+Lq1kL6cTekyaGJv3g8Suj0Hdj+M\npqKo5KjzyRK1L18hZmh7atsd9LobjNIRqm8CnuU3ympGdO/Dz80PjIPfqt3XwMpD\nNrQ6LSh71Ewfe9xNuvNrBYWo06pKoHAsVLxDzjNGVYgdouOptBP8PXsIwx+LYcYL\nzQes0tQtk85fWSwwstIw8RHTCqj+bq22Fb63n1UFpQ==\n-----END CERTIFICATE REQUEST-----\n","ca":"Issuing CA 1","template":"WebServer"}'

Responses

Status Code Description
200 Details decoded from the CSR.
400 The request body has no csr key, or the value is not a parseable PEM CSR.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 Sectigo PS only: the caller is neither a global administrator nor in a department entitled to the CA named in ca.

Example Response

{
  "key_type": "RSA",
  "key_size": 2048,
  "attributes": {
    "C": "US",
    "ST": "Texas",
    "L": "Dallas",
    "O": "Example Corp",
    "OU": "IT",
    "CN": "www.example.com"
  },
  "san_attributes": "DNS:www.example.com, DNS:example.com",
  "email": ""
}
GET /enrollment/csr_generated_count

How many CSRs were generated through POST /enrollment/generate_csr in each of the last four four-week periods (0-4 is the most recent four weeks, 12-16 the oldest). Counts all CAs unless ca narrows them to one. Any authenticated caller may read it.

Request Parameters

Name Located In Type Required Description
ca Query string No CertSecure name of a Certificate Authority to count for. Optional: omit it to count across all CAs. When sent it must be a registered CA, so an empty value is a 400.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/csr_generated_count" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 One count per period; the keys are the period labels, in weeks ago.
400 ca was sent but 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 The counts could not be produced.

Example Response

{
  "0-4": 3,
  "4-8": 1,
  "8-12": 0,
  "12-16": 5
}
DELETE /enrollment/delete-third-party-cert

Removes the enrollment record with the given Enrollment ID. Allowed for a global administrator, for a Department PKIAdmin whose department holds the record's CA, and for the record's owner; anyone else is answered with 403. The handler looks the record up by Enrollment ID only and does not check that it is a third-party record.

Request Body (application/json)

Field Type Required Description
EID integer or string Yes Enrollment ID of the record to delete. Must be an integer; a numeric string is also accepted.

Example Request

curl -X DELETE "https://<certsecure-backend-url>/enrollment/delete-third-party-cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"EID":1044}'

Responses

Status Code Description
200 The record was deleted.
400 The EID key is missing or is not an integer.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller is neither a global administrator, a Department PKIAdmin for the record's CA, nor the record's owner.
404 No enrollment record has this Enrollment ID.

Example Response

{
  "Success": "Certificate deleted"
}
POST /enrollment/delete-trusted-root

Deletes the trust-store entry whose Subject Key Identifier matches ski, then triggers a background rebuild of stored chains. Unlike the import endpoints, this handler checks no permission beyond authentication.

Request Body (application/json)

Field Type Required Description
ski string Yes Subject Key Identifier of the trusted root to remove, hexadecimal, as returned by GET /enrollment/trusted-roots. Must be a string: anything else, such as an object, is a 400 (the value is used as a database filter).

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/delete-trusted-root" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"ski":"4a1b2c3d4e5f60718293a4b5c6d7e8f901234567"}'

Responses

Status Code Description
200 The trust-store entry was removed.
400 The body is missing or is not a JSON object, ski is missing or empty, or ski is not a string.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
404 No trust-store entry has this Subject Key Identifier.
500 The deletion failed unexpectedly.

Example Response

{
  "Success": "Trusted root certificate with SKI (4a1b2c3d4e5f60718293a4b5c6d7e8f901234567) deleted successfully"
}
GET /enrollment/download

Returns the certificate of an active enrollment record in the requested format. Identify the record with eid, or with taskID of the request that produced it (when taskID is present eid is ignored). type=cer (the default) returns the certificate as PEM text; p7b returns the stored PKCS#7 chain as PEM text; text returns every certificate of the chain, concatenated as PEM text; zip returns an archive holding the certificate, the chain and the full-chain bundle in DER and PEM form. The text formats are served as text/html, the archive as application/zip with a Content-Disposition header naming <commonName>.zip. The caller needs the View Enrollment Database permission and must also hold Download Certificate, be a global administrator, be a Department PKIAdmin whose department owns the CA, or be the owner or a listed watcher of the record. p7b, zip and text need the record to hold a chain, which records that were not issued through CertSecure may not.

Request Parameters

Name Located In Type Required Description
eid Query integer No Enrollment ID of the certificate to download. Required unless taskID is sent (400 otherwise); must be an integer.
taskID Query integer No Id of the task that created or renewed the certificate; its enrollment ID is looked up from it. Alternative to eid. An unknown task id is not handled and fails the request.
type Query string No Format to download: cer (certificate, PEM), p7b (PKCS#7 chain, PEM), text (all certificates of the chain, PEM) or zip (archive). Case-insensitive; default cer.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/download" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The certificate in the requested format. cer, p7b and text are PEM text served as text/html; zip is a binary archive.
400 No identifier was sent, eid is not an integer, the record holds no certificate, or type is not supported.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller lacks the View Enrollment Database permission (JSON), or may not download this certificate (plain text).
404 There is no active enrollment record with this id, or type=p7b was asked of a record that holds no chain.
500 The requested format could not be produced, for example a zip or text of a record that holds no chain.
GET /enrollment/download_cert

Returns the PEM certificate of an active enrollment record. Identify the record with eid, or with taskID of the request that produced it (when taskID is present eid is ignored). The body is the bare PEM text, served as text/html. The caller needs the View Enrollment Database permission and must also hold Download Certificate, be a global administrator, be a Department PKIAdmin whose department owns the CA, or be the owner or a listed watcher of the record. For other formats (PKCS#7, chain, archive) use GET /enrollment/download.

Request Parameters

Name Located In Type Required Description
eid Query integer No Enrollment ID of the certificate to download. Required unless taskID is sent (400 otherwise); must be an integer.
taskID Query integer No Id of the task that created or renewed the certificate; its enrollment ID is looked up from it. Alternative to eid. An unknown task id is not handled and fails the request.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/download_cert" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The certificate in PEM form.
400 No identifier was sent, eid is not an integer, or the record holds no certificate.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller lacks the View Enrollment Database permission (JSON), or may not download this certificate (plain text).
404 There is no active enrollment record with this id.
500 The certificate could not be read.
POST /enrollment/download_cert_enroll_pfx

Builds a password-protected PKCS#12 bundle from the stored certificate of an active enrollment record and the private key the caller supplies, and returns it as a file download named Enrollment_<EnrollmentID>.pfx. CertSecure does not keep the key: it must be sent in key (PEM, optionally encrypted, in which case KeyPassphrase is required), and it must belong to the stored certificate. Requires the Download Certificate permission. A key that is wrong, undecryptable or not matching the certificate is answered 400, as is a missing or empty key. The fields are type-checked first: EnrollmentID, ExportPassword, key and algo of the wrong type are a 400 that names the field. The SHA1-3DES profile needs the OpenSSL legacy provider on the server; where it is missing the request is answered 400 with a message saying so (it is not a problem with the key) and OpenSSL's output in details. Algorithm is an older spelling of algo that is still read (it wins when it is non-empty) but is no longer part of the contract; send algo.

Request Body (application/json)

Field Type Required Description
EnrollmentID integer or string Yes Enrollment ID of the certificate to export: an integer, or a string of digits. Anything else (a sign, a fraction, a boolean, an object) is a 400. The record must exist, be active and hold a certificate.
ExportPassword string Yes Password that protects the exported PFX file. Required; must be a string that meets the product's password policy (a weaker one is a 400 naming each rule it breaks). The schema states the policy every install starts with: 9 to 16 characters, at least 2 upper-case, 2 lower-case, 2 digits and 1 special character (ASCII punctuation); an administrator can change it with POST /enrollment/policy, and the server then enforces the changed one. This is the password of the new PFX, so KeyPassphrase (the existing key's own passphrase) is not held to it.
KeyPassphrase string No Passphrase of the private key in key. Needed only when that key is encrypted; omit it for an unencrypted key.
algo string or string No Encryption profile of the PFX: SHA256-AES (AES-256 with SHA-256 MAC, the default) or SHA1-3DES (legacy, 3DES with SHA-1 MAC, for old consumers). Case-insensitive. The empty string, which the web interface sends for the default, and an omitted key both mean SHA256-AES. A value that is not a string is a 400, and so is an unknown profile name (Unsupported algorithm profile).
key string Yes The certificate's private key as PEM (-----BEGIN PRIVATE KEY----- or -----BEGIN RSA PRIVATE KEY-----, or the encrypted forms). It must match the stored certificate. Required and non-empty (400 key should be passed otherwise); must be a string. Sending a CSR or a certificate here is rejected with 400.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/download_cert_enroll_pfx" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"EnrollmentID":1042,"ExportPassword":"Export-Pa55word!","KeyPassphrase":"Key-Pa55phrase!","algo":"SHA256-AES","key":"-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQGVlWzGmPF8bGWiEq\nxtx6CQICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEG5D9WtEC7ibVgju\n42VTFoIEggTQeGNYtvCUOtVK4lvobf0i0c6xLOHyGwmBFqiDO7W5pqgmRWqGjrm6\ndFU3XdjmfzH9JKrSrLuZgwLbT7k345crGRivzOf0DQqkda4l8oh/f+Vor19jdPnX\nlxnQ1MrbvLXldGLDn9jgYTYJfHN3gcU69I49tnfYPhJiKhCEeu55u3BBDlHXgFyd\nEC1mDYNgvR1vRggIZDZqdYFTR07ZgqImB5tJpRUMwCvk4WTwOdbt0AAmSQ8oCF8v\ng1tFGYU0K0rMEO3Q3KwzRUKPxiCB68MgytnnyLoy/kmGxJqPVhhdkwDeKJ3UHPN4\nuyvtz6rZv6XRYUiYKdgsrNZ99eTvkNi+G0KaZ549Z6cjTO9SPle8S0xrj3XNlpGm\nHftGNoZunRcoh1ejobvZC505uhhaFZni+FPkPdisG7LyB2o3hFbzoPpVIyDcqEF0\nkuAVFByPs5GPPAsI8sLs5mdom0qd96CW4VNSJ21hZ4KsFt7v835zG0Jr4wgNR62q\n+Ic985ScuUNBpQNlq4T+i4dozOGbf0VwaNVljPTIDuCOMj36cTcuwIuxjbJo5imm\nQff8LfwgevVeQU627WOfIItVH0c9z0EFaDiE3pmYKZnTJvouehUts86JUSieSgHr\nWdqon82XBCGxHtE0JE9kVJYNd4FmJriyv0txtqsH+tm2CJOsFTEpmnTJU+qycUPf\njEssl+00BuDSVuE95+m1NcEqjEeWoliWd3hN8Dscd0vkl2MqQB387D+32NqNUJOY\n3pX8WF0sp8ocoK9ssvvWWA/AGN19pf8UGcSebknRT8daxnDRf6kEjWrY/Q90f+Ht\nojgXbWVr3Ftr+RxbuTtTQ4HWnOaalFDrqNlHpPqcJinViGWXYTMYi7xdmwLtRnlT\nj301x2Ixq9HzgxDo0zrTOP2FyYaplgWJJMQ9qyRzqVIoi9bU3OA2teYO6S/Z6O2J\n7VKpLqnaDD4zmSz0uGUVlenhdSeEQG6dhnkUiGt3B8uobWKUQGxXDzDv/wL4sgrO\niDo+IuAKHOBk59hyJ66dGzgcU81DdSUyPUUOmz7zCPRNldb5zNAdwwGW9Xi8P18k\nqE9Zn9WRm1nghz7hru1E0AfAxK0g+dLZjsTP63eWOiaCBkVonVJdb7ePXI/bM74o\nlCvL5gOCuuvE8OUd2qVE1iUYHj2DQ2130/X/gd8MjbysU8aMmfeAIr4WTgr1UEnJ\nJ8HILhAPHDyL4wN0NXRzH8a4cT9rKUEs/dOBYgUrMJePTmpizi9OlesFDUN1EnJq\nRnedvfaaIa+EsqzQAbBMpF4tYS07nCFzZb6vfuD6n4yBQg1eIR7BqC8L58o8faNC\nNUDc91I9rNKxvvjQ/geR55izOr6haFQHKyufp1yM1RdYkwvP1PORwc7NoXou2IvB\nX3kx1LxZu++8FJPuR7zpgDkP89+kjalaWZr3Ca1I8yNDpaMraC/jcfDOBZPbPG1s\ncqKDnc1wy9q193l3ZPtB/PMKjL3f+nmlKicixALsORENx7i9G7Lh2cB2A/ZpjTHC\nL5e+kYDld5bxj8Xa7KsoJtYsVXZasl/ruta0y4fEGZxjK00RBFcpU3tQgQRo8l+2\n0gwRk+Md260mQ1JBJjj6jY7/I9Q/IRxTeFA5e8Of8etSEyWAQwzFDjY=\n-----END ENCRYPTED PRIVATE KEY-----\n"}'

Responses

Status Code Description
200 The PFX file, sent as an attachment named Enrollment_<EnrollmentID>.pfx.
400 EnrollmentID, key or ExportPassword is missing or of the wrong type, key is the wrong kind of PEM or does not match the certificate, or OpenSSL could not build the PFX. Further 400 messages, produced once the record has been found: Valid PRIVATE KEY PEM block not found in request.key and Unsupported algorithm profile: <value>. Failures raised by OpenSSL also carry a details key with up to 800 characters of its output.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Download Certificate permission.
404 No active enrollment record has this Enrollment ID.
500 The record has no certificate stored, or the export failed unexpectedly.
POST /enrollment/download_pfx

Exports the certificate and the private key stored with an active enrollment record as a PKCS#12 file protected by password. Identify the record with eid, or with taskID of the request that produced it (eid wins when both are sent). password must satisfy the password policy configured in the product (minimum length and minimum counts of upper-case, lower-case, digit and special characters). The record must hold both a certificate and a private key. The response body is the raw PKCS#12 file; the handler sends it without setting a content type, so it is labelled text/html. The caller needs the View Enrollment Database permission and must also hold Download Certificate, be a global administrator, be a Department PKIAdmin whose department owns the CA, or be the owner or a listed watcher of the record.

Request Parameters

Name Located In Type Required Description
algorithm Query string No Encryption used inside the PFX. SHA1-3DES selects PBE-SHA1-3DES with a SHA-1 MAC (legacy), SHA256-AES selects AES-256-CBC with a SHA-256 MAC; case-insensitive. Any other value, or none, leaves the OpenSSL default.

Request Body (application/json)

Field Type Required Description
password string Yes Password protecting the PFX. Must meet the product's password policy; a weaker one is answered with 400 naming each rule it breaks. The schema states the policy every install starts with: 9 to 16 characters, at least 2 upper-case, 2 lower-case, 2 digits and 1 special character (ASCII punctuation). An administrator can change the policy with POST /enrollment/policy, and the server then enforces the changed one.
eid integer or string No Enrollment ID of the certificate. An integer or an integer string. Required unless taskID is sent.
taskID string No Id of the task that created or renewed the certificate, as a string of digits; its enrollment ID is looked up from it. Alternative to eid, used only when eid is absent. When it is sent it must be a string of digits even if eid is also sent (and wins): anything else, including null, a number or an empty string, is a 400.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/download_pfx" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"eid":1042,"password":"ExamplePass#42"}'

Responses

Status Code Description
200 The PKCS#12 file (binary), served with a text/html content type.
400 A field is missing or invalid, the password breaks the policy, or the record lacks a certificate or key.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller lacks the View Enrollment Database permission (JSON), or may not download this certificate (plain text).
404 There is no active enrollment record with this id.
500 The PFX could not be produced.
POST /enrollment/download_zip_key

Builds a zip archive with the certificate, the chain and the full-chain bundle in DER and PEM form, plus the private key re-encrypted with password (as <commonName>_privkey.key and pem/<commonName>_privkey.pem). Identify the record with eid, or with taskID of the request that produced it (eid wins when both are sent). The private key is the one stored with the record unless privateKey is sent; a key sent in privateKey must be PEM encrypted with the same password, otherwise 400. The body must be a JSON object, password and privateKey must be strings and a taskID that is sent must be a string of digits even when eid is also sent (a 400 names the field otherwise); eid still wins and the two are not compared. password must satisfy the password policy configured in the product (minimum length and minimum counts of upper-case, lower-case, digit and special characters). Success is the archive, application/zip, with a Content-Disposition header naming <commonName>.zip. The caller needs the View Enrollment Database permission and must also hold Download Certificate, be a global administrator, be a Department PKIAdmin whose department owns the CA, or be the owner or a listed watcher of the record. Several validation failures are answered as plain text (text/html) and the rest as JSON; both are listed.

Request Body (application/json)

Field Type Required Description
password string Yes Password that protects the private key inside the archive. Must meet the product's password policy; a weaker one is answered with 400 naming each rule it breaks. The schema states the policy every install starts with: 9 to 16 characters, at least 2 upper-case, 2 lower-case, 2 digits and 1 special character (ASCII punctuation). An administrator can change the policy with POST /enrollment/policy, and the server then enforces the changed one.
eid integer or string No Enrollment ID of the certificate. An integer or an integer string. Required unless taskID is sent.
taskID string No Id of the task that created or renewed the certificate, as a string of digits; its enrollment ID is looked up from it. Alternative to eid, used only when eid is absent. When it is sent it must be a string of digits even if eid is also sent: anything else, including null, a number or an empty string, is a 400.
privateKey string No PEM private key to put in the archive, either unencrypted or encrypted with password; it is always re-encrypted with password in the archive. Optional: when omitted or the empty string, the key stored with the enrollment record is used (400 when there is none). A key that cannot be read (not PEM, or encrypted with another password) is a 400; a value that is not a string, including null, is a 400.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/download_zip_key" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"eid":1042,"password":"ExamplePass#42"}'

Responses

Status Code Description
200 The archive. The Content-Disposition header names it <commonName>.zip.
400 The body is not a JSON object, a field is missing or invalid, the password breaks the policy, a supplied privateKey cannot be read, or the record holds no private key. Identifier and password-presence problems are plain text; the new type messages, the policy and the key messages are JSON.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller lacks the View Enrollment Database permission (JSON), or may not download this certificate (plain text).
404 There is no enrollment record with this id.
500 The archive could not be built, for example because the stored key could not be read or the record holds no chain.
POST /enrollment/enroll-acme-ca-cert

Records a certificate that was obtained directly over ACME from a public CA as a normal CA-issued enrollment record: CertificateAuthority is the registered name of the ACME CA named by ca (not a third-party container), and the record is created as already issued, with an enrollment task logged against it. The CA must already be registered as an ACME CA under CA Management; the certificate is filed under a template that CA has. Requires the Import Certificate permission. A certificate with the same serial number under the same CA is refused with 404.

Request Body (application/json)

Field Type Required Description
additional_notes string No Free-text note stored with the request and shown in the certificate's history. Not interpreted.
ca string Yes CertSecure name of an ACME Certificate Authority, as registered under CA Management (the Name returned by GET /ca, not the CA's subject DN). A name that is not an ACME CA, a Microsoft or DigiCert CA for example, is refused with 400 No ACME CA named '<name>' is registered.
cert_chain string No PEM-encoded issuing chain for the certificate, root last.
cert_data string Yes PEM-encoded certificate body.
domain_id string No Optional. Identifier of the ACME domain entry used for DNS-01 validation, as listed by GET /acme/get_domains. When given it must exist, otherwise the request is rejected with 400.
tags array of string No Free-form labels attached to the certificate for grouping and reporting.
watchers array of string No Email addresses notified about this certificate's expiry and lifecycle events, in addition to the owner.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/enroll-acme-ca-cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"additional_notes":"Issued for the public web front end.","ca":"API Test ACME","cert_chain":"-----BEGIN CERTIFICATE-----\nMIIDgzCCAmugAwIBAgIGShssPU5fMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYT\nAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGRGFsbGFzMRUwEwYDVQQKDAxF\neGFtcGxlIENvcnAxCzAJBgNVBAsMAklUMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5j\nb20wHhcNMjYwMTAxMDAwMDAwWhcNNDYwMTAxMDAwMDAwWjBsMQswCQYDVQQGEwJV\nUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkRhbGxhczEVMBMGA1UECgwMRXhh\nbXBsZSBDb3JwMQswCQYDVQQLDAJJVDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29t\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4KGdPq0SDQaATi+On/dF\nTH+mxg8a6grfrTpOk5FwE33zG+ow0s5ggulvCOuWSZ0mNhMlVPXIdcD09hO+kPXY\nNxh7TxQdJA5CQLS8Luo0NkdeA6VUPx0b1F5AA/ooaAPs7WXSiLrDCIrmrVg0uWJF\nUIH491cHZygNvIOLsbFo9VxKJZTql0YLlZZGV3JECZiPXyIqLvZFlCMdFzcLtoZA\nVpLJKOM7W31kum5uoZYwd+g7KFQ48vimcj+04mZhE4rhpx5iOUz6EMfad1Ttm8i2\ncpLVxBhLvUN+PO/RXAjmtS7KJ2Azv9FY0eRlahXWHj4X9Za1CUY3kvYA+4vz3JVO\ntwIDAQABoyswKTAnBgNVHREEIDAegg93d3cuZXhhbXBsZS5jb22CC2V4YW1wbGUu\nY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAs+vreNbnsbORRn4Xlqkx3YgFIVUr9ia+s\nE+KNkFtZ6VqwJ4zBCghYUXAcvGqb/0Ru1jr1hXFW1C4WgeXoGhWm+l6FEgLaHA0Z\nh9JcUZ+zkhLnzHtsz4EBnqmDQ93YjFbQMFkPFxrO98RZsbgcGovF4ohrxRypcYbS\nwcbPRP1NWcF8ljJlbLCTM4pEGz4wfaioZHRed5Po0EcOh5O0JLkqxrhlW6Y9enNE\n5NBywAIeg8Dh50rNtoo9LlvpPboNdr7+Kit+xmzTOoZK2Ky9SjuVm7vOIQ17/02y\n9pPQRD5Uz8jRif2CRgIrm9KuqGsR6C+LM6cvL3CKn4r/zJ9Dk2Uy\n-----END CERTIFICATE-----\n","cert_data":"-----BEGIN CERTIFICATE-----\nMIIDgzCCAmugAwIBAgIGShssPU5fMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYT\nAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGRGFsbGFzMRUwEwYDVQQKDAxF\neGFtcGxlIENvcnAxCzAJBgNVBAsMAklUMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5j\nb20wHhcNMjYwMTAxMDAwMDAwWhcNNDYwMTAxMDAwMDAwWjBsMQswCQYDVQQGEwJV\nUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkRhbGxhczEVMBMGA1UECgwMRXhh\nbXBsZSBDb3JwMQswCQYDVQQLDAJJVDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29t\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4KGdPq0SDQaATi+On/dF\nTH+mxg8a6grfrTpOk5FwE33zG+ow0s5ggulvCOuWSZ0mNhMlVPXIdcD09hO+kPXY\nNxh7TxQdJA5CQLS8Luo0NkdeA6VUPx0b1F5AA/ooaAPs7WXSiLrDCIrmrVg0uWJF\nUIH491cHZygNvIOLsbFo9VxKJZTql0YLlZZGV3JECZiPXyIqLvZFlCMdFzcLtoZA\nVpLJKOM7W31kum5uoZYwd+g7KFQ48vimcj+04mZhE4rhpx5iOUz6EMfad1Ttm8i2\ncpLVxBhLvUN+PO/RXAjmtS7KJ2Azv9FY0eRlahXWHj4X9Za1CUY3kvYA+4vz3JVO\ntwIDAQABoyswKTAnBgNVHREEIDAegg93d3cuZXhhbXBsZS5jb22CC2V4YW1wbGUu\nY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAs+vreNbnsbORRn4Xlqkx3YgFIVUr9ia+s\nE+KNkFtZ6VqwJ4zBCghYUXAcvGqb/0Ru1jr1hXFW1C4WgeXoGhWm+l6FEgLaHA0Z\nh9JcUZ+zkhLnzHtsz4EBnqmDQ93YjFbQMFkPFxrO98RZsbgcGovF4ohrxRypcYbS\nwcbPRP1NWcF8ljJlbLCTM4pEGz4wfaioZHRed5Po0EcOh5O0JLkqxrhlW6Y9enNE\n5NBywAIeg8Dh50rNtoo9LlvpPboNdr7+Kit+xmzTOoZK2Ky9SjuVm7vOIQ17/02y\n9pPQRD5Uz8jRif2CRgIrm9KuqGsR6C+LM6cvL3CKn4r/zJ9Dk2Uy\n-----END CERTIFICATE-----\n","domain_id":"37105","tags":["production","external"],"watchers":["[email protected]"]}'

Responses

Status Code Description
200 The certificate was registered. eid is the new Enrollment ID.
400 A required key is missing, ca does not name a registered ACME CA, domain_id does not exist, or cert_data could not be parsed.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Import Certificate permission.
404 A record with this serial number already exists under the same CA; the message names its Enrollment ID. (Reported as 404 by this endpoint, not 409.)
500 The enrollment failed unexpectedly.

Example Response

{
  "eid": 1042
}
POST /enrollment/enroll_csr

Submits a CSR you generated yourself and queues a certificate request for it; the response is the id of the task that tracks the request. The CSR is parsed (an unreadable one is a 400) and the subject is taken from it. The CA must be registered and the template must be one it publishes. Requires the Submit CSR permission. Whether the request then needs approval depends on the template workflow and on the request policy, which can raise the approvals required for callers other than administrators. SANs are the CSR's own plus san_attributes, unless override_csr_sans is true, when only san_attributes is used. For an ACME CA the CSR's DNS names must all belong to one registered, validated ACME domain; for CAs that build their request from a policy template the CSR is validated against that policy (a violation is a 400). To renew an existing certificate with your own CSR, use POST /enrollment/renew_csr; renews_serial is no longer accepted here. The optional fields are type-checked before anything else is looked at (a wrong type is a 400 naming the field). Several refusals come back as plain text (text/html) rather than JSON, and an unexpected failure is a 400 with a generic Error message; the reason is in the CertSecure log.

Request Body (application/json)

Field Type Required Description
csr string Yes PEM-encoded PKCS#10 certificate signing request, including the -----BEGIN CERTIFICATE REQUEST----- armour. It must parse (400 Invalid CSR otherwise).
template string Yes Certificate template to issue against. Must be one the chosen CA publishes (400 Not a correct template mapping otherwise); GET /enrollment/templates lists them. For a Sectigo CA the numeric certificate type id is accepted in place of the name.
ca string Yes CertSecure name of the Certificate Authority to request from. Must be a registered CA (400 otherwise).
email array or string No E-mail addresses to notify about the request and the issued certificate (its watchers): an array of strings, or the empty string for none (what the web interface sends when there are no watchers). Any other type, including a non-empty string and null, is a 400.
san_attributes string or array No Additional subject alternative names, as comma-separated entries: DNS:, IP:, IPAddress:, Email: or OtherName: followed by the value, or type=value (for example dns=host). Sent as one string, or as an array of such entries. An entry in any other form is a 400, and so is any other type, including null. Empty means none. Merged with the SANs in the CSR unless override_csr_sans is true.
override_csr_sans boolean No When true, only the SANs in san_attributes are used and the ones carried inside the CSR are dropped; when false or left out, the two lists are merged. Must be a boolean when sent: anything else, including null, is a 400.
renews_serial object No No longer accepted: renew with POST /enrollment/renew_csr. A request that carries this field, with any value, is refused with a 400 so that it is never enrolled as an unlinked new certificate in place of the renewal it asked for.
tags array of string No Free-form labels attached to the certificate for grouping and reporting. Must be an array of strings when sent: anything else, including null, is a 400.
additional_notes string No Free-text note stored with the request and shown in the certificate's history. Must be a string when sent: anything else, including null, is a 400.
additional_data object No Caller-supplied data stored on the request task. Free-form. For a policy-template CA it may carry organization_id, term and external_requester, which are passed to the CA; the data the policy produces then replaces it.
customFields array No Values for administrator-defined custom fields, as {"name": ..., "value": ...} objects, for example [{"name": "Cost Center", "value": "CC-1042"}]. Every name must be a defined custom field (POST /customFields/create) and every field defined as required must be present, otherwise 400. Optional when no defined field is required; null counts as no values, like leaving the key out.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/enroll_csr" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"csr":"-----BEGIN CERTIFICATE REQUEST-----\nMIIC6zCCAdMCAQAwbDELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYD\nVQQHDAZEYWxsYXMxFTATBgNVBAoMDEV4YW1wbGUgQ29ycDELMAkGA1UECwwCSVQx\nGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\nADCCAQoCggEBAOChnT6tEg0GgE4vjp/3RUx/psYPGuoK3606TpORcBN98xvqMNLO\nYILpbwjrlkmdJjYTJVT1yHXA9PYTvpD12DcYe08UHSQOQkC0vC7qNDZHXgOlVD8d\nG9ReQAP6KGgD7O1l0oi6wwiK5q1YNLliRVCB+PdXB2coDbyDi7GxaPVcSiWU6pdG\nC5WWRldyRAmYj18iKi72RZQjHRc3C7aGQFaSySjjO1t9ZLpubqGWMHfoOyhUOPL4\npnI/tOJmYROK4aceYjlM+hDH2ndU7ZvItnKS1cQYS71Dfjzv0VwI5rUuyidgM7/R\nWNHkZWoV1h4+F/WWtQlGN5L2APuL89yVTrcCAwEAAaA6MDgGCSqGSIb3DQEJDjEr\nMCkwJwYDVR0RBCAwHoIPd3d3LmV4YW1wbGUuY29tggtleGFtcGxlLmNvbTANBgkq\nhkiG9w0BAQsFAAOCAQEAEApMFMCPeZet/95ukhjHBgbpQDVjhxiRyg7hxcuRmBcJ\nNIHqjVW9F3ryFD+fHXrTMZJGkgaKgw1OZXlsz1j7GvwIKnaDqO2Yix/wQr07btDD\n5RMysRzOnWkcHsinDBY6VWYgMliTkA5VKTkQ+Lq1kL6cTekyaGJv3g8Suj0Hdj+M\npqKo5KjzyRK1L18hZmh7atsd9LobjNIRqm8CnuU3ympGdO/Dz80PjIPfqt3XwMpD\nNrQ6LSh71Ewfe9xNuvNrBYWo06pKoHAsVLxDzjNGVYgdouOptBP8PXsIwx+LYcYL\nzQes0tQtk85fWSwwstIw8RHTCqj+bq22Fb63n1UFpQ==\n-----END CERTIFICATE REQUEST-----\n","template":"WebServer","ca":"Issuing CA 1","email":["[email protected]"],"san_attributes":"DNS:www.example.com,DNS:example.com","override_csr_sans":false,"tags":["production"],"additional_notes":"Web server certificate request"}'

Responses

Status Code Description
200 The request was queued. TaskID identifies the task that tracks it.
400 The request was refused: a required field is missing, an optional field has the wrong type, the CSR, CA, template, SANs or custom fields are unusable, or the request failed in a way the handler reports as 400.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Submit CSR permission.
404 The CA has no template policy, or no details for the template, on record.
500 The CSR could not be validated against the CA policy, or the CA's inventory has not been refreshed yet.

Example Response

{
  "TaskID": "5821"
}
POST /enrollment/enroll_on_behalf

RA-attested "on-behalf" enrollment, used by the Proton Gateway after it has terminated a CMPv2 ir/kur exchange. Instead of a CSR, the caller submits the end entity's public key (and optionally its subject and requested extensions) as base64-encoded DER. The request is queued as an issue_on_behalf task which the CA connector issues through an Enrollment-Agent CMC request on AD CS. The CSR-based path (POST /enrollment/enroll_csr) is not involved. The caller needs the Submit On-Behalf Request permission. The response only confirms the request was queued: follow TaskID through GET /tasks for the outcome. The CA and template named in the request must exist and be mapped to each other, otherwise the request is refused with a 400. Error bodies are not uniform: the presence checks answer with a bare text string (text/html), the validation checks with {"Error": ...}, and an unexpected failure with {"Error:": ...} (the key really does carry a trailing colon).

Request Body (application/json)

Field Type Required Description
public_key string Yes The key to certify, as the base64 encoding of its DER SubjectPublicKeyInfo (not PEM). Must be non-empty, valid base64.
template string Yes Certificate template to issue against. Must be one the chosen CA publishes (GET /inventory/templates lists them).
ca string Yes CertSecure name of the Certificate Authority to issue from. This is the Name returned by GET /ca, not the CA's subject DN. The CA must be registered, otherwise the answer is a 400.
subject string No Requested certificate subject, as the base64 encoding of a DER Name. Optional; an empty string is treated as absent. A non-empty value must be valid base64.
extensions string No Requested X.509 extensions, as the base64 encoding of a DER Extensions sequence. Optional; an empty string is treated as absent. A non-empty value must be valid base64.
crmf string No The original CMP CRMF certificate-request message (base64 DER CertReqMsg) carrying the end entity's own proof-of-possession. When present the CA connector re-presents it to AD CS; when absent a throw-away proof is used. Optional; a non-empty value must be valid base64.
pop_verified boolean No Whether the gateway verified the proof-of-possession for public_key before forwarding it. Asserted by the gateway and recorded on the request; any value is read as a boolean and the default is false.
old_serial string No Hex serial number of the certificate being replaced, for a CMP key-update (kur) request, so the connector can revoke it as superseded once the new certificate has issued. Omit it on a first issuance (ir).
email array of string No Email addresses of CertSecure users to notify about this request (its watchers). Optional. Each entry must be a string.
tags array of string No Free-form labels attached to the certificate for grouping and reporting. Optional; anything other than a list is ignored.
additional_notes string No Free-text note stored with the request and shown in the certificate's history. Not interpreted.
additional_data object No Caller-supplied data carried onto the queued task unchanged. Optional; any JSON value is accepted.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/enroll_on_behalf" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"public_key":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+njHpGH32ysr129ASPPGDSg0KPji1bJzMBa91voQBbH+z95QukB1crgPTdK5Ov9t/J4p9xH6ujVgT/J+52Bn/WFnAZ0N89XXW1GuqqCgcOfyR7mKgs/caRRsvow15zoTfimq0XtxMhFKhBEZmmwsjgRwNf76RU+mvpckGqW+ignXC3mubuI6BtElK8EDaPBt1/m5EddgIMR8Du4Dly/GY0Fh/4R6qcPdSzHhXjGI9NJSJg2HQPOdALKYt194HVK+64F7F43kHYVkIJaxVAWuW0Eefztu4MroCe9JcWs7qlDiwUWsb4VwXak/Cvik2BbQBIwvZgRgz2v4nSec+dRGQwIDAQAB","subject":"MBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbQ==","extensions":"MBwwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29t","pop_verified":true,"template":"WebServer","ca":"Issuing CA 1","email":["[email protected]"],"tags":["production","external"],"additional_notes":"Issued for the branch-office gateway."}'

Responses

Status Code Description
200 The request was queued. Follow the task for the outcome.
400 The request was refused. Missing keys and an empty public_key answer with a bare text string (text/html); every other refusal is JSON.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Submit On-Behalf Request permission.

Example Response

{
  "TaskID": "2417"
}
GET /enrollment/enrolled_csr_details

Returns the request details of one certificate: subject fields, SANs split by kind, status, owner and watchers. Identify the certificate with exactly one of eid (enrollment ID), taskID (the task that requested it) or serialNum together with ca; when several are sent, eid is used first, then taskID, then serialNum. For eid and taskID the caller must hold View all user certificates or be the record's owner or a listed watcher (403 otherwise). A serialNum lookup falls back to the CA inventory when the certificate has no enrollment record and then needs a global administrator, a Department PKIAdmin of that CA, or the View Inventory permission; in that case the SAN fields are empty and the document has the inventory shape (Serial Number, Watchers, ... instead of EnrollmentID, EmailID). Several failures are answered as plain text (text/html) rather than JSON; both are listed.

Note: Pass eid, taskID, or serialNum together with ca.

Request Parameters

Name Located In Type Required Description
eid Query integer No Enrollment ID of the certificate. Takes precedence over taskID and serialNum. Must be an integer (400 otherwise). At least one of eid, taskID, serialNum is needed.
taskID Query integer No Id of the task that requested the certificate; its enrollment ID is looked up. Used when eid is absent. An unknown or non-numeric task id is not handled and fails the request.
serialNum Query string No Certificate serial number, used when neither eid nor taskID is sent. ca must accompany it: without ca the handler fails with 500.
ca Query string No CertSecure name of the Certificate Authority of the certificate. Needed with serialNum (an unregistered name is a 400, a missing one a 500); ignored with eid or taskID.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/enrolled_csr_details" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The certificate details. Fields for an enrollment record are listed; a certificate found only in the CA inventory is returned in the inventory shape instead.
400 No identifier was sent or eid is not an integer (plain text), or the CA of a serialNum lookup is not registered (JSON).
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller may not see this certificate. JSON for eid/taskID, plain text for serialNum.
404 No enrollment record or inventory certificate matches.
500 The lookup failed, for example serialNum was sent without ca.

Example Response

{
  "EnrollmentID": 1042,
  "CertificateAuthority": "Issuing CA 1",
  "Template": "WebServer",
  "Status": "active",
  "EmailID": [
    "[email protected]"
  ],
  "keyLength": 2048,
  "commonName": "www.example.com",
  "san": "dns=www.example.com&dns=example.com",
  "sanDNSNames": [
    "www.example.com",
    "example.com"
  ],
  "sanIPAddresses": [],
  "sanEmails": [],
  "ExpiresOn": "12/31/2026 11:59 PM",
  "pfxExport": "False",
  "certAvailable": true,
  "organization": "Example Corp",
  "organizationUnit": "IT",
  "state": "Texas",
  "country_code": "US",
  "city": "Dallas",
  "owner": "[email protected]",
  "certIgnored": false,
  "thirdPartyCert": false
}
GET /enrollment/enrollment_inventory_count

Number of enrollment records in each lifecycle status, across all CAs and users. Any authenticated caller may read it; it is not scoped to the caller's department.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/enrollment_inventory_count" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 One count per status.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.

Example Response

{
  "active": 128,
  "denied": 4,
  "expired": 37,
  "pending": 9,
  "revoked": 12,
  "failed": 2
}
GET /enrollment/expiry_count

Returns how many tracked certificates are currently filed in each of the 7, 30, 60 and 90 day expiry buckets. The counts are read from the pre-computed expiry collection that the background refresh job maintains, so they are only as fresh as the last refresh run. Takes no input; each call also writes an entry to the audit log.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/expiry_count" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 Number of certificates in each expiry bucket. The four keys are always present.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.

Example Response

{
  "7": 2,
  "30": 5,
  "60": 9,
  "90": 14
}
POST /enrollment/generate_acme_cert

Queues an ACME certificate request. The CA comes from ca (the CertSecure name of an ACME CA registered under CA Management) and the domain from domain_id (a registered domain whose DNS validation has not failed); CertSecure proves control of the domain through the DNS provider stored with that domain and generates the key itself. The certificate's common name is sub_domain and the registered domain joined with a dot, or just the registered domain when sub_domain is empty or absent. The caller needs the Generate Certificate with Private Key permission. The response only confirms the request was queued: follow TaskID through GET /tasks for the outcome. key_length, ca and domain_id must all be present; san_attributes is optional.

Request Body (application/json)

Field Type Required Description
additional_data object No Caller-supplied data carried onto the queued task unchanged. Optional; any JSON value is accepted.
additional_notes string No Free-text note stored with the request and shown in the certificate's history. Not interpreted.
ca string Yes CertSecure name of an ACME Certificate Authority, as registered under CA Management (the Name returned by GET /ca, not the CA's subject DN). A name that is not an ACME CA, a Microsoft or DigiCert CA for example, is refused with 400 No ACME CA named '<name>' is registered.
domain_id string Yes Identifier of the registered domain to request a certificate for: the id of a domain registered through the /acme endpoints (a five-digit string). An unknown id answers 400, and so does a domain whose validation has failed.
email array of string No Accepted for compatibility and not used: the notification list comes from watchers. Each entry must be a string if it is sent.
key_length integer or string Yes Key size in bits, for example 2048. A numeric string is accepted as well. It is not checked here; a size the ACME client cannot use fails the task.
san_attributes string Yes Subject alternative names wanted on the certificate, as a comma-separated string (a JSON array of strings is accepted as well). May be empty. The key itself must be present.
save_to object No Where to deliver the issued certificate once it is ready, for example {"azure_key_vault": {"cert_name": "www-example-com.pem", "vault_name": "my-vault"}}. Optional; defaults to none.
sub_domain string No Label placed in front of the registered domain, so that www with the domain example.com gives the common name www.example.com. Optional; empty or absent means the registered domain itself.
tags array of string No Free-form labels attached to the certificate for grouping and reporting. Optional; anything other than a list is ignored.
watchers array of string No Email addresses to notify about this certificate. Only addresses of registered CertSecure users are kept. Optional.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/generate_acme_cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"ca":"API Test ACME","domain_id":"37105","key_length":2048,"sub_domain":"www","san_attributes":"api.example.com","watchers":["[email protected]"],"tags":["production","external"],"additional_notes":"Public site certificate."}'

Responses

Status Code Description
200 The request was queued. Follow the task for the outcome.
400 The request was refused.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Generate Certificate with Private Key permission.
500 The request failed unexpectedly. Error carries the failure detail.

Example Response

{
  "TaskID": "2419"
}
GET /enrollment/generate_aws_acm_cert

Returns the values a POST to this path may use for the given CA: the domains the CA can validate, the key algorithms it supports, the validation methods, and the certificate options. The caller needs no permission beyond being authenticated.

Request Parameters

Name Located In Type Required Description
ca Query string Yes CertSecure name of the AWS ACM Certificate Authority to describe. This is the Name returned by GET /ca, not the CA's subject DN. Read by GET only; POST takes the CA from the request body.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/generate_aws_acm_cert?ca=<ca>" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The request options for this CA.
400 The ca query parameter is missing or does not name a registered CA.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
404 The CA is registered but has no stored record.
500 The request failed unexpectedly. Error carries the failure detail.

Example Response

{
  "aws_acm_payload": {
    "domain_validation_options": [
      "example.com"
    ],
    "validation_method": [
      "DNS",
      "EMAIL"
    ],
    "options": {
      "CertificateTransparencyLoggingPreference": [
        "ENABLED",
        "DISABLED"
      ],
      "Export": [
        "DISABLED",
        "ENABLED"
      ]
    },
    "key_algorithm": [
      "RSA_2048",
      "RSA_3072",
      "EC_prime256v1"
    ]
  }
}
POST /enrollment/generate_aws_acm_cert

Queues a public certificate request with AWS ACM. The type of every field is checked here: a field of the wrong type is a 400 that names it. The aws_acm_payload is then handed to the CA connector, which validates the values, so a bad domain name or option shows up as a failed task rather than as a 400. GET on this path lists the values the CA offers. The caller needs the Generate Certificate with Private Key permission. The ca query parameter is not used by POST.

Request Body (application/json)

Field Type Required Description
ca string Yes CertSecure name of the AWS ACM Certificate Authority to request from (the Name returned by GET /ca). Must be registered, otherwise the answer is a 400.
aws_acm_payload object No The certificate request as AWS ACM understands it. Optional here, but the connector rejects a request without domain_name. Use GET on this path to see the values the CA offers. Must be an object, and each field below must have its stated type, otherwise 400. null is not accepted for any field of it.
email array or string or null No Email addresses to notify about this certificate (its watchers): an array of strings, or the empty string or null for none. They need not belong to CertSecure users. Any other type is a 400.
tags array No Free-form labels attached to the certificate for grouping and reporting. An array of strings, or null for none; anything else is a 400.
additional_notes string No Free-text note stored with the request and shown in the certificate's history. Not interpreted. Must be a string when sent: anything else, including null, is a 400.
save_to object No Where to deliver the issued certificate, for example {"azure_key_vault": {"cert_name": "www-example-com.pem", "vault_name": "my-vault"}}. Optional; defaults to none.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/generate_aws_acm_cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"ca":"Issuing CA 1","aws_acm_payload":{"domain_name":"www.example.com","san_attributes":["example.com"],"validation_method":"DNS","key_algorithm":"RSA_2048"},"email":["[email protected]"],"tags":["production","external"],"additional_notes":"Public site certificate."}'

Responses

Status Code Description
200 The request was queued. Follow the task for the outcome.
400 The request was refused: ca is missing or not a registered CA, or a field of the POST body has the wrong type.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Generate Certificate with Private Key permission.
500 The request failed unexpectedly. Error carries the failure detail.

Example Response

{
  "TaskID": "2417"
}
POST /enrollment/generate_cert

Direct enrollment: CertSecure generates the key pair and the CSR itself from the subject fields in the request, then queues the certificate request with the chosen CA. Use POST /enrollment/enroll_csr instead when you hold the key and want to submit your own CSR. The caller needs the Generate Certificate with Private Key permission. The response only confirms the request was queued: follow TaskID through GET /tasks for the outcome. Depending on the approval workflow for the template, the request may wait for approvals before it is issued. ca, template, san_attributes and common_name are mandatory. The other subject fields (organization, organization_unit, city, state, country_code) are optional and are what the rest of the CSR is built from; an empty string means "none", and a CA's policy may still require some of them. The type of every field is checked first: a field of the wrong type is a 400 that names it. country_code must be empty or exactly two letters, and key_length must be a positive integer (an RSA key must be between 1024 and 16384 bits). If administrators have defined required custom fields, customFields must supply them, and every name in it must already exist (POST /customFields/create).

Request Body (application/json)

Field Type Required Description
ca string Yes CertSecure name of the Certificate Authority to issue from. This is the Name returned by GET /ca, not the CA's subject DN. The CA must be registered, otherwise the answer is a 400.
template string Yes Certificate template to issue against. Must be one the chosen CA publishes (GET /inventory/templates lists them). For a Sectigo CA the numeric certificate-type id is accepted too.
san_attributes string or array Yes Subject alternative names, as comma-separated type=value entries: dns=, ipaddress= and email= (and uri= for policy-based CAs). The DNS:value colon form is understood only by policy-based CAs and is silently ignored by the others. May be an empty string; a JSON array of strings with the same entries is accepted as well. Any other type is a 400. The common name is added automatically when it is not listed.
common_name string Yes Subject common name (CN) for the certificate, normally the fully-qualified hostname it will protect. Required and non-empty.
organization string No Subject organisation (O). The empty string means none; null is a 400.
organization_unit string No Subject organisational unit (OU). The empty string means none; null is a 400.
city string No Subject locality (L). The empty string means none; null is a 400.
state string No Subject state or province (ST). The empty string means none; null is a 400.
country_code string or string No Subject country (C) as a two-letter ISO 3166-1 alpha-2 code. Exactly two characters, or the empty string for none: the CSR builder rejects any other length (400).
group_email string No Distribution-list address to put in the subject's email attribute. Optional; when empty or absent the requesting user's own address is used. null is a 400.
key_length integer or string No Key size in bits: for example 2048, 3072 or 4096 for an RSA key, or 256, 384 or 521 when signing_algorithm selects ECDSA. Defaults to 2048. A positive integer, or a string of digits; anything else is a 400. For an RSA key made by CertSecure (a CA without a policy template) the size must be between 1024 and 16384, otherwise 400. A size the CA does not support makes the request fail later.
signing_algorithm string No Signature algorithm. Defaults to SHA256WITHRSA. For a CA without a policy template, ECDSA (or EC) generates an elliptic-curve key, ML-DSA-44, ML-DSA-65 and ML-DSA-87 generate post-quantum keys through OpenSSL 3.5, and any other value generates an RSA key. A policy-based CA interprets the value itself. Must be a string when sent.
email array of string No Email addresses of CertSecure users to notify about this certificate (its watchers). Optional. An array of strings; anything else is a 400.
tags array No Free-form labels attached to the certificate for grouping and reporting. Optional. An array of strings, or null for none; anything else is a 400.
customFields array No Administrator-defined fields to record against the certificate, as {"name": ..., "value": ...} objects. Each name must already be defined; a null value counts as not supplied. Required whenever a defined custom field is marked required. null, like leaving the key out, means no values.
additional_notes string No Free-text note stored with the request and shown in the certificate's history. Not interpreted. Must be a string when sent: anything else, including null, is a 400.
additional_data object No Extra issuance parameters handed to the CA connector with the request. For a Sectigo CA an object may carry organization_id, external_requester and term (days). A policy-based CA replaces it with the payload it derives from the request. Optional.
save_to object No Where to deliver the issued certificate once it is ready, for example {"azure_key_vault": {"cert_name": "www-example-com.pem", "vault_name": "my-vault"}}: the certificate is uploaded to that Azure Key Vault, as PEM when cert_name contains pem and as PFX when it contains pfx. Optional; defaults to none.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/generate_cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"ca":"Issuing CA 1","template":"WebServer","common_name":"www.example.com","san_attributes":"dns=www.example.com,dns=example.com","organization":"Example Corp","organization_unit":"IT Security","city":"Dallas","state":"Texas","country_code":"US","key_length":2048,"signing_algorithm":"SHA256WITHRSA","email":["[email protected]"],"tags":["production","external"],"additional_notes":"Web front end for the payments service."}'

Responses

Status Code Description
200 The request was queued. Follow the task for the outcome.
400 The request was refused: a required field is missing, a field has the wrong type or an unusable value, or the CA or template is not registered.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Generate Certificate with Private Key permission.
404 The CA has no usable configuration for this request.
500 The key pair or CSR could not be generated, or the request failed unexpectedly. Error carries the failure detail.

Example Response

{
  "TaskID": "2417"
}
POST /enrollment/generate_csr

Generates a new private key and a PKCS#10 CSR on the server and returns both in a ZIP archive: csr.pem and private_key.key, the key being encrypted with password. The server does not keep the key. A record of the request (subject, key size, CA when given) is kept for the "CSR generated" statistics. Callers other than administrators are held to the request policy (minimum key size, wildcard, duplicate and DNS allow-list rules) and are refused with a 403 when the CSR would break it. The common name is added to the SANs when it is a valid DNS name, IP address or e-mail address and not already listed.

Request Body (application/json)

Field Type Required Description
common_name string Yes Subject common name (CN) — normally the fully-qualified hostname the certificate will protect.
organization string Yes Subject organisation (O).
organization_unit string Yes Subject organisational unit (OU).
city string Yes Subject locality (L).
state string Yes Subject state or province (ST).
country_code string Yes Subject country (C) as a two-letter ISO 3166-1 alpha-2 code. Exactly two characters: any other length makes the subject builder raise, which the handler reports as a 500.
email string Yes E-mail address placed in the subject of the CSR.
san_attributes string Yes Subject alternative names as comma-separated entries in dns=, ipaddress= or email= form. Entries in any other form are ignored, and an empty string means no SANs beyond the common name. An invalid IP address or e-mail address makes the request fail with a 500.
password string Yes Password that encrypts the returned private key. Must be a string that meets the product's password policy; a weaker one is answered with 400 naming each rule it breaks, before any key is generated. The schema states the policy every install starts with: 9 to 16 characters, at least 2 upper-case, 2 lower-case, 2 digits and 1 special character (ASCII punctuation). An administrator can change the policy, including the maximum length, with POST /enrollment/policy; the server then enforces the changed one. GET /enrollment/generate_password returns a password that satisfies it.
key_length integer or string No Public key size in bits, as a string of digits (an integer is also accepted). Defaults to 2048. For ECDSA it selects the curve: 256, 384 or 521 (anything else gives P-256).
signing_algorithm string No Key algorithm: ECDSA (or EC) for an elliptic-curve key, ML-DSA-44, ML-DSA-65 or ML-DSA-87 for a post-quantum key, anything else (default SHA256WITHRSA) for an RSA key. The signature hash is SHA-384 for keys of 4096 bits or more and SHA-256 otherwise.
ca string No CertSecure name of the Certificate Authority the CSR is intended for. Only recorded for the "CSR generated" statistics; it is not checked.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/generate_csr" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"common_name":"www.example.com","organization":"Example Corp","organization_unit":"IT Security","city":"Dallas","state":"Texas","country_code":"US","email":"[email protected]","san_attributes":"dns=www.example.com,dns=example.com","password":"Str0ng#Pass12","key_length":"2048","signing_algorithm":"SHA256WITHRSA","ca":"Issuing CA 1"}'

Responses

Status Code Description
200 A ZIP archive containing csr.pem and the encrypted private_key.key.
400 The body is empty, a required field is missing, or password is not a string or does not meet the password policy.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The CSR breaks the request policy (administrators are exempt).
500 The key or CSR could not be generated; the message says why when it is a bad SAN entry.
GET /enrollment/generate_password

Returns a random password that meets the configured password policy (passwordRestriction from GET /enrollment/policy: minimum length and minimum counts of upper-case, lower-case, digit and special characters, within the maximum length if the administrator set one). Use it for the password of a PKCS#12 download or of a generated CSR's private key. Nothing is stored: every call returns a new value.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/generate_password" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 A newly generated password.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The stored password policy could not be read or applied.

Example Response

{
  "generated_password": "xY9$kLm2Qr7!"
}
POST /enrollment/hold_cert

Queues a reversible hold on one certificate (undo with POST /enrollment/unhold_cert) and answers immediately with the id of the task that carries it out, exactly like POST /enrollment/revoke_cert. Microsoft CA (MSCA) certificates only: Active Directory Certificate Services is the one integrated CA that can later reverse this (certutil -revoke <serial> Unrevoke only succeeds when the certificate's current revocation reason is CertificateHold) -- AWS Private CA, GlobalSign, Sectigo, DigiCert and ACME CAs have no such operation, so the request is refused for any CA whose connectorType is not MSCA. Identify the certificate either by eid (enrollment ID) or by serialNum together with ca; at least one of eid or serialNum is needed, and when both are sent eid wins. The certificate must currently be active. Authorization and permissions are identical to revoke_cert: the View Enrollment Database permission, and global administrator, Department PKIAdmin of the owning CA, or (when an enrollment record exists) its owner.

Request Parameters

Name Located In Type Required Description
eid Query integer No Enrollment ID of the certificate to hold. Takes precedence over serialNum. Must be an integer (400 otherwise) and name an active record. Required unless serialNum is given.
serialNum Query string No Serial number of the certificate to hold, as shown in the inventory. Used only when eid is absent, in which case ca is required. Required unless eid is given.
ca Query string No CertSecure name of the Certificate Authority that issued the certificate. Must be an MSCA CA (400 otherwise). Required with serialNum; ignored when eid is used.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/hold_cert" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The hold was queued. The body is the task id as plain text.
400 No identifier was sent, a value is malformed, the CA is not MSCA, the certificate is not active, or the hold could not be queued. The message says which.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller lacks the View Enrollment Database permission, or may not hold this certificate.
GET /enrollment/ignore_cert

Returns every certificate that has been marked as ignored, one object per entry. EnrollmentID is null for a certificate that was ignored by serial number and has no enrollment record.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/ignore_cert" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The ignored certificates; an empty array when there are none.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The list could not be read; the message is the underlying error text.

Example Response

[
  {
    "EnrollmentID": 1042,
    "SerialNumber": "4A1B2C3D4E5F",
    "CertificateAuthority": "Issuing CA 1"
  },
  {
    "EnrollmentID": null,
    "SerialNumber": "5B2C3D4E5F60",
    "CertificateAuthority": "Issuing CA 1"
  }
]
POST /enrollment/ignore_cert

Marks one certificate as ignored and removes it from the expiring-certificate listings. Identify it by eid, or by serialNum with ca; eid wins when both are sent. The body must be a JSON object and every field that is sent must have its stated type, even one that is not used (a 400 that names the field). An eid that matches no enrollment record is a 404. Ignoring a certificate that is already ignored answers 200 again and adds no second entry to the list.

Request Body (application/json)

Field Type Required Description
eid integer or string No Enrollment ID of the certificate to ignore: an integer, or a string of digits (the web interface sends "1042"). Anything else is a 400, and so is an ID that matches no record (404). Takes precedence over serialNum. Either eid or serialNum (with ca) is needed.
serialNum string No Serial number of the certificate to ignore, used when eid is absent; ca is then required. The certificate must exist in that CA's inventory. Must be a string even when eid is also sent (400 otherwise).
ca string No CertSecure name of the Certificate Authority of the certificate. Required with serialNum (400 otherwise, and it must be a registered CA); not read with eid, but it must be a string when sent (the web interface always sends it). null is a 400.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/ignore_cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"eid":"1042"}'

Responses

Status Code Description
200 The certificate is now ignored.
400 The body is not a JSON object, no identifier was sent, a field has the wrong type, or the CA is missing or not registered.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
404 With eid: no enrollment record has that ID. With serialNum: no such certificate in the CA's inventory.
500 The operation failed unexpectedly; the message is the underlying error text.

Example Response

{
  "Success": "1042 from Issuing CA 1 has been ignored"
}
GET /enrollment/ignore_templates

Returns an object keyed by CA name whose values are the ignored template names. When nothing has ever been saved, every registered CA maps to an empty array. Open to any authenticated caller.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/ignore_templates" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 Ignored template names per CA.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The handler failed unexpectedly; Error carries the exception text.

Example Response

{
  "Issuing CA 1": [
    "WebServer",
    "Client-Auth"
  ],
  "Issuing CA 2": []
}
POST /enrollment/ignore_templates

Restricted to global administrators and Department PKIAdmins; the permission is checked before the body is read. Responds with the lists of the CAs the request named, as stored, which can be shorter than the ones sent because unknown templates are dropped. A body that is missing or is not a JSON object, or whose ignoreTemplates is not an object of CA names to arrays of template names, is a 400.

Request Body (application/json)

Field Type Required Description
ignoreTemplates object Yes Object keyed by CertSecure CA name; each value is the array of template names to ignore for that CA. Each CA named has its list replaced by the one sent, and a CA that is not named keeps its list: to stop ignoring every template of a CA, send an empty array for it. An empty object changes nothing. Template names are trimmed, and a name the CA does not publish is silently skipped. Every CA named must be registered (400 otherwise), and a Department PKIAdmin may only name CAs of their own department (403). The value must be an object of CA names to arrays of strings, otherwise 400.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/ignore_templates" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"ignoreTemplates":{"Issuing CA 1":["WebServer"]}}'

Responses

Status Code Description
200 The ignored templates as stored.
400 The body is missing or is not a JSON object, it names no ignoreTemplates, ignoreTemplates is not an object of CA names to arrays of template names, or a CA is not registered.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller is neither a global administrator nor a Department PKIAdmin (plain-text body), or a Department PKIAdmin named a CA outside their department (JSON body).
500 The handler failed unexpectedly; Error carries the exception text.

Example Response

{
  "Templates Ignored": {
    "Issuing CA 1": [
      "WebServer"
    ]
  }
}
POST /enrollment/import-third-party-cert

Adds a certificate that was issued outside CertSecure to the enrollment inventory. The PEM in cert_data is parsed and its subject, serial number, validity, key size and chain are recorded; the caller becomes the owner. The certificate is filed under certContainer, which must be a registered third-party container, using the "Third Party Template". Requires the Import Certificate permission. A certificate whose PEM is already stored is refused with 404 and the Enrollment ID that holds it. The body must be a JSON object, and each field must have its stated type (a 400 that names the field otherwise); null is not accepted for any field.

Request Body (application/json)

Field Type Required Description
certContainer string Yes Name of the registered third-party certificate container to file the certificate under. The request is rejected with 400 unless a container with exactly this name is registered. Must be a string.
cert_chain string No PEM-encoded issuing chain for the certificate, root last. Optional; must be a string when sent.
cert_data string Yes PEM-encoded certificate body. Must be a string; one that is not a PEM certificate is a 400.
watchers array of string No Email addresses notified about this certificate's expiry and lifecycle events, in addition to the owner. Optional. An array of strings; anything else, including null, is a 400.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/import-third-party-cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"certContainer":"Third Party Container","cert_chain":"-----BEGIN CERTIFICATE-----\nMIIDgzCCAmugAwIBAgIGShssPU5fMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYT\nAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGRGFsbGFzMRUwEwYDVQQKDAxF\neGFtcGxlIENvcnAxCzAJBgNVBAsMAklUMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5j\nb20wHhcNMjYwMTAxMDAwMDAwWhcNNDYwMTAxMDAwMDAwWjBsMQswCQYDVQQGEwJV\nUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkRhbGxhczEVMBMGA1UECgwMRXhh\nbXBsZSBDb3JwMQswCQYDVQQLDAJJVDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29t\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4KGdPq0SDQaATi+On/dF\nTH+mxg8a6grfrTpOk5FwE33zG+ow0s5ggulvCOuWSZ0mNhMlVPXIdcD09hO+kPXY\nNxh7TxQdJA5CQLS8Luo0NkdeA6VUPx0b1F5AA/ooaAPs7WXSiLrDCIrmrVg0uWJF\nUIH491cHZygNvIOLsbFo9VxKJZTql0YLlZZGV3JECZiPXyIqLvZFlCMdFzcLtoZA\nVpLJKOM7W31kum5uoZYwd+g7KFQ48vimcj+04mZhE4rhpx5iOUz6EMfad1Ttm8i2\ncpLVxBhLvUN+PO/RXAjmtS7KJ2Azv9FY0eRlahXWHj4X9Za1CUY3kvYA+4vz3JVO\ntwIDAQABoyswKTAnBgNVHREEIDAegg93d3cuZXhhbXBsZS5jb22CC2V4YW1wbGUu\nY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAs+vreNbnsbORRn4Xlqkx3YgFIVUr9ia+s\nE+KNkFtZ6VqwJ4zBCghYUXAcvGqb/0Ru1jr1hXFW1C4WgeXoGhWm+l6FEgLaHA0Z\nh9JcUZ+zkhLnzHtsz4EBnqmDQ93YjFbQMFkPFxrO98RZsbgcGovF4ohrxRypcYbS\nwcbPRP1NWcF8ljJlbLCTM4pEGz4wfaioZHRed5Po0EcOh5O0JLkqxrhlW6Y9enNE\n5NBywAIeg8Dh50rNtoo9LlvpPboNdr7+Kit+xmzTOoZK2Ky9SjuVm7vOIQ17/02y\n9pPQRD5Uz8jRif2CRgIrm9KuqGsR6C+LM6cvL3CKn4r/zJ9Dk2Uy\n-----END CERTIFICATE-----\n","cert_data":"-----BEGIN CERTIFICATE-----\nMIIDgzCCAmugAwIBAgIGShssPU5fMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYT\nAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGRGFsbGFzMRUwEwYDVQQKDAxF\neGFtcGxlIENvcnAxCzAJBgNVBAsMAklUMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5j\nb20wHhcNMjYwMTAxMDAwMDAwWhcNNDYwMTAxMDAwMDAwWjBsMQswCQYDVQQGEwJV\nUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkRhbGxhczEVMBMGA1UECgwMRXhh\nbXBsZSBDb3JwMQswCQYDVQQLDAJJVDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29t\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4KGdPq0SDQaATi+On/dF\nTH+mxg8a6grfrTpOk5FwE33zG+ow0s5ggulvCOuWSZ0mNhMlVPXIdcD09hO+kPXY\nNxh7TxQdJA5CQLS8Luo0NkdeA6VUPx0b1F5AA/ooaAPs7WXSiLrDCIrmrVg0uWJF\nUIH491cHZygNvIOLsbFo9VxKJZTql0YLlZZGV3JECZiPXyIqLvZFlCMdFzcLtoZA\nVpLJKOM7W31kum5uoZYwd+g7KFQ48vimcj+04mZhE4rhpx5iOUz6EMfad1Ttm8i2\ncpLVxBhLvUN+PO/RXAjmtS7KJ2Azv9FY0eRlahXWHj4X9Za1CUY3kvYA+4vz3JVO\ntwIDAQABoyswKTAnBgNVHREEIDAegg93d3cuZXhhbXBsZS5jb22CC2V4YW1wbGUu\nY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAs+vreNbnsbORRn4Xlqkx3YgFIVUr9ia+s\nE+KNkFtZ6VqwJ4zBCghYUXAcvGqb/0Ru1jr1hXFW1C4WgeXoGhWm+l6FEgLaHA0Z\nh9JcUZ+zkhLnzHtsz4EBnqmDQ93YjFbQMFkPFxrO98RZsbgcGovF4ohrxRypcYbS\nwcbPRP1NWcF8ljJlbLCTM4pEGz4wfaioZHRed5Po0EcOh5O0JLkqxrhlW6Y9enNE\n5NBywAIeg8Dh50rNtoo9LlvpPboNdr7+Kit+xmzTOoZK2Ky9SjuVm7vOIQ17/02y\n9pPQRD5Uz8jRif2CRgIrm9KuqGsR6C+LM6cvL3CKn4r/zJ9Dk2Uy\n-----END CERTIFICATE-----\n","watchers":["[email protected]"]}'

Responses

Status Code Description
200 The certificate was imported. eid is the new Enrollment ID.
400 The body is not a JSON object, a key is missing or has the wrong type, certContainer is not registered, or cert_data could not be read as a PEM certificate.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Import Certificate permission.
404 The same certificate PEM is already stored; the message names the Enrollment ID that holds it. (Reported as 404 by this endpoint, not 409.)
500 The import failed unexpectedly.

Example Response

{
  "eid": 1042
}
POST /enrollment/import-third-party-cert-manual

Adds a third-party certificate to the enrollment inventory from metadata the caller types in, without supplying the certificate itself. The resulting record has no certificate body; use PUT /enrollment/attach-cert later to attach the PEM. The record is filed under certContainer, which must be a registered third-party container, and the caller becomes the owner. Requires the Import Certificate permission. A record with the same serial number in the same container is refused with 404. The body must be a JSON object and each field must have its stated type (a 400 that names the field otherwise); null is not accepted for any field, and "" stands for "none" in the optional text fields.

Request Body (application/json)

Field Type Required Description
certContainer string Yes Name of the registered third-party certificate container to file the certificate under. The request is rejected with 400 unless a container with exactly this name is registered.
commonName string Yes Subject common name (CN).
expiry string or string Yes Expiry date of the certificate in ISO 8601 form, either a date (2027-01-31) or a date-time (2027-01-31T23:59:59Z). A value without a time zone is read as UTC. A date in the past makes the record expired rather than active. Anything that is not such a date is a 400.
serialNumber string Yes Certificate serial number as a hexadecimal string, optionally prefixed with 0x. Colon or space separators are also tolerated and stripped. Stored in lower case.
template string No Template name to record against the certificate. Defaults to Third Party Template when omitted or empty.
watchers array of string No Email addresses notified about this certificate's expiry and lifecycle events, in addition to the owner.
san string No Optional. Subject alternative names as one comma-separated string of TYPE:value entries, for example DNS:www.example.com, IP:192.0.2.10. Recognised types are DNS, IP, Email and othername. The list is checked against the configured SAN policies (wildcard and DNS allow-list); a violation is answered 400.
keyLength integer or string No Optional. Public-key size in bits, for example 2048: a positive integer, or a string of digits. Anything else is answered 400.
tags array of string No Optional. Names of existing certificate tags to attach, as an array of strings. A name that is not a defined tag is answered 400 with the list of available tags.
organization string No Optional. Subject organization (O).
organizationUnit string No Optional. Subject organizational unit (OU).
city string No Optional. Subject locality (L).
state string No Optional. Subject state or province (ST).
countryCode string or string No Optional. Subject country (C), a two-letter code, or the empty string for none. Any other length is a 400.
issuer string No Optional. Common name of the issuing CA, recorded as typed.
additional_notes string No Optional. Free-text note stored with the record and shown in the certificate history. Not interpreted.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/import-third-party-cert-manual" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"certContainer":"Third Party Container","commonName":"www.example.com","expiry":"2027-01-31","serialNumber":"4A1B2C3D4E63","template":"Third Party Template","watchers":["[email protected]"],"san":"DNS:www.example.com, DNS:example.com","keyLength":2048,"tags":[],"organization":"Example Corp","organizationUnit":"IT","city":"Dallas","state":"Texas","countryCode":"US","issuer":"Example Issuing CA","additional_notes":"Registered manually pending receipt of the PEM."}'

Responses

Status Code Description
200 The record was created. eid is the new Enrollment ID.
400 The body is not a JSON object, a required key (certContainer, commonName, serialNumber, expiry) is missing or empty, a field has the wrong type, certContainer is not registered, or the typed-in details are invalid (serial number not hexadecimal, expiry not ISO 8601, SAN denied by policy, unknown tag). A missing expiry is answered {"Error": "expiry is required"}.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Import Certificate permission.
404 A record with this serial number already exists in the container; the message names its Enrollment ID. (Reported as 404 by this endpoint, not 409.)
500 The import failed unexpectedly.

Example Response

{
  "eid": 1042
}
POST /enrollment/import-trusted-root

Parses a PEM certificate and stores it in the CertSecure trust store as a trusted root, keyed by its Subject Key Identifier (re-importing the same certificate updates the stored entry). A background job then rebuilds the stored chains so certificates that chain to it show as trusted. Requires the Manage Certification Authorities administrator permission. Every failure after the permission check, including an unparseable certificate, a request body that is not a JSON object, or a failure while saving, is answered with 400 Invalid root certificate format.

Request Body (application/json)

Field Type Required Description
root_cert string Yes PEM-encoded root certificate.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/import-trusted-root" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"root_cert":"-----BEGIN CERTIFICATE-----\nMIIDgzCCAmugAwIBAgIGShssPU5fMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYT\nAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGRGFsbGFzMRUwEwYDVQQKDAxF\neGFtcGxlIENvcnAxCzAJBgNVBAsMAklUMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5j\nb20wHhcNMjYwMTAxMDAwMDAwWhcNNDYwMTAxMDAwMDAwWjBsMQswCQYDVQQGEwJV\nUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkRhbGxhczEVMBMGA1UECgwMRXhh\nbXBsZSBDb3JwMQswCQYDVQQLDAJJVDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29t\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4KGdPq0SDQaATi+On/dF\nTH+mxg8a6grfrTpOk5FwE33zG+ow0s5ggulvCOuWSZ0mNhMlVPXIdcD09hO+kPXY\nNxh7TxQdJA5CQLS8Luo0NkdeA6VUPx0b1F5AA/ooaAPs7WXSiLrDCIrmrVg0uWJF\nUIH491cHZygNvIOLsbFo9VxKJZTql0YLlZZGV3JECZiPXyIqLvZFlCMdFzcLtoZA\nVpLJKOM7W31kum5uoZYwd+g7KFQ48vimcj+04mZhE4rhpx5iOUz6EMfad1Ttm8i2\ncpLVxBhLvUN+PO/RXAjmtS7KJ2Azv9FY0eRlahXWHj4X9Za1CUY3kvYA+4vz3JVO\ntwIDAQABoyswKTAnBgNVHREEIDAegg93d3cuZXhhbXBsZS5jb22CC2V4YW1wbGUu\nY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAs+vreNbnsbORRn4Xlqkx3YgFIVUr9ia+s\nE+KNkFtZ6VqwJ4zBCghYUXAcvGqb/0Ru1jr1hXFW1C4WgeXoGhWm+l6FEgLaHA0Z\nh9JcUZ+zkhLnzHtsz4EBnqmDQ93YjFbQMFkPFxrO98RZsbgcGovF4ohrxRypcYbS\nwcbPRP1NWcF8ljJlbLCTM4pEGz4wfaioZHRed5Po0EcOh5O0JLkqxrhlW6Y9enNE\n5NBywAIeg8Dh50rNtoo9LlvpPboNdr7+Kit+xmzTOoZK2Ky9SjuVm7vOIQ17/02y\n9pPQRD5Uz8jRif2CRgIrm9KuqGsR6C+LM6cvL3CKn4r/zJ9Dk2Uy\n-----END CERTIFICATE-----\n"}'

Responses

Status Code Description
200 The certificate was added to the trust store.
400 root_cert is missing or empty, or the request could not be processed as a PEM certificate.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Manage Certification Authorities permission.

Example Response

{
  "Success": "Trusted root certificate (Example Root CA) imported successfully"
}
GET /enrollment/key_length_count

Returns, for every key length present among the active enrollment records, how many active records use it. The keys of the returned object are the key lengths (for example 2048) and the values are the counts; an estate with no active certificates answers an empty object. Takes no input; each call also writes an entry to the audit log.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/key_length_count" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 Map of key length to the number of active certificates using it.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.

Example Response

{
  "2048": 14,
  "4096": 3
}
GET /enrollment/organization_details

Returns the stored organization details. Any signed-in user may read them. On an installation where none have been saved the lists and the location map are empty and othersEnabled is absent.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/organization_details" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The stored organization details.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.

Example Response

{
  "organization": [
    "Example Corp"
  ],
  "organizationUnit": [
    "IT Security"
  ],
  "Location": {
    "Austin": {
      "State": "Texas",
      "CountryCode": "US"
    }
  },
  "othersEnabled": false
}
POST /enrollment/organization_details

Replaces the stored organization details with the values supplied. Requires the Manage Organization Details administrator permission. The body is not type-checked: the handler stores whatever it is given, but other parts of the product read organization and organizationUnit as lists and location as the city map shown here, so send those shapes. Omitting organization, organizationUnit or location makes the request fail.

Request Body (application/json)

Field Type Required Description
organization array of string Yes Organization names to offer as the subject O.
organizationUnit array of string Yes Organizational unit names to offer as the subject OU.
location object Yes Locations keyed by city name, each with its State and two-letter CountryCode. Stored, and returned by GET, as Location.
othersEnabled boolean No Whether values other than the listed ones may be entered. Optional; treated as false when omitted.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/organization_details" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"organization":["Example Corp"],"organizationUnit":["IT Security"],"location":{"Austin":{"State":"Texas","CountryCode":"US"}},"othersEnabled":false}'

Responses

Status Code Description
200 The organization details as now stored. Note the location map comes back as Location.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Manage Organization Details permission.

Example Response

{
  "organization": [
    "Example Corp"
  ],
  "organizationUnit": [
    "IT Security"
  ],
  "Location": {
    "Austin": {
      "State": "Texas",
      "CountryCode": "US"
    }
  },
  "othersEnabled": false
}
GET /enrollment/organization_info

Returns the organization information saved for the CA by its last inventory refresh. A CA whose connector does not report any is answered with 200 and {"Error": "Not found"}, not with a 404; a 404 means the CA itself is unknown.

Request Parameters

Name Located In Type Required Description
caName Query string Yes CertSecure name of the Certificate Authority, as returned by GET /ca. Must be a CA known to CertSecure (404 otherwise); an empty value is a 400.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/organization_info?caName=<caName>" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The stored organization information, or {"Error": "Not found"} when the CA has none (the status is still 200).
400 caName 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 CA with that name.

Example Response

{
  "organizationInfo": {
    "O": "Example Corp",
    "OU": "IT"
  }
}
GET /enrollment/policy

Open to any authenticated caller. number_of_approvers is how many users can currently approve requests.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/policy" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The current policy.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.

Example Response

{
  "csr": false,
  "wildcard": false,
  "short_dns_names_allowed": false,
  "dnsWhiteList": [],
  "passwordRestriction": {
    "MinPassLen": 9,
    "MaxPassLen": 16,
    "uppercase": 2,
    "lowercase": 2,
    "decimal": 2,
    "specialChar": 1
  },
  "workflow": {
    "Issuing CA 1": [
      {
        "template_name": "WebServer",
        "approvals_required": 1
      }
    ]
  },
  "number_of_approvers": 3
}
POST /enrollment/policy

Requires the Manage Enrollment Policies permission. Every field is optional and only the ones sent are changed. The whole body is checked first: if any field is invalid nothing is changed. The body must be a JSON object, and fields not listed here are ignored. The response is the whole stored policy.

Request Body (application/json)

Field Type Required Description
csr string No Whether a CSR that is already on record (active, pending, expired or revoked) is refused by policy. Sent as the string true or false (case-insensitive, surrounding spaces ignored); a CSR is not accepted here despite the name. Any other value, including one that is not a string, is a 400. Omit to leave unchanged.
wildcard string No Whether wildcard certificates are refused by policy for non-administrators. Sent as the string true or false (case-insensitive). Any other value, including one that is not a string, is a 400. Omit to leave unchanged.
short_dns_names_allowed string No Whether unqualified (single-label) DNS names are accepted in SAN lists. Sent as the string true or false (case-insensitive). Any other value, including one that is not a string, is a 400. Omit to leave unchanged.
dnsWhiteList array of string No DNS names or *. wildcard suffixes that requests are allowed to name; an empty array allows any name, for example ["example.com", "*.example.org"]. Replaces the stored list. An array of strings; anything else (including null) is a 400. Names are stored as sent.
passwordRestriction object No -
workflow object No Approval workflow, keyed by CertSecure CA name. Each value is an array of objects {"template_name": ..., "approvals_required": ...} saying how many approvals a request on that template needs; other keys of an object are kept as sent. The value must be an object of CA names to arrays of such objects, and template_name must be a non-empty string, otherwise 400. Every CA named must be registered (400 otherwise). A caller holding Remove Restricted Templates replaces the CA's whole list; a caller holding only Manage Templates can add templates that the CA publishes and that are not already listed; anyone else changes nothing for that CA. Omit to leave unchanged.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/policy" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"csr":"false","wildcard":"false","short_dns_names_allowed":"false","dnsWhiteList":[],"passwordRestriction":{"MinPassLen":9,"MaxPassLen":16,"uppercase":2,"lowercase":2,"decimal":2,"specialChar":1}}'

Responses

Status Code Description
200 The whole stored policy after the update, under Restrict.
400 The body is not a JSON object, a flag is not true or false, dnsWhiteList, passwordRestriction or workflow has the wrong shape, passwordRestriction is not a valid, satisfiable policy, or a workflow names a CA that is not registered.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Manage Enrollment Policies permission.

Example Response

{
  "Restrict": {
    "csr": false,
    "wildcard": false,
    "short_dns_names_allowed": false,
    "dnsWhiteList": [],
    "passwordRestriction": {
      "MinPassLen": 9,
      "MaxPassLen": 16,
      "uppercase": 2,
      "lowercase": 2,
      "decimal": 2,
      "specialChar": 1
    },
    "workflow": {
      "Issuing CA 1": [
        {
          "template_name": "WebServer",
          "approvals_required": 1
        }
      ]
    }
  }
}
POST /enrollment/renew_aws_acm_cert

Queues a new AWS ACM certificate request that repeats the original one, identified by the certificate's enrollment id or its serial number. The domain names, watchers, notes, tags and CA are all taken from the stored enrollment record; nothing about the certificate itself is supplied here. Only an active certificate that was requested through CertSecure (so that its request payload was kept) can be renewed; any other certificate is answered 409. The caller needs the Generate Certificate with Private Key permission, which is checked before the body is read. The response only confirms the request was queued: follow TaskID through GET /tasks. At least one of eid, EnrollmentID and serialNum is required. When EnrollmentID is present it takes the place of eid; when an enrollment id is given, serialNum is ignored (but must still be a string). The body must be a JSON object sent with a JSON Content-Type (a body with any other type is treated as missing, 400); a value of the wrong type (including null) is a 400.

Request Body (application/json)

Field Type Required Description
eid integer or string No Enrollment ID: the number CertSecure assigned to the certificate request, as an integer or a string of digits. Ignored when EnrollmentID is also sent.
EnrollmentID integer or string No Alternative spelling of eid; when both are sent this one wins.
serialNum string No Serial number of the certificate to renew, in any letter case. Only used when no enrollment id is given, but a blank value (empty or only spaces) is a 400 either way.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/renew_aws_acm_cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"eid":1046}'

Responses

Status Code Description
200 The renewal was queued. Follow the task for the outcome.
400 The request was refused.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Generate Certificate with Private Key permission.
404 No active certificate with that enrollment id or serial number was found.
409 The certificate is active but was not requested through CertSecure as an AWS ACM request, so there is no request to repeat.
500 The renewal failed unexpectedly. Error carries the failure detail.

Example Response

{
  "TaskID": "2418"
}
POST /enrollment/renew_cert

Queues the renewal of one existing certificate and answers with the id of the task that tracks it, as a bare string (not JSON). Identify the certificate with eid / EnrollmentID (an enrollment record) or serialNum (an inventory certificate); at least one of the three is needed (400 otherwise), and when both kinds are sent the enrollment id wins. Every other field is an optional override: anything omitted is taken from the certificate being renewed, so {"EnrollmentID": "1042"} alone renews it unchanged. Authorization differs by identifier: with an enrollment id the caller must be a global administrator, a Department PKIAdmin whose department owns the CA, or the record's owner or a listed recipient; with a serial number the caller needs the Renew Inventory Certificates permission. A certificate on an ACME template, or on a HashiCorp Vault CA, is renewed through its own task type and the subject and key fields are ignored. For other CAs a new key pair and CSR are generated and submitted like a fresh request, so the approvals configured for the template apply. The body must be a JSON object sent with a JSON Content-Type (a body with any other type is treated as missing, 400). Every field is type-checked before anything is read, and a wrong type is a 400 that names the field.

Note: Identify the certificate with eid (or EnrollmentID), or with serialNum together with ca.

Request Body (application/json)

Field Type Required Description
eid integer or string No Enrollment ID of the certificate to renew. An integer or a string of digits (surrounding spaces are trimmed); anything else, a boolean included, is refused with a 400. Overridden by EnrollmentID when that is also sent.
EnrollmentID integer or string or null No Alias of eid. When it is not null it replaces eid. Same format. null means not sent.
serialNum string No Serial number of an inventory certificate to renew, as shown by the inventory (hex, case insensitive). Must be a string. Used only when neither eid nor EnrollmentID is sent.
ca string No CertSecure name of the Certificate Authority to renew against. Defaults to the CA that issued the certificate. Must be a registered CA (404 otherwise).
template string No Certificate template to renew against. Defaults to the certificate's current template. Must be a template the CA publishes (400 Not a correct template mapping otherwise); GET /enrollment/templates lists them.
common_name string No Subject common name (CN) for the renewed certificate. Defaults to the current one.
organization string No Subject organisation (O). Defaults to the current one.
organization_unit string No Subject organisational unit (OU). Defaults to the current one.
city string No Subject locality (L). Defaults to the current one.
state string No Subject state or province (ST). Defaults to the current one.
country_code string No Subject country (C) as a two-letter ISO 3166-1 alpha-2 code. Defaults to the current one.
san string No Subject alternative names for the renewed certificate: comma-separated entries in dns=, ipaddress= or email= form (an array of the same entries is also accepted). When omitted the enrollment path reuses the current SANs and the serial-number path sends none.
key_length integer or string No Public key size in bits, as a positive integer or a string of digits; anything else is a 400. Defaults to the current key size. For an RSA key made by CertSecure (a CA without a policy template) the size must be between 1024 and 16384, otherwise 400; that range is checked once the record, CA and template have been found.
signing_algorithm string No Signature algorithm. Defaults to the certificate's current one, else SHA256WITHRSA.
EmailID array of string No E-mail addresses to notify about the renewed certificate (its watchers). Defaults to the current ones on the enrollment path and to none on the serial-number path. An array of strings; anything else, a bare string included, is a 400.
tags array No Free-form labels attached to the renewed certificate. An array of strings, or null for none; anything else is a 400.
additional_notes string No Free-text note stored with the renewal request and shown in the certificate's history. Must be a string.
additional_data object No Caller-supplied object stored on the renewal task unchanged. Free-form; not interpreted. For a CA that builds its request from a policy template (for example GlobalSign or AWS Private CA) it is replaced by the data the policy produces. Anything that is not an object is a 400.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/renew_cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"EnrollmentID":"1042","common_name":"www.example.com","san":"dns=www.example.com,dns=example.com","key_length":"2048","tags":["production"],"additional_notes":"Scheduled renewal"}'

Responses

Status Code Description
200 The renewal was queued. The body is the numeric id of the task that tracks it, as plain text (served as text/html), for example 5821.
400 The body is not a JSON object, a field has the wrong type, no certificate was identified, the key size is unusable, or the template is.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller may not renew this certificate (see the operation description).
404 The enrollment record, certificate, CA, template details or CA policy was not found.
500 Key or CSR generation failed, or the renewal raised an unexpected error. When it is the latter Reason carries the exception text.
POST /enrollment/renew_csr

Renews an issued certificate with a CSR you supply, so you keep your own private key; POST /enrollment/renew_cert instead generates a new key pair on the server. The response is the id of the task that tracks the renewal. Name the certificate with eid, or with serialNum and ca. Only an active or expired certificate is renewed (409 otherwise), and CertSecure must hold it (404 otherwise): a certificate it does not hold is never enrolled as a new one. The renewal keeps the old certificate's CA, template, owner, watchers, tags, note and custom fields; anything sent in the body replaces the inherited value, except the owner. When the new certificate is installed, the old one leaves the expiry alerts and renewal notifications are sent. The CSR-reuse policy does not count the CSRs of this certificate and the ones it renewed, so a client may renew repeatedly with the same CSR. Every enrollment rule of POST /enrollment/enroll_csr (CA, template, SANs, approvals) applies. Authorization: the Renew Inventory Certificates permission, or, for a certificate with an enrollment record, being a global administrator, the Department PKIAdmin of the CA the renewal is issued from (the one ca names, else the certificate's own), its owner or a watcher (403 otherwise). The Submit CSR permission is not needed.

Request Body (application/json)

Field Type Required Description
csr string Yes PEM-encoded PKCS#10 certificate signing request for the renewed certificate. It may be the CSR the certificate was issued from (same key, same subject), a new CSR for the same key, or a CSR for a new key. It must parse (400 otherwise). No private key is generated or stored.
eid integer or string No Enrollment ID of the certificate to renew. Send either eid, or serialNum with ca; sending both, or neither, is a 400. An id CertSecure does not hold is a 404.
serialNum string No Serial number (hex) of the certificate to renew, on the CA named by ca. Any spelling is accepted (case, leading zero, 0x prefix, :, - or space separators); anything else, including the placeholders None and EMPTY, is a 400. A certificate CertSecure holds only in its inventory (issued outside CertSecure) is renewed too, and then needs template. A serial CertSecure does not hold on that CA is a 404.
ca string No CertSecure name of the Certificate Authority. Required with serialNum, where it names the CA the certificate is on. With eid it is optional and moves the renewal to another registered CA; left out, the renewal uses the certificate's own CA.
template string No Certificate template to issue against. Optional: left out, the renewal uses the template the certificate was issued from. Required for a certificate CertSecure did not issue, which has none recorded (400 otherwise).
email array or string No E-mail addresses to notify about the renewal (the new certificate's watchers): an array of strings, or the empty string for none. Left out, the old certificate's watchers are kept.
san_attributes string or array No Additional subject alternative names, exactly as for POST /enrollment/enroll_csr. Merged with the SANs in the CSR unless override_csr_sans is true.
override_csr_sans boolean No When true, only the SANs in san_attributes are used; otherwise they are merged with the CSR's. Must be a boolean when sent.
tags array of string No Labels for the renewed certificate. Left out, the old certificate's tags are kept. Must be an array of strings when sent.
additional_notes string No Note stored with the renewal. Left out, the old certificate's note is kept. Must be a string when sent.
additional_data object No Caller-supplied data stored on the request task, exactly as for POST /enrollment/enroll_csr.
customFields array No Custom field values as {"name": ..., "value": ...} objects, validated as for POST /enrollment/enroll_csr. Left out (or null), the old certificate's values are kept.
renews_serial object No Not accepted on this route either; name the certificate with eid or serialNum. Any value is a 400.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/renew_csr" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"csr":"-----BEGIN CERTIFICATE REQUEST-----\nMIIC6zCCAdMCAQAwbDELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYD\nVQQHDAZEYWxsYXMxFTATBgNVBAoMDEV4YW1wbGUgQ29ycDELMAkGA1UECwwCSVQx\nGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\nADCCAQoCggEBAOChnT6tEg0GgE4vjp/3RUx/psYPGuoK3606TpORcBN98xvqMNLO\nYILpbwjrlkmdJjYTJVT1yHXA9PYTvpD12DcYe08UHSQOQkC0vC7qNDZHXgOlVD8d\nG9ReQAP6KGgD7O1l0oi6wwiK5q1YNLliRVCB+PdXB2coDbyDi7GxaPVcSiWU6pdG\nC5WWRldyRAmYj18iKi72RZQjHRc3C7aGQFaSySjjO1t9ZLpubqGWMHfoOyhUOPL4\npnI/tOJmYROK4aceYjlM+hDH2ndU7ZvItnKS1cQYS71Dfjzv0VwI5rUuyidgM7/R\nWNHkZWoV1h4+F/WWtQlGN5L2APuL89yVTrcCAwEAAaA6MDgGCSqGSIb3DQEJDjEr\nMCkwJwYDVR0RBCAwHoIPd3d3LmV4YW1wbGUuY29tggtleGFtcGxlLmNvbTANBgkq\nhkiG9w0BAQsFAAOCAQEAEApMFMCPeZet/95ukhjHBgbpQDVjhxiRyg7hxcuRmBcJ\nNIHqjVW9F3ryFD+fHXrTMZJGkgaKgw1OZXlsz1j7GvwIKnaDqO2Yix/wQr07btDD\n5RMysRzOnWkcHsinDBY6VWYgMliTkA5VKTkQ+Lq1kL6cTekyaGJv3g8Suj0Hdj+M\npqKo5KjzyRK1L18hZmh7atsd9LobjNIRqm8CnuU3ympGdO/Dz80PjIPfqt3XwMpD\nNrQ6LSh71Ewfe9xNuvNrBYWo06pKoHAsVLxDzjNGVYgdouOptBP8PXsIwx+LYcYL\nzQes0tQtk85fWSwwstIw8RHTCqj+bq22Fb63n1UFpQ==\n-----END CERTIFICATE REQUEST-----\n","eid":1042}'

Responses

Status Code Description
200 The renewal was queued. TaskID identifies the task that tracks it.
400 The request was refused: the body names no certificate or both forms, a field has the wrong type, the CSR is unreadable, a template is needed and missing, or the enrollment rules of POST /enrollment/enroll_csr refuse it (CA, template, SANs, custom fields).
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller may not renew this certificate.
404 CertSecure holds no such certificate, or the CA has no template policy or template details on record.
409 The certificate is not issued (revoked, pending, requested, denied or failed) and cannot be renewed.
500 The CSR could not be validated against the CA policy.

Example Response

{
  "TaskID": "5821"
}
POST /enrollment/revoke_cert

Queues the revocation of one certificate and answers immediately with the id of the task that carries it out; the revocation itself happens asynchronously on the CA's agent (or, for ACME CAs, against the ACME service). Identify the certificate either by eid (enrollment ID) or by serialNum together with ca. At least one of eid or serialNum is needed; when both are sent eid wins and serialNum/ca are ignored. With serialNum the CA is mandatory (400 otherwise) and the certificate must be present in that CA's inventory. Only an active enrollment record can be revoked. The caller needs the View Enrollment Database permission and must be a global administrator, a Department PKIAdmin whose department owns the CA, or (for a certificate that has an enrollment record) its owner. The success body is the bare task id, sent as text/html; poll GET /tasks for the outcome.

Note: Identify the certificate with eid, or with serialNum together with ca.

Request Parameters

Name Located In Type Required Description
eid Query integer No Enrollment ID of the certificate to revoke. Takes precedence over serialNum. Must be an integer (400 otherwise) and name an active record (404 otherwise). Required unless serialNum is given.
serialNum Query string No Serial number of the certificate to revoke, as shown in the inventory. Used only when eid is absent, in which case ca is required. Required unless eid is given.
ca Query string No CertSecure name of the Certificate Authority that issued the certificate. Required with serialNum (400 otherwise); ignored when eid is used.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/revoke_cert" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The revocation was queued. The body is the task id as plain text.
400 No identifier was sent, a value is malformed, or the revocation could not be queued. The message says which.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller lacks the View Enrollment Database permission, or may not revoke this certificate.
404 With eid: there is no active enrollment record with that id.
500 Looking up the record or queueing the revocation failed.
POST /enrollment/switch_ca

Starts a background job that renews each listed inventory certificate against another CA, and answers at once with the plain text Process started. The job works through the serial numbers in batches of 10, 30 seconds apart; nothing about its progress or outcome is returned here. Serial numbers that another renewal job is already processing are skipped. Template maps the current template name of each certificate to the template to use on the new CA. Requires the Renew Inventory Certificates permission, which is checked before anything else. The body must be a JSON object sent with a JSON Content-Type (a body with any other type is treated as missing, 400). Every field is checked before the job starts (400 for a missing field, a wrong type or an unregistered target CA), but the 200 only means the job was started: a template mapping that is wrong for a certificate fails that certificate inside the job.

Request Body (application/json)

Field Type Required Description
SerialNumber array of string Yes Serial numbers of the inventory certificates to re-issue: a non-empty array of non-blank strings, otherwise 400.
CertificateAuthority string Yes CertSecure name of the target Certificate Authority that will issue the new certificates. A non-blank string that must be a registered CA (400 CA not found otherwise).
Template object Yes Object mapping a certificate's current template name to the template to use for it on the target CA; every value must be a string, otherwise 400. A certificate whose current template is not a key fails to renew inside the job.
additional_notes string No Free-text note stored with each renewal request. A string, otherwise 400.
additional_info object No Object of extra order data merged into every renewal request (the job adds the computed order_validity), for example {"organization_id": 7} for DigiCert. Its entries are free-form and not interpreted here, but the value must be an object, otherwise 400.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/switch_ca" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"SerialNumber":["4A1B2C3D4E5F"],"CertificateAuthority":"Issuing CA 2","Template":{"WebServer":"WebServer-2"}}'

Responses

Status Code Description
200 The job was started.
400 The body is not a JSON object, a required field is missing, a field has the wrong type, or the target CA is not registered.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Renew Inventory Certificates permission.
500 The request could not be processed because of an unexpected failure.
GET /enrollment/templates

Returns the certificate templates the caller may request certificates from, grouped by CA. A global administrator sees every CA; anyone else sees the CAs of their department. CAs marked restricted appear only for callers holding Access Restricted CAs. With categories each CA's list is narrowed to the templates filed under those template categories (a CA without categories, or a categories value that is empty, maps to an empty array).

Request Parameters

Name Located In Type Required Description
categories Query string No Comma-separated template category names, for example SSL/TLS,Server. Optional: omit it to list every template. Names are trimmed and empty items ignored.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/templates" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 Template names per CA. An empty object when the caller has no CAs.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The templates could not be retrieved.

Example Response

{
  "Issuing CA 1": [
    "WebServer",
    "Client-Auth"
  ],
  "Issuing CA 2": []
}
POST /enrollment/transfer-third-party-cert

Re-files the enrollment record under a different registered third-party certificate container by changing its CertificateAuthority. Allowed for a global administrator, for a Department PKIAdmin whose department holds the record's CA, and for the record's owner; anyone else is answered with 403. Checks run in this order: EID present and an integer, certContainer present and registered, record exists, caller authorised.

Request Body (application/json)

Field Type Required Description
EID integer or string Yes Enrollment ID of the record to move. Must be an integer; a numeric string is also accepted.
certContainer string Yes Name of the registered third-party certificate container to move the record into. The request is rejected with 400 unless a container with exactly this name is registered.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/transfer-third-party-cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"EID":1045,"certContainer":"Third Party Container"}'

Responses

Status Code Description
200 The record was moved. (The word "transfered" is spelled this way in the live response.)
400 A key is missing, EID is not an integer, or certContainer is not a registered container.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller is neither a global administrator, a Department PKIAdmin for the record's CA, nor the record's owner.
404 No enrollment record has this Enrollment ID.

Example Response

{
  "Success": "Certificate transfered"
}
GET /enrollment/transfer_ownership

Makes the registered CertSecure user email the owner of the enrollment record eid. Allowed only for a global administrator (Admin; the PKIAdmin role is deliberately excluded) or the record's current owner. The new owner must be a registered user and must not already be the owner. Only an issued certificate can be transferred: a request still awaiting approval or the CA, or one that was denied or failed, has no serial number yet and is refused with a 409. To hand such a request to someone else, deny it and request the certificate again. The change of owner is recorded in the certificate's audit trail. With verify=true nothing is changed: the same checks run and the endpoint answers {"Reponse": true} if the transfer would be accepted. Without verify, or with verify=false, the transfer is performed. The response key is spelled Reponse (sic) in both the dry-run and the real answer. Calling it again for the same new owner is a 400 (already the owner).

Request Parameters

Name Located In Type Required Description
eid Query integer Yes Enrollment ID of the certificate whose ownership moves. Must be an integer (surrounding spaces and a sign are accepted); anything else is a 400. The example is a record of its own, so a real transfer never changes the certificates the other examples use.
email Query string Yes Email address of the registered CertSecure user who becomes the new owner.
verify Query boolean No Dry run. true (any letter case) checks the transfer but does not perform it. false, or leaving it out, performs it. Any other value is a 400, so a mistyped dry run can never move a certificate. (Until 2026-10-26 any value other than true performed the transfer.)

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/transfer_ownership?eid=<eid>&email=<email>" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The transfer was performed, or (with verify=true) would be accepted.
400 A parameter is missing or unusable, the new owner is already the owner, or the new owner is not a registered user.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller is neither a global administrator nor the current owner of the record.
404 No enrollment record has this Enrollment ID.
409 The certificate has not been issued yet (awaiting approval or the CA, denied or failed), so its ownership cannot be transferred. The dry run (verify=true) gives the same answer.
500 The transfer failed unexpectedly.

Example Response

{
  "Reponse": "Transfer of ownership complete"
}
POST /enrollment/trust-certificate-chain

Takes the anchor (last) certificate of the chain stored for the given Enrollment ID and adds it to the CertSecure trust store, then triggers a background rebuild of stored chains. The record must be active, revoked or expired, and must have an uploaded or built chain (see POST /enrollment/upload-chain). The body must be a JSON object. Requires the Manage Certification Authorities administrator permission.

Request Body (application/json)

Field Type Required Description
eid integer or string Yes Enrollment ID of the certificate whose chain anchor should be trusted. Must be a positive integer; 0 is treated as missing.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/trust-certificate-chain" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"eid":1047}'

Responses

Status Code Description
200 The chain anchor was added to the trust store.
400 The body is missing or is not a JSON object, eid is missing, zero or not an integer, the record is in a state that cannot be trusted, or no usable chain anchor exists.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller does not hold the Manage Certification Authorities permission.
404 No enrollment record has this Enrollment ID.
500 The operation failed unexpectedly.

Example Response

{
  "Success": "Certificate chain anchored with trusted root certificate (Example Root CA) successfully"
}
GET /enrollment/trust-history

A merger, a cross-signing or a distrust event changes the path a certificate chains through WITHOUT the certificate changing, so the only visible symptom is a chain that looks different than it did. The timeline is what lets an operator show a customer exactly what moved and when. Entries are recorded per OBSERVED CHANGE, never per refresh, and a regression seen while AIA was unreachable is deliberately absent -- see classes/functions/trust_history.py.

Request Parameters

Name Located In Type Required Description
eid Query string Yes Enrollment ID — the identifier CertSecure assigns to a certificate request and keeps for the life of the certificate. Distinct from the serial number, which only exists once the CA has issued.
limit Query integer No Maximum number of rows to return.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/trust-history?eid=<eid>" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The enrollment id and its trust history, newest change first. An empty history means the chain has never changed.
400 The request was rejected as malformed or failed validation.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 Unhandled server-side failure.

Example Response

{
  "eid": 1042,
  "history": []
}
GET /enrollment/trusted-roots

Returns every certificate in the CertSecure trust store, keyed by Subject Key Identifier. An empty trust store answers an empty object. Takes no input.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/trusted-roots" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 Trusted roots keyed by Subject Key Identifier (hexadecimal).
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The trust store could not be read.

Example Response

{
  "4a1b2c3d4e5f60718293a4b5c6d7e8f901234567": {
    "common_name": "Example Root CA",
    "certificate": "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----\n",
    "expiry": "2036-01-01T00:00:00+00:00",
    "signature_algorithm": "sha256WithRSAEncryption",
    "key_size": 4096
  }
}
POST /enrollment/unhold_cert

Reverses a hold placed by POST /enrollment/hold_cert and answers immediately with the id of the task that carries it out. Microsoft CA (MSCA) certificates only, for the same reason as hold_cert. Identify the certificate either by eid (enrollment ID) or by serialNum together with ca; at least one of eid or serialNum is needed, and when both are sent eid wins. The certificate must currently be on hold -- an active or revoked certificate is refused, there is nothing to remove. Authorization and permissions are identical to hold_cert/revoke_cert.

Request Parameters

Name Located In Type Required Description
eid Query integer No Enrollment ID of the certificate to unhold. Takes precedence over serialNum. Must be an integer (400 otherwise) and name an on hold record. Required unless serialNum is given.
serialNum Query string No Serial number of the certificate to unhold, as shown in the inventory. Used only when eid is absent, in which case ca is required. Required unless eid is given.
ca Query string No CertSecure name of the Certificate Authority that issued the certificate. Must be an MSCA CA (400 otherwise). Required with serialNum; ignored when eid is used.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/unhold_cert" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The unhold was queued. The body is the task id as plain text.
400 No identifier was sent, a value is malformed, the CA is not MSCA, the certificate is not on hold, or the unhold could not be queued. The message says which.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller lacks the View Enrollment Database permission, or may not unhold this certificate.
GET /enrollment/unknown-certs

Lists the certificates that were imported as third-party records, one per line. The response is not JSON: it is comma-separated text served as text/html, whose first line is a header made of the stored field names of the first record, followed by one line per record. Commas and square brackets inside values are replaced by spaces or removed, and a missing value prints as None. An estate with no third-party certificates answers 200 with an empty body. Because the header comes from the first record only, records with different field sets do not line up column for column.

Request Parameters

Name Located In Type Required Description
ca Query string No Optional. Name of the third-party certificate container (the value stored as the record's certificate authority) to list; omit it to list third-party certificates from every container.
count Query string No Accepted but ignored: the response always lists every matching certificate, whatever this value is.
status Query string No Optional. active lists only certificates whose status is active; other lists every certificate that is not active (expired, revoked, pending, ...). Omit it for all of them.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/unknown-certs" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 CSV-style text, header line first. Empty when nothing matches.
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 The listing failed unexpectedly.
POST /enrollment/update_email

Replaces the watcher list (EmailID) of one enrollment record, and of the matching inventory certificate when it exists. Every address is stored (trimmed), registered CertSecure user or not; the response lists what was stored and, separately, which of those addresses do not belong to a registered user. Every address must be well formed, otherwise nothing is stored (400). The body must be a JSON object. Allowed for a global administrator, for a Department PKIAdmin whose department owns the record's CA, and for a user already listed as owner of the record; anyone else gets 403. The record is looked up before the emails type is checked, so an unknown eid answers 404 whatever emails contains, and the address format is checked only for callers who are allowed to make the change.

Request Body (application/json)

Field Type Required Description
eid integer or string Yes Enrollment ID of the record to update — the identifier CertSecure assigns to a certificate request. Must exist (404 otherwise); a value that is not an integer or integer string is answered 400.
emails array of string Yes The complete new list of addresses to notify about this certificate. Replaces the existing list; an empty list clears it. Must be a JSON array of strings, each a well-formed address (surrounding white space is trimmed).

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/update_email" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"eid":1042,"emails":["[email protected]","[email protected]"]}'

Responses

Status Code Description
200 The list was replaced. EmailsRegistered is the list that was stored; UnregisteredEmails holds those of the stored addresses that do not belong to a registered CertSecure user (they are kept all the same).
400 The body is not a JSON object, a required field is missing, eid is not an integer, emails is not an array of strings, or one of the addresses is malformed (InvalidEmails lists them).
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 The caller is not an administrator of this record's CA and not its owner.
404 No enrollment record has this eid.
500 The stored record is incomplete, or the update failed.

Example Response

{
  "EmailsRegistered": [
    "[email protected]",
    "[email protected]"
  ],
  "UnregisteredEmails": []
}
POST /enrollment/upload-chain

Stores a chain for the certificate with the given Enrollment ID, so that GET /enrollment/view-trust-chain and POST /enrollment/trust-certificate-chain can use it. Despite the field name, the handler accepts PEM text: either a -----BEGIN PKCS7----- block or -----BEGIN CERTIFICATE----- blocks. The text must have that armour and hold at least one certificate that parses, otherwise nothing is stored (400). The chain replaces the one already stored for the record, whatever it was, so upload the complete chain. The format is checked before the record is looked up, so a bad value for an unknown eid is answered 400, not 404. The body must be a JSON object sent with a JSON Content-Type (a body with any other type is treated as missing, 400). This handler checks no permission beyond authentication.

Request Body (application/json)

Field Type Required Description
eid integer or string Yes Enrollment ID of the certificate the chain belongs to: a positive integer, or a string of digits. 0 is treated as missing; any other type (a boolean, a fraction, an object) is a 400.
p7b string Yes The chain as PEM text: a -----BEGIN PKCS7----- ... -----END PKCS7----- block, or one or more -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- blocks. The text must start with one BEGIN line and end with the matching END line (surrounding whitespace is ignored), and it must contain at least one certificate that can be parsed, otherwise 400. It replaces the stored chain.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/upload-chain" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"eid":1048,"p7b":"-----BEGIN CERTIFICATE-----\nMIIDgzCCAmugAwIBAgIGShssPU5fMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYT\nAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGRGFsbGFzMRUwEwYDVQQKDAxF\neGFtcGxlIENvcnAxCzAJBgNVBAsMAklUMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5j\nb20wHhcNMjYwMTAxMDAwMDAwWhcNNDYwMTAxMDAwMDAwWjBsMQswCQYDVQQGEwJV\nUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkRhbGxhczEVMBMGA1UECgwMRXhh\nbXBsZSBDb3JwMQswCQYDVQQLDAJJVDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29t\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4KGdPq0SDQaATi+On/dF\nTH+mxg8a6grfrTpOk5FwE33zG+ow0s5ggulvCOuWSZ0mNhMlVPXIdcD09hO+kPXY\nNxh7TxQdJA5CQLS8Luo0NkdeA6VUPx0b1F5AA/ooaAPs7WXSiLrDCIrmrVg0uWJF\nUIH491cHZygNvIOLsbFo9VxKJZTql0YLlZZGV3JECZiPXyIqLvZFlCMdFzcLtoZA\nVpLJKOM7W31kum5uoZYwd+g7KFQ48vimcj+04mZhE4rhpx5iOUz6EMfad1Ttm8i2\ncpLVxBhLvUN+PO/RXAjmtS7KJ2Azv9FY0eRlahXWHj4X9Za1CUY3kvYA+4vz3JVO\ntwIDAQABoyswKTAnBgNVHREEIDAegg93d3cuZXhhbXBsZS5jb22CC2V4YW1wbGUu\nY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAs+vreNbnsbORRn4Xlqkx3YgFIVUr9ia+s\nE+KNkFtZ6VqwJ4zBCghYUXAcvGqb/0Ru1jr1hXFW1C4WgeXoGhWm+l6FEgLaHA0Z\nh9JcUZ+zkhLnzHtsz4EBnqmDQ93YjFbQMFkPFxrO98RZsbgcGovF4ohrxRypcYbS\nwcbPRP1NWcF8ljJlbLCTM4pEGz4wfaioZHRed5Po0EcOh5O0JLkqxrhlW6Y9enNE\n5NBywAIeg8Dh50rNtoo9LlvpPboNdr7+Kit+xmzTOoZK2Ky9SjuVm7vOIQ17/02y\n9pPQRD5Uz8jRif2CRgIrm9KuqGsR6C+LM6cvL3CKn4r/zJ9Dk2Uy\n-----END CERTIFICATE-----\n"}'

Responses

Status Code Description
200 The chain was stored.
400 The body is not a JSON object, eid or p7b is missing or empty, eid has the wrong type, or p7b is not PEM armoured text holding a certificate that parses.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
404 No enrollment record has this Enrollment ID.
500 The upload failed unexpectedly.

Example Response

{
  "Success": "Certificate chain uploaded successfully"
}
GET /enrollment/user

Unavailable when the administrator has not configured user certificates; Available for Request when none has been requested yet (or the last one belongs to someone else); Certificate Requested.Pending approval. while the request is requested or pending; Issued otherwise. The last two carry the request's task id and its enrollment details (data, the shape of GET /enrollment/enrolled_csr_details).

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/user" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The state of the caller's user certificate.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The stored request could not be read.

Example Response

{
  "status": "Unavailable",
  "cert": null
}
POST /enrollment/user

Generates a key pair and a CSR for the caller (common name = the local part of their e-mail address, e-mail SAN, key size 2048, SHA256WITHRSA) using the organization details and the CA and template that the administrator configured, and queues the request in the background. Answers Unavailable when user certificates are not configured. Needs the organization details (a city, state and country) to have been filled in the Enrollment settings.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/user" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The request was queued, or user certificates are not configured.
400 The organization details needed for the CSR have not been configured.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The key pair or request could not be generated.

Example Response

{
  "SUCCESS": true
}
POST /enrollment/user/download-cert

Downloads the certificate record behind the self-service configuration saved with POST /enrollment/user/manage. Two states answer 200 with a small JSON status object and no certificate: Unavailable when no self-service configuration has been saved, and Available for Request when one exists but no certificate has been requested yet. Otherwise the 200 body is the certificate itself, in the format chosen by type (default cer): cer is the PEM certificate, p7b the PKCS#7 bundle text, text the chain as concatenated PEM blocks, zip a ZIP archive with one .cer file per chain certificate (application/zip) and pfx a PKCS#12 file protected by password (binary, but sent with the default text/html media type like cer, p7b and text). type is matched case-insensitively. The caller must be a global administrator, a Department PKIAdmin whose department owns the certificate's CA, or the record's owner or a listed recipient; cer, p7b, text and zip are also open to anyone holding the Download Certificate permission. The request body is only read once a certificate record exists, so the first two states answer identically whatever is sent. Once one does, the body must be a JSON object (400 otherwise). A record that has no certificate yet, for instance a request still pending approval, is answered 409.

Request Body (application/json)

Field Type Required Description
type string No Format to download: cer (PEM certificate), p7b, text (PEM chain), zip or pfx. Case-insensitive. Optional: defaults to cer when omitted. Any other value is refused with a 400 once a certificate record exists.
password string No Password that protects the PKCS#12 (pfx) file. Required (400 otherwise) when type is pfx and ignored for every other type (when sent it must still be a string, whatever type is: 400 otherwise). For pfx it must satisfy the password policy (passwordRestriction from GET /enrollment/policy: minimum length and minimum counts of upper-case, lower-case, digit and special characters).

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/user/download-cert" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"type":"cer"}'

Responses

Status Code Description
200 Either the JSON status object (nothing to download yet), or the certificate in the requested format: application/zip for zip, otherwise the text or binary body is sent as text/html.
400 The request cannot produce the requested download: the body is not a JSON object, type or password is not a string, type is not one of the supported formats, or password is missing or breaks the policy for pfx.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
403 Authenticated, but the caller is neither an administrator for the certificate's CA nor its owner or a listed recipient (and, for pfx, no permission substitutes for that).
404 The enrollment record the self-service certificate points at no longer exists (or, for pfx, is no longer active).
409 The record the self-service certificate points at has no certificate yet, for instance because the request is still pending approval. Nothing is wrong with the request itself.
500 The download failed after the record was found, for example the record carries no PKCS#7 bundle for p7b, zip or text, or the PKCS#12 export failed.

Example Response

{
  "status": "Unavailable",
  "cert": null
}
GET /enrollment/user/manage

Returns the saved CA and template. Both are empty strings until a configuration has been saved with POST.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/user/manage" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The saved configuration, or empty strings when none has been saved.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The configuration could not be read; the cause is in the server log.

Example Response

{
  "caName": "Issuing CA 1",
  "template": "User"
}
POST /enrollment/user/manage

Replaces the saved CA and template. The body must be a JSON object and both keys are required, each a non-blank string; anything else is answered 400 and nothing is saved.

Request Body (application/json)

Field Type Required Description
caName string Yes CertSecure name of the Certificate Authority that issues self-service user certificates. A non-blank string (400 otherwise). Stored as sent: it is not checked against the registered CAs.
template string Yes Name of the certificate template to issue self-service certificates from. A non-blank string (400 otherwise). Stored as sent: it is not checked against the CA's templates. Pick one that exists, because POST /enrollment/user issues from it.

Example Request

curl -X POST "https://<certsecure-backend-url>/enrollment/user/manage" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"caName":"Issuing CA 1","template":"User"}'

Responses

Status Code Description
200 The configuration was saved.
400 The body is not a JSON object, caName or template is missing, is not a string, or is blank.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The configuration could not be saved; the cause is in the server log.

Example Response

{
  "Message": "Configuration Saved"
}
GET /enrollment/view-trust-chain

Returns the chain that CertSecure built for the certificate with the given Enrollment ID, ordered from the leaf up to the root. Each element describes one certificate of the chain and says whether it is a trusted root. A record with no stored chain, and an Enrollment ID that does not exist, both answer 200 with an empty array.

Request Parameters

Name Located In Type Required Description
eid Query integer Yes Enrollment ID of the certificate whose chain to return. Must be an integer.

Example Request

curl -X GET "https://<certsecure-backend-url>/enrollment/view-trust-chain?eid=<eid>" \
  -H "Authorization: Bearer <token>"

Responses

Status Code Description
200 The chain, leaf first. Empty when the record has no chain or does not exist.
400 The eid query parameter is missing or empty, or is not an integer.
401 Authentication failed. The Authorization header is missing, malformed, expired, revoked, or names a session that no longer exists.
500 The chain could not be read.

Example Response

[
  {
    "level": "leaf",
    "status": "active",
    "is_trusted_root": false,
    "common_name": "www.example.com",
    "subject": "CN=www.example.com,OU=IT,O=Example Corp,L=Dallas,ST=Texas,C=US",
    "issuer": "Example Root CA (CN=Example Root CA,O=Example Corp,C=US)",
    "serial": "4a1b2c3d4e5f",
    "signature_algorithm": "sha256WithRSAEncryption",
    "public_key": {
      "algorithm": "RSA",
      "type": "RSA",
      "family": "RSA",
      "size": 2048,
      "exponent": 65537
    },
    "fingerprints": {
      "sha256": "0f1e2d3c4b5a69788796a5b4c3d2e1f00f1e2d3c4b5a69788796a5b4c3d2e1f0"
    },
    "valid_from": "Thu, 01 Jan 2026 00:00:00 GMT",
    "valid_to": "Fri, 01 Jan 2027 00:00:00 GMT",
    "is_ca": false,
    "path_length": null,
    "self_signed": false,
    "ski": "4a1b2c3d4e5f60718293a4b5c6d7e8f901234567",
    "aki": "7654321098fedcba0987654321fedcba09876543",
    "ocsp": "http://ocsp.example.com",
    "issuer_url": "http://pki.example.com/root.crt",
    "crl_distribution_points": [
      "http://pki.example.com/root.crl"
    ]
  }
]
On this Page:
Support Privacy Policy Terms of Service

Copyright 2026 Encryption Consulting LLC. All rights reserved.